
Exploit de prueba de concepto para CVE-2018-1000533, una vulnerabilidad de ejecución remota de código en GitList 0.6.0 a través de una entrada no sanitizada en la función de búsqueda, que permite la ejecución arbitraria de comandos.
GitList es un visor moderno de repositorios Git.
En las versiones de GitList 0.6.0 e inferiores existe una vulnerabilidad que pasa entrada no validada adecuadamente a funciones del sistema, lo que permite ejecutar comandos arbitrarios con los permisos del usuario de PHP.
Para iniciar el servidor GitList 0.6.0, ejecute el siguiente comando.
docker compose up -d
Instalar las dependencias antes de ejecutar poc.py.
pip install requests
Una vez configurado el entorno, acceder a http://127.0.0.1:8080 y verificar que exista un repositorio de prueba llamado example.
GitList utiliza git grep para buscar código dentro del repositorio.
public function searchTree($query, $branch)
{
if (empty($query)) {
return null;
}
$query = escapeshellarg($query);
try {
$results = $this->getClient()->run($this, "grep -i --line-number {$query} $branch");
} catch (\RuntimeException $e) {
return false;
}
Aquí, $query es la palabra clave de búsqueda y $branch es la rama objetivo de la búsqueda.
Si un atacante envía --open-files-in-pager=id; como término de búsqueda, el comando id se ejecutará en el sistema.
Las razones por las que ocurre esta vulnerabilidad son dos:
escapeshellarg()Teóricamente, al pasar por el código $query = escapeshellarg($query);, la entrada se convierte en una cadena entre comillas simples. Sin embargo, escapeshellarg() previene la inyección desde la perspectiva del shell, pero no impide que el analizador de opciones de git interprete cadenas que comienzan con -- como opciones.
--open-files-in-pagerEsta opción de git grep se utiliza para especificar un programa externo (pager) para mostrar los resultados de búsqueda, y tiene la característica de ejecutar directamente el valor pasado como comando del sistema.
[repo_name]/tree/[keyword]/search) contiene dos argumentos: [repo_name] y [keyword].[repo_name] debe ser un repositorio existente en GitList, y [keyword] debe ser una palabra clave que genere al menos un resultado de búsqueda.
(En esta reproducción se utilizó example como repositorio y a como palabra clave.)Ejecutar poc.py con el siguiente comando.
A través de este script se ejecuta touch /tmp/success_dddo0, creando un archivo vacío llamado success_dddo0 en el directorio /tmp del servidor.
python3 poc.py http://127.0.0.1:8080
Después de enviar la solicitud, verificar si success_dddo0 se ha creado correctamente con el siguiente comando.
docker compose exec web ls -l /tmp/success_dddo0
Después de ejecutar el PoC, se puede comprobar que el comando arbitrario del sistema (touch /tmp/success_dddo0) se ejecutó exitosamente en el servidor, creando el archivo.

docker compose down
Se debe actualizar GitList a la versión más reciente.
Cambios en el código:
public function searchTree($query, $branch)
{
if (empty($query)) {
return null;
}
$query = preg_replace('/(--?[A-Za-z0-9\-]+)/', '', $query);
$query = escapeshellarg($query);
try {
$results = $this->getClient()->run($this, "grep -i --line-number -- {$query} $branch");
} catch (\RuntimeException $e) {
return false;
}
GitList ha solucionado esta vulnerabilidad usando una expresión regular para eliminar los prefijos - ilegítimos en el término de búsqueda ($query), y añadiendo -- (el indicador de fin de opciones) al comando git grep para forzar que todos los valores posteriores sean tratados solo como cadenas normales (términos de búsqueda) y no como opciones de comando.