pwn学习笔记(5)--格式化字符串漏洞(未完全完成)
pwn学习笔记(5)–格式化字符串漏洞
前言:由于条件有限,因此对于该漏洞的学习不算很多,
格式化字符串漏洞基础:
格式化字符串介绍:
格式化字符串函数可以接收可变数量的参数,并将第一个参数作为格式化字符串,根据其来解析之后的参数,格式化字符串的利用一般分为三个部分:
- 格式化字符串函数
- 格式化字符串
- [后续参数]
格式化字符串函数:
常见的格式化字符串有:
输入:
- scanf()
输出:
函数 基本介绍 printf 输出到 stdout fprintf 输出到指定 FILE 流 vprintf 根据参数列表格式化输出到 stdout vfprintf 根据参数列表格式化输出到指定 FILE 流 sprintf 输出到字符串 snprintf 输出指定字节数到字符串 vsprintf 根据参数列表格式化输出到字符串 vsnprintf 根据参数列表格式化输出指定字节到字符串 setproctitle 设置 argv syslog 输出日志
格式化字符串的格式:
%[parameter][flags][field width][.precision][length]type
其中,需要注意的有parameter参数,以及type参数:
parameter:
n$,获取格式化字符串中的指定参数
type:
- d/i,有符号整数
- u,无符号整数
- x/X,16 进制 unsigned int 。x 使用小写字母;X 使用大写字母。如果指定了精度,则输出的数字不足时在左侧补 0。默认精度为 1。精度为 0 且值为 0,则输出为空。
- o,8 进制 unsigned int 。如果指定了精度,则输出的数字不足时在左侧补 0。默认精度为 1。精度为 0 且值为 0,则输出为空。
- s,如果没有用 l 标志,输出 null 结尾字符串直到精度规定的上限;如果没有指定精度,则输出所有字节。如果用了 l 标志,则对应函数参数指向 wchar_t 型的数组,输出时把每个宽字符转化为多字节字符,相当于调用 wcrtomb 函数。
- c,如果没有用 l 标志,把 int 参数转为 unsigned char 型输出;如果用了 l 标志,把 wint_t 参数转为包含两个元素的 wchart_t 数组,其中第一个元素包含要输出的字符,第二个元素为 null 宽字符。
- p, void * 型,输出对应变量的值。printf(“%p”,a) 用地址的格式打印变量 a 的值,printf(“%p”, &a) 打印变量 a 所在的地址。
- n,不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。
- %, '
%
'字面值,不接受任何 flags, width。
下面使用几个案例来说明下几个需要注意的参数:
parameter:
n$ 表示获取后面参数列表中的第几个参数。
比如如下代码:
#include<stdio.h>
int main(){printf("%2$d\n",1,2,3);return 0;
}
通过编译运行之后得到的值却是
root@g01den-virtual-machine:/home/g01den/Temp# ./a
2
好了,我们稍微修改下刚刚的代码:
#include<stdio.h>
int main(){printf("%d%d%d\n",1,2,3);return 0;
}
然后编译为32位之后,查看下汇编代码:
0000119d <main>:119d: 8d 4c 24 04 lea 0x4(%esp),%ecx11a1: 83 e4 f0 and $0xfffffff0,%esp11a4: ff 71 fc push -0x4(%ecx)11a7: 55 push %ebp11a8: 89 e5 mov %esp,%ebp11aa: 53 push %ebx11ab: 51 push %ecx11ac: e8 2b 00 00 00 call 11dc <__x86.get_pc_thunk.ax>11b1: 05 27 2e 00 00 add $0x2e27,%eax11b6: 6a 03 push $0x3 <-------------------------------11b8: 6a 02 push $0x2 <-------------------------------11ba: 6a 01 push $0x1 <-------------------------------11bc: 8d 90 30 e0 ff ff lea -0x1fd0(%eax),%edx11c2: 52 push %edx11c3: 89 c3 mov %eax,%ebx11c5: e8 86 fe ff ff call 1050 <printf@plt>11ca: 83 c4 10 add $0x10,%esp11cd: b8 00 00 00 00 mov $0x0,%eax11d2: 8d 65 f8 lea -0x8(%ebp),%esp11d5: 59 pop %ecx11d6: 5b pop %ebx11d7: 5d pop %ebp11d8: 8d 61 fc lea -0x4(%ecx),%esp11db: c3 ret
能够发现在我指的那三行,在调用printf函数之前是先将参数从右向左压入栈中,之后通过读取栈的参数与格式化字符串一起打印出来。
格式化字符串漏洞:
有了前面的那些储备知识,这个时候就可以来看看格式化字符串的漏洞了。
初探:
首先,写一个程序,如下内容:
#include<stdio.h>
int main(){printf("%x %x %x %x \n",0x1);return 0;
}
那么,直接进行动态调试,观看main的栈帧中相关的信息:
00:0000│ esp 0xffffd500 —▸ 0x56557008 ◂— '%x %x %x %x \n'
01:0004│-014 0xffffd504 ◂— 0x1 <--------------------
02:0008│-010 0xffffd508 —▸ 0xf7fbeb20 —▸ 0xf7c1acc6 ◂— 'GLIBC_PRIVATE' <--------------------
03:000c│-00c 0xffffd50c —▸ 0x565561b1 (main+20) ◂— add eax, 0x2e27 <--------------------
04:0010│-008 0xffffd510 —▸ 0xffffd530 ◂— 0x1 <--------------------
05:0014│-004 0xffffd514 —▸ 0xf7e2a000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac
06:0018│ ebp 0xffffd518 —▸ 0xf7ffd020 (_rtld_global) —▸ 0xf7ffda40 —▸ 0x56555000 ◂— 0x464c457f
然后,运行到printf函数之后,再看看输出的值是多少:
pwndbg> n
1 f7fbeb20 565561b1 ffffd530
发现输出的值和箭头指出来的值一样。因此,黑客则可以利用此漏洞配合**%n$d**来进行内存的读取了。
一次简单的漏洞的实例:
实际上,格式化字符串的漏洞很多时候都是由于程序员们偷懒,才会导致一些漏洞的产生,比如下面的程序,如果写成这个样子:
#include<stdio.h>
int main(){char str[100];scanf("%s\n",str);printf("%s\n",str);return 0;
}
如果是这样的话,程序运行就不会出现太大的问题,但是,当程序员偷懒,使用下面的写法,就会出现问题:
#include<stdio.h>
int main(){char str[100];scanf("%s",str);printf(str);return 0;
}
运行的话就会出现如下的结果:
root@g01den-virtual-machine:/home/g01den/Temp# ./a
aaa.%x
aaa.fff53a28
根据gdb调试,就会发现,它输出了比esp地址高4字节的那一地址的数据。
泄露内存:
还是刚才那个程序,其实可以在这个时候多输入几个%x来进行父函数栈帧的esp高4字节的地址开始的多个字节的内存,或者通过n$来进行任意内存的读取:
aaa.fff53a28root@g01den-virtual-machine:/home/g01den/Temp# ./a
%x.%x.%x.%x.%x.%x.%x
ff8631d8.0.565a31d4.0.0.252e7825.78252e78root@g01den-virtual-machine:/home/g01den/Temp# ./a
%3$x
565cf1d4
泄露任意地址的内存:
上一个方法只是泄露了栈上的数据,其实,格式化字符串可以对任意内存地址的数据进行泄露。、
攻击者可以使用类似于"%s"的格式规范做到泄露栈中存放的值对应的地址的字符串的内容,这里引用下dalao的对于%s的讲解:
程序会将%s指向的地址作为一个ASCII字符串处理,直到遇到一个空字符。所以,如果攻击者能够操纵这个参数的值,那就可以泄露任意地址的内容。
或者说
%s 是把地址指向的内存内容给打印出来,可以把 函数的地址给打印出来。
也就是说,想要做到任意地址的内存泄露,就需要想办法对栈上的某个地址的值进行修改为想要获得的那个字符串的地址。
覆盖栈内存:
%n不能够输出字符,但是,它能把已经成功输出的字符个数写入对应的整形指针参数所致的变量,只要变量对应的地址可写,就可以利用格式化字符串来改变其对应的值。
一般来说,这种方法利用的步骤为:
- 确定覆盖地址
- 确定相对位移
- 进行覆盖
注:以下为我个人的见解,如有问题,请指正。
首先,之前说过了%n这个格式化字符串的作用是啥:
%n,不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。
之后,用一个程序作为示例:
#include <stdio.h>
int a = 123, b = 456;
int main() {int c = 789;char s[100];printf("%p\n", &c);scanf("%s", s);printf(s);if (c == 16) {puts("modified c.");} else if (a == 2) {puts("modified a for a small number.");} else if (b == 0x12345678) {puts("modified b for a big number!");}return 0;
}
这个程序的格式化字符串漏洞的函数很容易就能找到,那就是printf(s),因此,假设对变量c进行修改,就需要用到%n对C进行修改,所以,格式如下:
c的地址+12个任意的字符+对应格式化字符串的参数的偏移
好了,实际试试看吧:
AAAA,$p,$p,$p,$p,$p,$p,$p,$p,$proot@g01den-virtual-machine:/home/g01den/Temp# ./a
0xff8d3ad4
AAA,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p
AAA,0xff8d3ad8,(nil),0x565d51e4,(nil),0x315,0x2c414141,0x252c7025,0x70252c70,0x2c70252c,0x252c7025,0x70252c70
由此可知,传入的格式化字符串AAA,所对应的参数是第六位,因此,对应格式化字符串对应的偏移为6,也就是说,值为%6$n,好的,之后就是c的地址,我在学到这里的时候出现了理解不能的问题,最后大致是整明白了,就是不知道对不对。
对于C的地址,我认为是,正是因为构造的格式化字符串的前四个字节是c的地址,因此,%n这个格式化字符串在写的时候对应的就是第六个参数,而第六个参数的前四个字节就是c的地址,因此就成功修改了c这个变量的值;**那么问题就来了,为啥不能直接指定第五个参数进行修改呢?**我个人的理解是这样的:因为第五个参数存放的并不是c这个变量的地址,是789,因此,%n就试图把16写入789这个地址里去,但是,这个地址要么不存在,要么就是无法访问,则会出现segment fault,导致程序出现了错误。
覆盖小数字:
那么,问题又出现了,因为如果让变量的地址作为开始的字符,就会导致%n写入的最小的值也是4,那么,如果要让某个变量被覆盖为2,又该怎么做呢?
注:以下对于内容的解释部分均为我自己的理解,如有错误,还请指正。
照理来说,想要某个变量被覆盖为2的话,就需要诸如
aa%k$naa+地址
这样的字符串,所以是为啥呢?
这里借用julao们的说法是
aa%k n x x ,如果用这样的方式,前面 a a nxx,如果用这样的方式,前面 aa%k 是第六个参数, nxx,如果用这样的方式,前面aanxx 是第七个参数,后面在跟一个 我们想要修改的地址,那么这个地址就是第八个参数,只需要把 k 改成 8 就可以把这第八个参数改成 2,aa%8$nxx
我个人的理解为,在栈中,每个字符的长度为1字节,另外,对于格式化字符串的参数传递而言,每个参数都占用了四个字节(32位),所以,这里需要前和中都构成四个字节的字符串,因此,第六位的字符串就是aa%k,第七位就是$naa,第八位就可以传入变量的地址了。
后续的内容需要花费一些时间,短时间内先放放,暂时放下不管,之后有时间再来补充。
相关文章:
pwn学习笔记(5)--格式化字符串漏洞(未完全完成)
pwn学习笔记(5)–格式化字符串漏洞 前言:由于条件有限,因此对于该漏洞的学习不算很多, 格式化字符串漏洞基础: 格式化字符串介绍: 格式化字符串函数可以接收可变数量的参数࿰…...

