見出し画像

Writeup: Pico CTF 2024 (Web)

しばらく投稿していなかったので、リハビリ代わりに記事を書いています。
picoCTF 2024 の Web問題の Writeup です。

#500点のものだけは解けませんでした。JavaScriptや Node.js は良く判らないなぁ、、勉強不足を反省してます。。orz

picoCTF はカーネギーメロン大学が主催している学生向け(高校生向け?)の CTF です。教育的な配慮がされていて、問題を解くことを楽しみながら、サイバーセキュリティの知識が身に付くようになっています。
ゲーム感覚で遊んでいるうちに知識が身に付くのでお勧めです。

初心者向けCTF なので、Writeup もなるべく詳しく書いてみました。
この記事を読む人がCTF に興味を持ってくれたらとても嬉しいです。


1.Bookmarklet

サイトにアクセスすると画面の下に何やら意味ありげなJavaScriptがあります。とりあえずこのスクリプトを実行してみることにします。

スクリプトをコピーし、ブラウザの「ウェブ開発ツール」を開いて「コンソール」に貼り付けた後、キーボードの[ Enter ]で実行できます。

フラグがゲットできました。

2.WebDecode

アクセスしてみると、下図のようなサイトが表示されました。
ページのどこかにフラグが隠されているようです。

このページにはフラグが無さそうなので「ABOUT」をクリックしてみます。

なんとなく怪しげです。このページのHTMLソースを眺めてみます。

HTMLソースには、何やら意味ありげな長い文字列が有りました。
見るからに怪しいです。何かでエンコードされたフラグに違いありません。

文字列のエンコード、デコードは「CyberChef」 がお勧めです。
オンラインでブラウザさえあれば使えます。便利です。

Base64 でデコードすると、フラグが得られました。

3.IntroToBurp

 "Burp" は "Burp Suite" というツールのことです。このツールはPCとWebサイトの間の通信をキャプチャしたり、加工したりしてWebアプリの脆弱性検査をするためのもので、Webのセキュリティを勉強する人には必携です。

問題のタイトルからして 「Burp」を使用して解きたくなりますが、この問題は 「Burp」を使わなくても解けました。

問題サイトにアクセスすると、何やら登録フォームのようなものが表示されます。

適当に入力して [Register] をクリックしてみます。

ワンタイムパスワードの入力画面が表示され、ここからは何を入力してもエラーになります。この認証画面を突破すればフラグを得られそうです。

ブラウザの「ウェブ開発ツール」を開き、[ネットワーク] をクリックして、先ほどのワンタイムパスワード入力画面で適当なパスワードを入れて送信してみます。

デタラメなパスワードなので当然、エラー画面が表示されますが、
画面右側の「ウェブ開発ツール」にはキャプチャした通信がしっかりと表示されています。

お楽しみはここから。さまざまに通信を加工してWebサイトに投げてみて、その反応を見るのです。バグを見つけたらそれを手がかりにします。

「POST」を右クリックし「編集して再送信」を選びます。

この画面から、User-Agent などさまざまな項目を加工して再送信できます。

まずは手始めに「ボディ」(先ほど画面から送信した「ワンタイムパスワード」に当たる部分)を削除して送信してみます。
通常はあり得ない「中身が空っぽのリクエスト」を送ってみるわけです。

当たりです!「ウェブ開発ツール」画面の右側でサーバーの「応答」を確認すると、フラグが画面に表示されていました。

4.Unminify

アクセスしてみると、最初の「Bookmarklet」と同じような画面が表示されています。「フラグは既に渡したよ。どうやって読むのかは知らないけどね」などと書いてあります。

画面のどこかにフラグがある、ということなのでブラウザの「ウェブ開発ツール」を起動して眺めてみると・・・有りました。フラグが。

画面が JavaScriptで構成されている場合は、画面右クリック→「ソースの表示」だとスクリプトしか見えませんが、「ウェブ開発ツール」の「インスペクター」を使うと、スクリプトが生成したHTMLソースが見えます。

5.No SQL Injection

何の変哲も無いログイン画面。これを突破すればフラグが得られる、ということのようです。

