Содержание
SQL injection. Описание
Описание
Отличное описание приведено в статье на habrahabr.ru :
SQL инъекция - это атака на базу данных, которая позволит выполнить некоторое действие, которое не планировалось создателем скрипта. Пример из жизни:
Отец, написал в записке маме, чтобы она дала Васе 100 рублей и положил её на стол. Переработав это в шуточный SQL язык, мы получим:
ДОСТАНЬ ИЗ кошелька 100 РУБЛЕЙ И ДАЙ ИХ Васе
Так-как отец плохо написал записку (Корявый почерк), и оставил её на столе, её увидел брат Васи — Петя. Петя, будучи хакер, дописал там «ИЛИ Пете» и получился такой запрос:
ДОСТАНЬ ИЗ кошелька 100 РУБЛЕЙ И ДАЙ ИХ Васе ИЛИ Пете
Мама прочитав записку, решила, что Васе она давала деньги вчера и дала 100 рублей Пете. Вот простой пример SQL инъекции из жизни :) Не фильтруя данные (Мама еле разобрала почерк), Петя добился профита.
А теперь рассмотрим реальный пример, взятый с ru.wikipedia.org . Допустим, серверное ПО, получив входной параметр id, использует его для создания SQL-запроса. Рассмотрим следующий PHP-скрипт:
# Предыдущий код скрипта... $id = $_REQUEST['id']; $res = mysql_query("SELECT * FROM news WHERE id_news =".$id); # Следующий код скрипта...
Если на сервер передан параметр id, равный 5 ( например так: http://example.org/script.php?id=5 ), то выполнится следующий SQL-запрос:
SELECT * FROM news WHERE id_news = 5
Но если злоумышленник передаст в качестве параметра id строку -1 OR 1=1
(например, так: http://example.org/script.php?id=-1+OR+1=1 ), то выполнится запрос:
SELECT * FROM news WHERE id_news = -1 OR 1=1
Таким образом, изменение входных параметров путём добавления в них конструкций языка SQL вызывает изменение в логике выполнения SQL-запроса (в данном примере вместо новости с заданным идентификатором будут выбраны все имеющиеся в базе новости, поскольку выражение 1=1 всегда истинно — вычисления происходят по кратчайшему контуру в схеме
Классификация SQL-инъекций
В этом параграфе я сделал попытку классифицировать данный тип уязвимости:
- Классическая SQLI
- Строковой входящий параметр
- Цифровой входящий параметр
- Слепая SQL инъекция
- Специфическая для конкретной системы управления базами данных SQLI
- Составные SQLI
- SQL инъекция + недостаточная аутентификация
- SQL инъекция + DDoS атаки
- SQL инъекция + взлом DNS
- SQL инъекция + XSS
Признаки
- Приложение получает данные для составления SQL запроса от пользователя;
- Приложение не проверяет введенные данные на корректность;
- Для построения SQL запроса или команды SQL exec (или её аналога) используется конкатенация или строковая замена.
- Подключение к базе осуществляется с данными административной или привилегированной учётной записи;
- Встраивание авторизационных данных в программный код;
Способы обнаружения
- Тестирование функций (black/white-box)
- Фаззинг (fuzzing)
- Cтатический/динамический/ручной анализ исходного кода
Методы для работы с БД
Язык | Ключевое слово |
---|---|
VB.NET | Sql SqlClient, OracleClient, Sql Data Adapter |
C# | Sql, SqlClient, OracleClient, Sql Data Adapter |
РНР | mysql_connect |
Perl | DBI, Oracle, SQL |
Ruby | ActiveRecord |
Python (MySQL) | MySQLdb |
Python (Oracle) | DCOracle2 |
Python (SQL Server) | pymssql |
Java (cJDBC) | java.sql, sql |
Active Server Pages | ADODB |
C++ (Microsoft Foundation Classes) | СDatabase |
C/C++ (MySQL) | #include <mysql++.h> #include <mysql.h> |
C/C++ (ODBC) | #include <sql.h> |
C/C++ (ADO) | ADODB, #import «msadol5.dll» |
SQL | exec, execute, sp_executesql |
ColdFusion | cfquery |
Дополнительная информация
Конструкция | Комментирование остатка строки | Получение версии | Конкатенация строк |
---|---|---|---|
MySQL | -- /* | version() | concat (string1, string2) |
MS SQL | --- | @@version | string1 + string2 |
Oracle | --- /* | select banner from v$version | string1 || string2 concat (string1, string2) |
MS Access | Внедрение в запрос NULL‑байта: %00 | ||
PostgreSQL | --- | version() | string1 || string2 |
Sybase | --- | @@version | string1 + string2 |
IBM DB2 | --- | select versionnumber from sysibm.sysversions | string1 || string2 string1 concat string2 |
Ingres | --- | dbmsinfo('_version') | string1 || string2 |