
Script de exploit de prova de conceito para injeção de comando (CVE-2026-27626) na manipulação de argumentos de senha do OliveTin, permitindo RCE por meio de requisições de API maliciosas.
O OliveTin permite que um administrador defina "ações": comandos shell com argumentos parametrizados que os utilizadores podem acionar a partir de uma interface web ou API. Antes de inserir um valor fornecido pelo utilizador no comando shell, o OliveTin deve executá-lo através de checkShellArgumentSafety(). Essa função verifica quatro tipos de argumentos: string, int, bool, choice. Ela ignora password completamente e retorna true, significando "seguro", sem analisar o valor de forma alguma.
Portanto, se uma ação tiver um argumento do tipo password e esse argumento for substituído numa string de comando shell, pode-se colocar qualquer coisa nele. Ponto e vírgula, crases, $(), tanto faz. Se o argumento estiver entre aspas no comando subjacente (um padrão comum para senhas de banco de dados, por exemplo), sair das aspas é suficiente.
func checkShellArgumentSafety(argType string, value string) bool {
dangerousTypes := []string{"string", "int", "bool", "choice"}
for _, dt := range dangerousTypes {
if argType == dt {
return sanitizeInput(value)
}
}
// password type falls through here, unchecked
return true
}
Afeta o OliveTin até a versão 3000.10.0. Corrigido na linha 3000.11.1 (commit 0.0.0-20260222101908-4bbd2eab1532), que adiciona password aos tipos verificados. Aviso: GHSA-49gm-hh7w-wfvf. CVSS 9.9.
Qualquer coisa onde um argumento do tipo password acaba dentro de uma string shell, geralmente entre aspas:
- title: Backup database
id: backup_db
shell: "mysqldump -u {{ db_user }} -p'{{ db_pass }}' {{ db_name }} > /tmp/backup.sql"
arguments:
- name: db_user
type: ascii_identifier
- name: db_pass
type: password
- name: db_name
type: ascii_identifier
db_pass fica entre aspas simples sem nada verificando-o. Envie '; id ;' como valor e o OliveTin executa id antes da chamada mysqldump malformada falhar. A falha não importa; o comando injetado já foi executado, com o usuário que o OliveTin utiliza. Em muitas configurações, isso é root, porque as pessoas o executam sob systemd sem uma linha User= e não pensam mais nisso.
Você não precisa de credenciais para nada disso se a instância tiver authRequireGuestsToLogin: false configurado, o que é comum em implantações menores ou amadoras.
pip install requests
python3 exploit.py -u <target> --action backup_db --arg db_pass -x "id"
| flag | para que serve | padrão |
|---|---|---|
-u, --url | alvo ou IP | obrigatório |
-p, --port | porta do OliveTin | 1337 |
--action | bindingId da ação vulnerável | obrigatório |
--arg | nome do argumento do tipo password | obrigatório |
-x, --cmd | comando a injetar | id |
--extra-arg | outros argumentos que a ação precisa, nome=valor, repetível | nenhum |
Se a ação precisar de outros argumentos para executar sem erros antes do seu comando injetado ser executado, passe-os com --extra-arg:
python3 exploit.py -u 10.0.0.5 --action backup_db --arg db_pass \
--extra-arg db_user=admin --extra-arg db_name=prod -x "whoami"
O script faz POST para StartAction, espera dois segundos, depois consulta ExecutionStatus e imprime o que retornou. Normalmente, você verá a saída do seu comando injetado acima de um erro do comando legítimo que foi executado depois e falhou. Isso é esperado. O erro é cosmético; o seu comando já foi executado.
Atualize o OliveTin para além da versão 3000.10.0. Se ainda não puder: remova quaisquer argumentos do tipo password das ações que utilizadores não confiáveis podem aceder, desative a execução de convidados e pare de permitir que valores de argumentos sejam interpolados em strings shell, se possível. Passe segredos através de variáveis de ambiente ou de um ficheiro que o OliveTin lê num caminho fixo. E não execute o serviço como root. Não há razão para um executor de tarefas ter isso.
exploit.py: o script do PoCREADME.md: este ficheiroIsto está aqui para pessoas que estão a corrigir as suas próprias instâncias do OliveTin, a escrever deteções ou a testar sistemas que estão autorizadas a testar. Não aponte para nada que não possui ou para o qual não tem permissão. Isso é responsabilidade sua, não de quem escreveu isto.