タイトルの通り、この画面から No SQLデータベース向けのインジェクション攻撃をせよ、ということなのでしょう。

「No SQL」はデータベースの一種で独特の言語を使ってデータを抽出するようになっていて、言語も製品ごとに違っています。
有名な製品としては、MongoDB,  REDIS の2つがあります。

この問題ではプログラムのソースも配布されていて、それを見ると MongoDB が使われていることが判ります。

ここまで情報が揃えば、あとは「教えて!Google先生」です。
下記の記事が判り易く、参考になりました。

結局、プログラムのソースを眺めながらあれこれ試してみて、下記でうまくいきました。
(Password, Email ともに {"$ne":""} 、つまりEmail, Password のどちらも空白でないものを選択せよ、という命令文を挿入することになります。)

プログラムのソースでは「該当するユーザーが存在する場合にログイン成功」という判定条件になっていたので、これでログインできます。

ログイン後の画面がこちら。「あれ?フラグどこに有るの?」と思いながら探してみたのですが、この画面には見当たりませんでした。

気を取り直して、「ウェブ開発ツール」で通信をチェックすると、ログイン後の画面に遷移する直前のサーバーの応答に、意味ありげな長い文字列があるのを見つけました。

この文字列をCybereChef で Base64デコードしてフラグが入手できました。

6.Trick Star

アクセスしてみると、画像ファイルのアップロードサイトのようです。

ペイントでPNG画像(Test.png)を作ってアップロードしてみます。

問題無くアップロードは成功。画面にも「アップロード成功」って書いてあるけど、あれ?ファイルはどこに行ったんだろう・・・?

このWebサイトで他にディレクトリが無いか適当に探してみると、
/uploads/ というディレクトリがあることが判りました。
「Forbiddenエラー」は「アクセス権無し」なのでディレクトリが存在する証拠です。 

ならばと、/uploads/Test.png にアクセスしてみると、無事にアップロードした画像が表示されました。

動作が判ったので、このサイトに「Webシェル」などの「悪意のあるファイル」をアップロードすることを考えます。

「Webシェル」とは、リモートからブラウザを使って「Webサーバ上でコマンドを実行できる」ようにするためのファイルのことを指します。

たとえば下記のような1行の PHPファイルも「Webシェル」です。
このファイルをアップロードできれば、ブラウザから任意のコマンドをサーバー上で実行できるようになります。

<?php echo system($_GET["cmd"]); ?>

問題のサーバーは 「PNGファイルのアップロード」想定して作られているので、アップロードされたファイルが「PNGファイル」かどうかチェックしているはずです。

アップロードされたファイルが「PNGファイルかどうか」をWebサーバ側で判定する主な方法は2つあります。

1)拡張子が *.png かどうか?
2)ファイルの先頭4バイトが 0x89,0x50,0x4E,0x47 かどうか?

上記1)は例えば二重拡張子(*.png.php ) などでチェックを誤魔化せることがあります。2)は先頭4バイトさえ合っていれば、5バイト目以後の中身は何でも良いわけです。

なので、先頭4バイトが  0x89,0x50,0x4E,0x47 で拡張子が  *.png.php になるような php ファイルを作ることにします。バイナリエディタが無くても、echo コマンドで簡単に作ることができます。

echo -e '\x89\x50\x4e\x47'  > webshell.png.php
echo '<?php echo system($_GET["cmd"]);?>' >> webshell.png.php

webshell.png.php をアップロードします。

無事にアップロードできました。

Webシェルの動作確認のため、 /uploads/webshell.png.php?cmd=id  にアクセスしてみます。

id コマンドがサーバー上で実行できたことが判ります。

こんどは   "/uploads/webshell.png.php?cmd=ls ../"  にアクセスしてみます。 
拡張子 *.txt の 怪しげなファイルが見つかりました。

このテキストファイルの中身を見てみます。
"/uploads/webshell.png.php?cmd=cat ../G4ZTCOJYMJSDS.txt" をブラウザで開いてみると、フラグが表示されました。

この記事が気に入ったらサポートをしてみませんか?