
análisis de cve-2024-42327
objetivo: 10.129.231.176
Información: Sé que mi objetivo es un servidor Zabbix. Recibí una cuenta de usuario estándar para iniciar sesión en Zabbix: usuario matthew contraseña 96qzn0h2e1k3. Esta cuenta tiene un usuario estándar, sin grupos ni privilegios adicionales.
Como de costumbre, comenzamos con la enumeración, vamos a hacer un escaneo de puertos usando nmap.

La salida de nmap nos muestra que el puerto estándar SSH y Apache2 también en el puerto estándar. También tenemos los puertos 10051 y 10050 ejecutando algún servicio de Zabbix.
Vamos a acceder a Zabbix colocando la IP en la URL del navegador y en el puerto HTTP estándar, puerto 80.

Esta es la pantalla de inicio de sesión de Zabbix, voy a iniciar sesión con el usuario que recibí.


En el pie de página, encontré la versión de Zabbix:

Usando el "padre de los tontos", investigué si ya había algún CVE de esta versión de Zabbix.

Después de un buen tiempo de investigación, vi que esta versión es vulnerable a CVE-2024-42327, que habla sobre una explotación de inyección SQL para obtener datos de la base de datos y escalar privilegios, y a CVE-2024-36467, que permite cambiar el rol de usuario a superusuario abusando de controles de acceso ausentes.
https://nvd.nist.gov/vuln/detail/CVE-2024-36467
https://nvd.nist.gov/vuln/detail/CVE-2024-42327
En la documentación de Zabbix se enseña cómo hacer solicitudes HTTP para llamar a la API.

https://www.zabbix.com/documentation/current/en/manual/api
Envié la solicitud llamando a appiinfo.version, que nos enseña en la documentación.

Lo que nos devolvió lo siguiente:
{"jsonrpc":"2.0","result":"7.0.0","id":1}
Para la siguiente prueba cambié algunos parámetros en esta request para enviarla de nuevo.

En method, cambié de appinfo.version a user.login y agregué los parámetros username y password. Esto también lo vi en la documentación de Zabbix.

Nos devolvió un token:
{"jsonrpc":"2.0","result":"9566174b00c9c3ca552abc1a52d670ba","id":1}
Después de más tiempo investigando, decidí ir al repositorio de Zabbix en GitHub.
https://github.com/zabbix/zabbix
Busqué sobre CUser y encontré un archivo CUser.php.

Encontramos la función user.update:
public function update(array $users) {
$this->validateUpdate($users, $db_users);
self::updateForce($users, $db_users);
return ['userids' => array_column($users, 'userid')];
}
No encontré ninguna verificación de autorización, así que decidí cambiar mi función a una función de superusuario, volví a la solicitud e hice los ajustes en el payload.

Me devolvió un error con un mensaje de invalid params.
Dando otro análisis largo al código, encontramos esta función:
/**
* Additional check to exclude an opportunity to deactivate himself.
*
* @param array $users
* @param array $users[]['usrgrps'] (optional)
*
From this snippet, we understand that we cannot change our roles because our role is checked
from extracting our data from the API token, and verifying against the database if we are that user.
But following the code we see that usrgrps has no validation at all, and therefore can be abused
to add ourselves into multiple groups at once. As long as the group is not disabled and the group
allows GUI access we can abuse this to change our current role with the following command:
User ID 3 is matthew , User group 7 is the Zabbix administrators group and user group 13 is the
Internal group which both hold unrestrictive privileges. The response indicates that the change
was successful:
* @throws APIException
*/
private function checkHimself(array $users) {
foreach ($users as $user) {
if (bccomp($user['userid'], self::$userData['userid']) == 0) {
if (array_key_exists('roleid', $user) && $user['roleid'] !=
self::$userData['roleid']) {
self::exception(ZBX_API_ERROR_PARAMETERS, _('User cannot change
own role.'));
}
if (array_key_exists('usrgrps', $user)) {
$db_usrgrps = DB::select('usrgrp', [
'output' => ['gui_access', 'users_status'],
'usrgrpids' => zbx_objectValues($user['usrgrps'], 'usrgrpid')
]);
foreach ($db_usrgrps as $db_usrgrp) {
if ($db_usrgrp['gui_access'] == GROUP_GUI_ACCESS_DISABLED
|| $db_usrgrp['users_status'] ==
GROUP_STATUS_DISABLED) {
self::exception(ZBX_API_ERROR_PARAMETERS,
_('User cannot add himself to a disabled group or a
group with disabled GUI access.')
);
}
}
}
break;
}
}
}
De acuerdo con este fragmento, no podemos cambiar nuestros roles porque nuestro rol se verifica al extraer nuestros datos del token de la API y verificar en la base de datos si somos ese usuario. Pero analizando el código, vemos que usrgrps no tiene ninguna validación y, debido a esta falta de validación, se puede abusar para agregarnos a varios grupos a la vez. No hay ninguna verificación que impida que un usuario se agregue a sí mismo a grupos a los que no debería tener acceso.
Vamos a intentar escalar privilegios por la falta de esta validación, edité el payload y envié la request nuevamente.

userid 3 se refiere al ID del usuario matthew. usrgrps contiene una lista de IDs de grupo: 13 que es un grupo interno y 7 es el grupo de administradores de Zabbix. Nuestra respuesta del servidor confirma el éxito de la operación:
{"jsonrpc":"2.0","result":{"userids":["3"]},"id":1}
Ahora podemos extraer los grupos de usuarios de nuestro usuario actual. Vamos a modificar la request y enviarla nuevamente.

Al verificar la respuesta, vemos que el usuario con ID 3 está en los grupos de administradores Interno y Zabbix.
{"jsonrpc":"2.0","result":[{"userid":"1","usrgrps":
[{"usrgrpid":"7","name":"Zabbix administrators"},
{"usrgrpid":"13","name":"Internal"}]},{"userid":"2","usrgrps":
[{"usrgrpid":"8","name":"Guests"}]},{"userid":"3","usrgrps":
[{"usrgrpid":"7","name":"Zabbix administrators"},
{"usrgrpid":"13","name":"Internal"}]}],"id":1}