0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

0xL4ugh CTF 2024 - Micro Writeup

Last updated at Posted at 2024-02-13

CTFサイト

問題

原文

Remember Bruh 1,2 ? This is bruh 3 : D
login with admin:admin and you will get the flag :*

日本語

Bruh 1,2 を覚えていますか?これはブル 3 :D
admin:admin でログインすると、フラグ :* が表示されます。

試行錯誤

まずは、サイトにアクセスする。

スクリーンショット 2024-02-12 192122.png

問題文を見るにUsernamePasswordともにadminでログインするとFlagが取れるらしいので、試してみる。

スクリーンショット 2024-02-13 040221.png

ダメみたいですね。adminでのログインはローカルホストからしか許可されていないと。

一旦コードを見てみる。

index.php
<?php

error_reporting(0);
function Check_Admin($input)
{
    $input=iconv('UTF-8', 'US-ASCII//TRANSLIT', $input);   // Just to Normalize the string to UTF-8
    if(preg_match("/admin/i",$input))
    {
        return true;
    }
    else
    {
        return false;
    }
}

function send_to_api($data)
{
    $api_url = 'http://127.0.0.1:5000/login';
    $options = [
        'http' => [
            'method' => 'POST',
            'header' => 'Content-Type: application/x-www-form-urlencoded',
            'content' => $data,
        ],
    ];
    $context = stream_context_create($options);
    $result = file_get_contents($api_url, false, $context);
    
    if ($result !== false) 
    {
        echo "Response from Flask app: $result";
    } 
    else 
    {
        echo "Failed to communicate with Flask app.";
    }
}

if(isset($_POST['login-submit']))
{
	if(!empty($_POST['username'])&&!empty($_POST['password']))
	{
        $username=$_POST['username'];
		$password=md5($_POST['password']);
        if(Check_Admin($username) && $_SERVER['REMOTE_ADDR']!=="127.0.0.1")
        {
            die("Admin Login allowed from localhost only : )");
        }
        else
        {
            send_to_api(file_get_contents("php://input"));
        }   

	}
	else
	{
		echo "<script>alert('Please Fill All Fields')</script>";
	}
}
?>

Check_Admin関数があるので確認してみると、Usernameadminだと正規表現にマッチしてはじかれることが確認できた。
それ以外の場合はFlaskにPOSTリクエストが送信される。
Usernameadmin以外にしてみる。

flask_error.png

これもダメみたいですね。

Flaskの方のコードを見てみる。

app.py
from flask import Flask, request
import mysql.connector, hashlib

app = Flask(__name__)

# MySQL connection configuration
mysql_host = "127.0.0.1"
mysql_user = "ctf"
mysql_password = "ctf123"
mysql_db = "CTF"

def authenticate_user(username, password):
    try:
        conn = mysql.connector.connect(
            host=mysql_host,
            user=mysql_user,
            password=mysql_password,
            database=mysql_db
        )

        cursor = conn.cursor()

        query = "SELECT * FROM users WHERE username = %s AND password = %s"
        cursor.execute(query, (username, password))

        result = cursor.fetchone()

        cursor.close()
        conn.close()

        return result  
    except mysql.connector.Error as error:
        print("Error while connecting to MySQL", error)
        return None

@app.route('/login', methods=['POST'])
def handle_request():
    try:
        username = request.form.get('username')
        password = hashlib.md5(request.form.get('password').encode()).hexdigest()
        # Authenticate user
        user_data = authenticate_user(username, password)

        if user_data:
            return "0xL4ugh{Test_Flag}"  
        else:
            return "Invalid credentials"  
    except:
        return "internal error happened"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

authenticate_user関数でadmin:adminの認証が成功した場合にFlagが取れるみたいです。
php側ではUsernameadmin以外でないとダメで、Flask側ではadmin:adminでないとダメ。
そこで今回使用する攻撃はHTTP パラメータ汚染!

HTTP パラメータ汚染とは

HTTPパラメータ汚染(HPP)は、攻撃者がHTTPパラメータを操作してWebアプリケーションの動作を意図しない方法で変更する技術です。この操作は、HTTPパラメータを追加、変更、または複製することによって行われます。これらの操作の影響はユーザーに直接は見えませんが、サーバーサイドでアプリケーションの機能を大幅に変更し、クライアントサイドにも影響を与える可能性があります。

HackTrics-Parameter Pollution-より

今回の場合は、まさにこれ。

パラメータ解析: Flask vs. PHP
Web技術が重複するHTTPパラメータを処理する方法は異なり、HPP攻撃への脆弱性に影響します。
Flask: クエリ文字列a=1&a=2で最初に遭遇したパラメータ値を採用し、初期のインスタンスを後続の重複より優先します。
PHP(Apache HTTP Server上): 逆に、与えられた例では a=2 を選択し、最後のパラメータ値を優先します。この動作は、攻撃者の操作されたパラメータを元のパラメータよりも優先することで、HPPの悪用を誤って容易にする可能性があります。

HackTrics-Parameter Pollution-より

つまり、username=admin&username=test&password=admin&login-submit=このようなリクエストを送った場合、php側ではusername=test&password=admin&login-submit=を処理してFlask側ではusername=admin&password=admin&login-submit=の値で処理する。

フラグ取得

Burpで先ほどのパラメータを送信する。

param inject.png

無事Flag取得できました。
めでたしめでたし。

flag.png

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?