Skip to content

Latest commit

 

History

History

Let's_buy_some_array

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

Let's buy some array:Web:99.02pts

贔屓にしている数列屋さんがモバイルオーダーに対応したらしい。とは言っても金額計算機能しかないらしいけど。
...この金額計算、あんまり安全じゃなくないか?
問題サーバー:https://lets-buy-some-array.web.cpctf.space/
配布ファイル:https://files.cpctf.space/lets-buy-some-array.zip

Hint1
値が数値であるかどうかはクライアント側でしか検証していないようです。
不正な文字列を注入することが出来るかもしれません。
Hint2
金額計算にeval()が使われているので、任意のPHPコードが実行できます。
環境変数FLAGが表示されるよう、コードを入れてみましょう。
Hint3 (解法)
PHPでは$_ENV['FLAG']で環境変数FLAGを読み取ることが出来ます。
eval('return ' . $_POST["quantity1"] . '*1000;')$_POST["quantity1"]に不正なコードを注入することを考えます。
単に$_ENV['FLAG']を入れると$_ENV['FLAG'] *1000が実行されてしまいます。PHPはPythonなどと異なり文字列×数字の演算は出来ないので、これはエラーになります。
エラーを回避する方法としては、*1000の前に数字を置く方法があります。例えば、quantity1として$_ENV['FLAG'] . 2などを送ることで$_ENV['FLAG'] . 2*1000 を実行させることができます。

Solution

URLとソースが渡される。
アクセスすると個数を指定して商品を注文できるサイトだ。
site.png
注文後ページのソースは以下の通りであった。

<html>
    <head>
        <title>数列屋</title>
        <meta charset="utf-8">
    </head>
    <body>
        <h1>レジ</h1>
        <form action="purchase.php" method="post">
            <table>
                <tr>
                    <th>商品名</th>
                    <th>単価</th>
                    <th>個数</th>
                    <th>小計</th>
                </tr>
                <tr>
                    <td>フィボナッチ数列</td>
                    <td>1000</td>
                    <td><?=$_POST["quantity1"]?></td>
                    <td><?=eval('return ' . $_POST["quantity1"] . '*1000;')?></td>
                </tr>
                <tr>
                    <td>素数列</td>
                    <td>2000</td>
                    <td><?=$_POST["quantity2"]?></td>
                    <td><?=eval('return ' . $_POST["quantity2"] . '*2000;')?></td>

                </tr>
                <tr>
                    <td>三角数列</td>
                    <td>1500</td>
                    <td><?=$_POST["quantity3"]?></td>
                    <td><?=eval('return ' . $_POST["quantity3"] . '*1500;')?></td>
                </tr>
            </table>
            <p>合計金額は<?=eval('return ' . $_POST["quantity1"] . '*1000+' . $_POST["quantity2"] . '*2000+' . $_POST["quantity3"] . '*1500;')?>円です。この画面を実店舗の店員にご提示ください。</p>
        </form>
    </body>
</html>

危険なevalを利用している。
$_POST["quantity1"]systemなどをうまく指定してやればRCEできそうだ。
配布されたDockerfileより、フラグは環境変数にあることがわかるので/proc/self/environから取得できる。
注意点として、後ろに*1000;がついているのでsystem("cat /proc/self/environ");1としてやる。
また、フロントで数値のみの入力の制限がかかっているので、開発者ツールでtype="number"を消してやればよい。
送信すると以下の注文後ページとなる。
flag.png
flagが得られた。

CPCTF{3x3c_Func710n_1s_d4ng3r0u5}