HTML标签之表单标签,web开发实例教程
标签语义化: 语义和默认样式的区别: 默认样式是浏览器设定的一些常用tag的表现形式;语义化的主要目的就是让大家直观的认识标签和属性的用途和作用; 标签语义化作用: 当只有HTML页面时,没有CSS…...
数据库-第四/五章 数据库安全性和完整性【期末复习|考研复习】
前言 总结整理不易,希望大家点赞收藏。 给大家整理了一下计数据库系统概论中的重点概念,以供大家期末复习和考研复习的时候使用。 参考资料是王珊老师和萨师煊老师的数据库系统概论(第五版)。 文章目录 前言4 第四章 数据库安全性4.1 数据库安全性定义4.…...

网站维护页面404源码
网站维护页面404源码,源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面 下载地址 https://www.qqmu.com/2407.html...

CSS的文本样式属性值,web开发难点
什么是css块元素? 块级元素是独占一行显示的。它的兄弟元素必定不会与其在同一行中(除非脱离了文档流)。通俗点来说,就是块元素(block element)一般是其他元素的容器元素 戳这里领取完整开源项目:【一线大厂前端面试题…...

springboot+jsp汽车配件管理系统idea maven 项目lw
springbootweb汽车配件销售业绩管理系统服务于汽车配件公司业务,实现了客户管理,主要负责对客户相关数据的增删改查方面、渠道管理,主要对渠道信息也就是设备的供应商渠道信息进行管理、项目管理,主要是一些项目信息的记录与整理、销售数据管…...

