Долбим SQL’ные базы данных
maravan
Xakep, номер #056, стр. 056-058-3
SELECT * FROM clients WHERE login='$login' AND password='$password'
Здесь на помощь приходит такой элемент языка SQL, как UNION. UNION обычно используется в случае необходимости объединить результаты обработки двух запросов в один:
SELECT smth FROM table1 UNION SELECT smth FROM table2
Заюзав UNION, можно добавить еще один SELECT, который будет извлекать инфу из таблицы cards. Для этого в качестве пароля в форме может быть задано что-то вроде этого:
' UNION SELECT * FROM cards WHERE ''='
В итоге получается:
SELECT * FROM clients WHERE login='nologin' AND password='nopassword' UNION SELECT * FROM cards WHERE ''=''
После приема такого запроса произойдет вывод всего содержимого таблицы cards.
При использовании UNION необходимо учитывать следующий момент. Оба SELECT'а должны выдавать одинаковое количество столбцов, иначе произойдет глюк. Грубо говоря, если в таблице clients - всего 4 столбца, а в cards - 5, вышеуказанный пример работать не будет. Чтобы он все-таки заработал, надо задать не "SELECT *", а, например, "SELECT type, number, holder, address".
Использование разделителей SQL-выражений
Если sql-сервер позволяет задавать в одном запросе несколько SQL-выражений, разделенных некоторым символом, то это открывает перед потенциальным атакующим более широкие возможности. Следует отметить, что фичи такого рода поддерживаются далеко не всеми серверами баз данных. К примеру, Microsoft SQL Server позволяет это делать, интерпретируя в качестве разделителя символ ';', а MySQL - нет.
Опять небольшой пример с использованием того же SQL-выражения, что и выше. Допустим, веб-магазин использует базу данных, крутящуюся на скульном сервере от Дяди Билли. Допустим также, что атакующему надо почистить логи, которые скрипт сохраняет в таблицу logs, содержащую поле с именем remote_ip. Ему надо удалить все записи, содержащие в поле remote_ip его IP-адрес. Удаление записей производится при помощи SQL-команды DELETE. Соответственно, удаление логов может выполняться командой:
DELETE FROM logs WHERE remote_ip='IP address'
Без использования разделителей совместить оригинальное выражение
SELECT * FROM clients WHERE login='$login' AND password='$password'
с DELETE затруднительно. А с их использованием все делается на раз-два. Достаточно в качестве пароля забить в форму, например, "nopassword'; DELETE FROM logs WHERE remote_ip='10.0.0.2", и все становится на свои места:
SELECT * FROM clients WHERE login='nologin' AND password='nopassword'; DELETE FROM logs WHERE remote_ip='10.0.0.2'
Теперь логи почищены.
Естественно, что помимо DELETE после разделителя можно забить ЛЮБУЮ SQL-конструкцию, поддерживаемую сервером: SELECT, INSERT, UPDATE и т.д.
Вывод в файл
Некоторые SQL-сервера позволяют выводить результаты обработки SQL-выражений во внешний файл. Когда это может быть полезным? Самое первое, что может прийти на ум хакеру - это собрать какой-нить скрипт, облегчающий дальнейшее юзание сервера. К примеру, php-шелл.
В сервере MySQL вывод в файл происходит посредством команды INTO OUTFILE. В простейшем случае это делается так: