Хакер #305. Многошаговые SQL-инъекции
SQLite — вероятно, самая популярная встраиваемая СУБД. В силу простой архитектуры она считается высоконадёжной и на 100% протестированной, о чём заявляют разработчики. Но сейчас к инспекции приступили профессионалы.
Известный польский хакер Михал Залевски (Michał Zalewski) занимается поиском багов и в рабочее, и в свободное время. Недавно в сферу его внимания попала SQLite. Как выяснилось, даже в этой СУБД можно найти слабости. Дело в том, что SQLite иногда используют не только для во встраиваемых системах, но и в вебе — и тогда она представляет угрозу безопасности. Залевски приводит пример WebDB / WebSQL, который поддерживают некоторые браузеры. В этом случае любой баг в парсере SQLite может стать отправной точкой для атаки на всю систему.
Как обычно, Залевски подверг предмет испытаний мощному фаззингу. В случае с разными SQL-системами фаззер приходится настраивать под грамматику конкретной системы, чтобы получились более-менее осмысленные результаты. Здесь Михал поступил просто: всего пять минут заняло автоматически извлечь и отсортировать ключевые слова из документации SQLite. Их и загнали в словарь фаззера, после чего запустили тест:
create table t1(one smallint);
insert into t1 values(1);
select * from t1;
Но потом хакер вспомнил, что разработчики SQLite когда-то выкладывали в открытый репозиторий большой набор вручную написанных тестов. Их-то он взял, отсортировал по файлам (550 штук по 220 байт) и снова запустил программу.
В такой конфигурации очень быстро вылезли различные ошибки: разыменовывание нулевого указателя, неинициализированные указатели (пруф), фиктивные обращения к free() (пруф), переполнения буфера в куче (пруф) и даже переполнения стека (пруф).
В отдельных случаях для появления ошибки достаточно минимального набора запросов.
CREATE VIRTUAL TABLE t0 USING fts4(x,order=DESC);
INSERT INTO t0(docid,x)VALUES(-1E0,'0(o');
INSERT INTO t0 VALUES('');
INSERT INTO t0 VALUES('');
INSeRT INTO t0 VALUES('o');
SELECT docid FROM t0 WHERE t0 MATCH'"0*o"';
На всю работу у Михала Залевски ушло полчаса. Патчи для 22 багов включены в состав SQLite 3.8.9.