计算机网络-网络安全(二)
1.应用层安全协议: S-HTTP或SHTTP(Sec HTTP),安全超文本传输协议,是HTTP扩展,使用TCP的80端口。HTTPS:HTTPSSL,使用TCP的443端口。和TLS(传输层安全标准)是双…...
Flutter App代码混淆
Flutter 应用混淆 Flutter 应用的混淆非常简单,只需要在构建 release 版应用时结合使用 --obfuscate 和 --split-debug-info 这两个参数即可。 flutter build apk –obfuscate --split-debug-info 命令需要指定输出调试文件的位置,该命令会生成一个符号映…...
pandas中apply函数的坑——错误信息Must provide ‘func‘ or tuples of ‘(column, aggfunc)的解决办法
近期需要获取某网站上的文章标题,并对文章来源以及不同来源的文章数量进行分析。已通过爬虫完成对文章标题、日期和文章链接的爬取,并存入pandas中的dataframe中,准备进行下一步的分析。 该网站一般情况下,文章标题前两个字是信息…...

《操作系统真相还原》读书笔记二:环境搭建 xshell连接virtualbox
修改 sshd_config 使用 vi /etc/ssh/sshd_config命令进入sshd服务配置,键盘输入i进行编辑,将监听端口、监听地址前的 # 号去除,开启允许远程登录,开启使用用户名密码来作为连接验证。修改完成,按一下Esc,输…...

