
Exploit de prova de conceito para CVE-2018-1000533, uma vulnerabilidade de execução remota de código no GitList 0.6.0 através de entrada não sanitizada na função de pesquisa, permitindo execução arbitrária de comandos.
GitList é um visualizador moderno de repositórios Git.
Nas versões do GitList 0.6.0 e anteriores, existe uma vulnerabilidade que passa entradas validadas inadequadamente para funções do sistema, permitindo a execução de comandos arbitrários com privilégios do usuário PHP.
Execute o seguinte comando para iniciar o servidor GitList 0.6.0:
docker compose up -d
Instale as dependências antes de executar poc.py:
pip install requests
Quando a configuração estiver concluída, acesse http://127.0.0.1:8080 e verifique se existe um repositório de teste chamado example.
O GitList usa git grep para pesquisar código dentro do repositório.
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;
}
Aqui, $query é a palavra-chave de pesquisa e $branch é o branch alvo da pesquisa.
Se um atacante passar --open-files-in-pager=id; como termo de pesquisa, o comando id será executado no sistema.
Essa vulnerabilidade ocorre por dois motivos:
escapeshellarg()Teoricamente, ao passar pelo código $query = escapeshellarg($query);, o valor de entrada se torna uma string entre aspas simples. No entanto, escapeshellarg() impede injeções do ponto de vista do shell, mas não impede que o parser de opções do próprio git interprete strings começando com -- como opções.
--open-files-in-pagerEssa opção do git grep especifica um programa paginador externo para exibir os resultados da pesquisa e, por sua vez, executa o valor passado como um comando do sistema diretamente.
[repo_name]/tree/[keyword]/search) contém dois argumentos: [repo_name] e [keyword].[repo_name] deve ser um repositório existente no GitList e [keyword] deve ser uma palavra-chave que gere pelo menos um resultado de pesquisa.
(Nesta reprodução, foi usado o repositório example e a palavra-chave a.)Execute o poc.py com o seguinte comando:
Através deste script, o comando touch /tmp/success_dddo0 será executado, criando um arquivo vazio chamado success_dddo0 no diretório /tmp do servidor.
python3 poc.py http://127.0.0.1:8080
Após o envio da requisição, verifique se o arquivo success_dddo0 foi criado com sucesso com o seguinte comando:
docker compose exec web ls -l /tmp/success_dddo0
Após a execução do PoC, é possível confirmar que o comando arbitrário do sistema (touch /tmp/success_dddo0) foi executado com sucesso no servidor, criando o arquivo.

docker compose down
Deve-se atualizar a versão do GitList para a mais recente.
Conteúdo da correção do 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;
}
O GitList corrigiu essa vulnerabilidade usando uma expressão regular para remover prefixos - ilegais no termo de pesquisa ($query) e adicionando -- (um sinalizador de fim de opções) ao comando git grep, forçando que todos os valores subsequentes sejam tratados apenas como strings comuns (termos de pesquisa), e não como opções de comando.