KOSENセキュリティコンテスト2018 WriteUp

はじめに

2018年9月1、2日に開催されたKOSENセキュリティコンテスト2018に行ってきたので、他の参加者の皆さんに倣ってWriteUpを書いてみます。
https://sckosen2018.sasebo.ac.jp/sckosen2018.sasebo.ac.jp

私のスキルセット

  • CTFは2年ほど前に1回だけやったことがある
  • 普段はWebアプリなどを作っているので、Web系は若干できるようなできないような…
  • CryptoとかBinaryは全くわからない
  • stringsコマンドやobjdumpは今回初めて使った

つまり、CTF超超超初心者です。

解けた問題

12番 サーバーから情報を抜き出せ! [Web]

ディレクトリトラバーサルの問題。flag.txtというファイルの探す問題だったので、アドレスを書き換えてアクセス。目当てのファイルがあったので書いてあったフラグを提出。100点獲得。

途中までやった問題

23番 攻撃ログ [Misc]

Apacheアクセスログを調べて、おかしい1行を探し、その行をSHA1でハッシュ化したものがフラグという問題。ログはこんな感じで、約10000行。

192.168.10.26 - - [29/Aug/2018:20:44:21 -0700] "GET / HTTP/1.1" 200 187 time:426 Content-type:-

アクセス元のIPアドレス、アクセス時刻などが記録されている。ひたすらgrep

  1. 変なIPアドレスは記録されていないか→全て同一
  2. アクセス時刻におかしな点はないか→目視でさらっとみた感じおかしいところはなかった。
  3. GET、POST以外のリクエストはないか→ない
  4. iLogScannerでログをチェック→ディレクトリトラバーサルで/etc/passwdを開こうとした形跡が1500件ほど
  5. 変なステータスコードが記録されていないかチェック→200、403、404、500など

色々調べた結果、以下の3行が怪しいという結論に…

192.168.10.26 - - [29/Aug/2018:20:45:05 -0700] "GET /viewSource.action?className=com.opensymphony.xwork2.ActionSupport&config=file:/opt/apache-tomcat-8.0.53/webapps/ROOT/WEB-INF/classes/struts-validation.xml:139&page=/validation//WEB-INF/validation/storeErrorsAcrossRequestExample.jsp HTTP/1.1" 200 15249 time:14 Content-type:-
192.168.10.26 - - [29/Aug/2018:20:44:41 -0700] "GET /validation/storeErrorsAcrossRequestExample.jsp HTTP/1.1" 403 1059 time:0 Content-type:-
192.168.10.26 - - [29/Aug/2018:20:56:37 -0700] "POST /fileupload/upload.action HTTP/1.1" 500 347 time:49 Content-type:multipart/form-data; boundary=---------------------------100000000000

1行目は/viewSource.actionというエンドポイントにGETリクエストを投げると、ソースコードが返されるらしいと考えた。HTTP 200なので、storeErrorsAcrossRequestExample.jspというファイルの内容が返されたっぽい。
2行目は、/validation/storeErrorsAcrossRequestExample.jspというエンドポイントにGETリクエストを投げているが、HTTP 403なので、閲覧が許可されていない。にも関わらず、1行目でソースの内容を返しているので違和感を感じた。
3行目は、/fileupload/upload.actionというエンドポイントにファイルをPOSTしているっぽい。Content-type:multipart/form-data; boundary=---------------------------100000000000というのはバウンダリ文字列を指定している。この辺はRFC7578で定義されている。この1行だけ、Content-typeがmultipart/form-dataになっていた。
結論から言うと、正解は3行目の行をSHA1でハッシュ化して提出すればよかった。不正解だったのは、SHA1でハッシュ化するときにアルファベットを大文字にしてしまっていたから。解答サンプルを見てみると、アルファベットは全て小文字だった。正解すれば300点だっただけに、未だに悔やまれる最大のミス。

15番 47405b599e22969295ebed486d7343cb [Web]

問題のページにアクセスすると、検索フォームとログインフォームがある。検索フォームに数字を入れると、別の数字が返される。文字コードっぽいと思い、以下のようなコードを書いて、結果を取ってきた。

import requests

headers = {
    'Origin': 'http://find.kosensc2018.tech',
    'Content-Type': 'application/x-www-form-urlencoded',
}

for i in range(127):
    data = [
    ('no', str(i)),
    ]

    response = requests.post('http://find.kosensc2018.tech/search', headers=headers, data=data)
    t=response.text.split('\n')
    print(t[38].replace(' ',''))

文字列に直すと、Sorry... :<""This values aren't flag...""""Hint:""This flag is the someone's password.という文字列が出てきたが、ここでタイムアップ。

結果とまとめ

1150点で17位でした。去年も17位だったので、17位の呪いからは逃れられませんでした。ほぼ全てを私以外のメンバーに頼ってしまい、全く戦力にならなかったのが申し訳ないです。
https://sckosen2018.sasebo.ac.jp/result.htmlsckosen2018.sasebo.ac.jp
CTFをやってみた感想ですが、「Pythonできないと辛い」ですね。人の力ではどうにもならない部分が多々あるので、Pythonでサクッとコードが書けると強いと思いました。あとは、「Mac OSはCTFに向いていない」と言うことがわかりました。大抵のツールはWindows用のものがほとんど(に感じた)ので、Macを使い始めて1ヶ月の私には色々と辛い部分がありました。

さいごに

「結局お前は何やったの?」と聞かれたら、自信を持って「糖分補給係です」と言えるくらい、戦力になりませんでした。(キ○リクリス○ルとパイ○アメを供給し続けました)完全に私の実力不足です。
大会自体はいくつかトラブルはありましたが、とても楽しいものでした。運営の皆様にはとても感謝しています。本当にありがとうございました。