CSS盒模型居中方法,大学生必备
96道前端面试题 下面给大家分享96道前端面试题 1,一些开放性题目 自我介绍:除了基本个人信息以外,面试官更想听的是你与众不同的地方和你的优势。项目介绍如何看待前端开发?平时是如何学习前端开发的?未来三到五年的…...
【Golang星辰图】构建健壮应用的秘籍:探索Go语言中最强大的测试工具库
精进单元测试:探秘Go语言中流行的测试框架和工具 前言 提高软件质量和稳定性是每个开发人员的目标之一。而单元测试是保证代码质量的重要手段之一,可以帮助我们检查代码是否按预期工作,并提早发现潜在的bug。Go语言提供了丰富的测试框架和工…...

刷题笔记day27-回溯算法3
39. 组合总和 var path []int var tmp []int var result [][]int// 还是需要去重复,题目中要求的是至少一个数字备选的数量不同。 // 所以需要剪枝操作,右边的要比左边的> func combinationSum(candidates []int, target int) [][]int {// 组合问题pa…...

【项目】Boost 搜索引擎
文章目录 1.背景2.宏观原理3.相关技术与开发环境4. 实现原理1.下载2.加载与解析文件2.1获取指定目录下的所有网页文件2.2. 获取网页文件中的关键信息2.3. 对读取文件进行保存 3.索引3.1正排与倒排3.2获取正排和倒排索引3.3建立索引3.3.1正排索引3.3.2倒排索引 4.搜索4.1 初始化…...
vue3 (六)自定义指令
1.定义自定义指令: app.directive(pos,{mounted(el,bunding){el.style[bunding.arg] bunding.value px;}, updated(el,bunding){el.style[bunding.arg] bunding.value px;} }) app.directive(指令名,{ mounted(el,bunding){}, updated(el,bunding){} }) 如果只…...
vite、mode如果为production打包后 .env.production 中 VITE_API_DOMAIN变量作为API地址吗
Vite 是一个现代化的前端构建工具,它使用 .env 文件来管理不同环境下的环境变量。通过为不同的环境(如开发环境、生产环境等)设置不同的 .env 文件,你可以控制这些环境中的变量,这些变量在构建时会被注入到项目中 当你…...

静态时序分析:SDC约束命令set_fasle_path详解
相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 目录 指定建立/保持时间检查 指定上升/下降沿 指定时序路径起点 删除虚假路径 添加注释 简单使用 写在最后 在之前的文章中,我们讨论了如何使…...
浅谈马尔科夫链蒙特卡罗方法(MCMC)算法的理解
1.解决的问题 计算机怎么在任意给定的概率分布P上采样?首先可以想到把它拆成两步: (1)首先等概率的从采样区间里取一个待定样本x,并得到它的概率为p(x) (2)然后在均匀分布U[0,1]上取一个值&a…...
2403C++,C++20协程库
原文 基于C20协程的http库--cinatra cinatra是基于C20无栈协程实现的跨平台,仅头,高性能,易用的http/https库(http1.1),包括httpserver和httpclient,功能完备,不仅支持最普通的getpost等请求,还支持restfulapi,websocket,chunked,ranges,multipart,静态文件服务和反向代理等功…...
mybatis动态加载mapper.xml
mybatis动态加载mapper.xml mybatis动态加载mapper.xml、springboot mybatis动态加载mapper.xml 教程连接:https://blog.csdn.net/weixin_44480167/article/details/136356398...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...

AWSLambda之设置时区
目标 希望Lambda运行的时区是东八区。 解决 只需要设置lambda的环境变量TZ为东八区时区即可,即Asia/Shanghai。 参考 使用 Lambda 环境变量...
Angular中Webpack与ngx-build-plus 浅学
Webpack 在 Angular 中的概念 Webpack 是一个模块打包工具,用于将多个模块和资源打包成一个或多个文件。在 Angular 项目中,Webpack 负责将 TypeScript、HTML、CSS 等文件打包成浏览器可以理解的 JavaScript 文件。Angular CLI 默认使用 Webpack 进行项目…...
Steam爬取相关游戏评测
## 因为是第一次爬取Steam。所以作为一次记录发出;有所错误欢迎指出。 无时间指定爬取 import requests import time import csv import osappid "553850" # 这里你也可以改成 #appid int(input()) max_reviews 10000 # 想爬多少条 # max_reviews…...