На прошлом уроке http://profiwm.com/forum/thema62510/page106 мы с вами изучили, что такое PHP-инъекция. Давайте теперь рассмотрим SQL-инъекция
Для особо одаренных:
1. Тема для тех кто не знает. Знаешь? Покинь тему.
2. Цитирование поста приравнивается к флуду. За флуд банят
Начнем!
Внедрение SQL-кода — один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL-кода.
Внедрение SQL, в зависимости от типа используемой СУБД и условий внедрения, может дать возможность атакующему выполнить произвольный запрос к базе данных (например, прочитать содержимое любых таблиц, удалить, изменить или добавить данные), получить возможность чтения и/или записи локальных файлов и выполнения произвольных команд на атакуемом сервере.
Атака типа внедрения SQL может быть возможна из-за некорректной обработки входных данных, используемых в SQL-запросах.
Принцип атаки внедрения SQL
Допустим, серверное ПО, получив входной параметр id, использует его для создания SQL-запроса.
Рассмотрим следующий PHP-скрипт:
<?php
#Предыдущий код скрипта...
$id = $_REQUEST['id'];
$res = mysql_query("SELECT * FROM news WHERE id_news = $id"
#Следующий код скрипта...
?>
Если на сервер передан параметр id, равный 5 (например так: http://example.org/script.php?id=5 ), то выполнится следующий SQL-запрос:
<?php
SELECT * FROM news WHERE id_news = 5
?>
Но если злоумышленник передаст в качестве параметра id строку -1 OR 1=1 (например, так: http://example.org/script.php?id=-1+OR+1=1 ), то выполнится запрос:
<?php
SELECT * FROM news WHERE id_news = -1 OR 1=1
?>
Таким образом, изменение входных параметров путём добавления в них конструкций языка SQL вызывает изменение в логике выполнения SQL-запроса (в данном примере вместо новости с заданным идентификатором будут выбраны все имеющиеся в базе новости, поскольку выражение 1=1 всегда истинно).
Внедрение в строковые параметры
Предположим, серверное ПО, получив запрос на поиск данных в новостях параметром search_text, использует его в следующем SQL-запросе (здесь параметры экранируются кавычками):
<?php
…
$search_text = $_REQUEST['search_text'];
$res = mysql_query("SELECT id_news, news_date, news_caption, news_text, news_id_author FROM news WHERE news_caption LIKE('%$search_text%')"
?>
Сделав запрос вида http://example.org/script.php?search_text=Test мы получим выполнение следующего SQL-запроса:
<?php
SELECT id_news, news_date, news_caption, news_text, news_id_author FROM news WHERE news_caption LIKE('%Test%')
?>
Но, внедрив в параметр search_text символ кавычки(который используется в запросе), мы можем кардинально изменить поведение SQL-запроса.
Например, передав в качестве параметра search_text значение ')+and+(news_id_author='1, мы вызовем к выполнению запрос:
<?php
SELECT id_news, news_date, news_caption, news_text, news_id_author FROM news WHERE news_caption LIKE('%') AND (news_id_author='1%')
?>
Использование UNION
Язык SQL позволяет объединять результаты нескольких запросов при помощи оператора UNION.
Это предоставляет злоумышленнику возможность получить несанкционированный доступ к данным.
Рассмотрим скрипт отображения новости(идентификатор новости, которую необходимо отобразить, передается в параметре id):
<?php
$res = mysql_query("SELECT id_news, header, body, author FROM news WHERE id_news = " . $_REQUEST['id']);
?>
Если злоумышленник передаст в качестве параметра id конструкцию -1 UNION SELECT 1,username,password,1 FROM admin , это вызовет выполнение SQL-запроса
<?php
SELECT id_news, header, body, author FROM news WHERE id_news = -1 UNION SELECT 1,username, password,1 FROM admin
?>
Так как новости с идентификатором −1 заведомо не существует, из таблицы news не будет выбрано ни одной записи, однако в результат попадут записи, несанкционированно отобранные из таблицы admin в результате инъекции SQL.
Использование UNION + group_concat()
В некоторых случаях хакер может провести атаку, но не может видеть более одной колонки. В случае MySQL взломщик может воспользоваться функцией:
<?php
group_concat(col, symbol, col)
?>
которая объединяет несколько колонок в одну.
Например, для примера данного выше вызов функции будет таким:
<?php
-1 UNION SELECT group_concat(username, 0x3a, password) FROM admin
?>
Экранирование хвоста запроса
Зачастую, SQL-запрос, подверженный данной уязвимости, имеет структуру, усложняющую или препятствующую использованию union.
Например скрипт
<?php
$res = mysql_query("SELECT author FROM news WHERE id=".$_REQUEST['id']." AND author LIKE ('a%')"
?>
отображает имя автора новости по передаваемому идентификатору id только при условии, что имя начинается с буквы а, и внедрение кода с использованием оператора UNION затруднительно.
В таких случаях, злоумышленниками используется метод экранирования части запроса при помощи символов комментария( /* или -- в зависимости от типа СУБД).
В данном примере, злоумышленник может передать в скрипт параметр id со значением -1 UNION SELECT password FROM admin/* , выполнив таким образом запрос
<?php
SELECT author FROM news WHERE id=-1 UNION SELECT password FROM admin/* AND author LIKE ('a%')
?>
в котором часть запроса (AND author LIKE ('a%')) помечена как комментарий и не влияет на выполнение.
Расщепление SQL-запроса
Для разделения команд в языке SQL используется символ ; (точка с запятой), внедряя этот символ в запрос, злоумышленник получает возможность выполнить несколько команд в одном запросе, однако не все диалекты SQL поддерживают такую возможность.
Например, если в параметры скрипта
<?php
$id = $_REQUEST['id'];
$res = mysql_query("SELECT * FROM news WHERE id_news = $id"
?>
злоумышленником передается конструкция, содержащая точку с запятой, например 12;INSERT INTO admin (username, password) VALUES ('HaCkEr', 'foo'); то в одном запросе будут выполнены 2 команды
<?php
SELECT * FROM news WHERE id_news = 12; INSERT INTO admin(username, password) VALUES ('HaCkEr', 'foo');
?>
и в таблицу admin будет несанкционированно добавлена запись HaCkEr.
Методика атак типа внедрение SQL-кода
Поиск скриптов, уязвимых для атаки
На данном этапе злоумышленник изучает поведение скриптов сервера при манипуляции входными параметрами с целью обнаружения их аномального поведения. Манипуляция происходит всеми возможными параметрами:
¤ Данными, передаваемыми через методы POST и GET
¤ Значениями [HTTP-Cookie]
¤ HTTP_REFERER (для скриптов)
¤ AUTH_USER и AUTH_PASSWORD (при использовании аутентификации)
Как правило, манипуляция сводится к подстановке в параметры символа одинарной (реже двойной или обратной) кавычки.
Аномальным поведением считается любое поведение, при котором страницы, получаемые до и после подстановки кавычек, различаются (и при этом не выведена страница о неверном формате параметров).
Наиболее частые примеры аномального поведения:
¤ выводится сообщение о различных ошибках;
¤ при запросе данных (например, новости или списка продукции) запрашиваемые данные не выводятся вообще, хотя страница отображается и т. д. Следует учитывать, что известны случаи, когда сообщения об ошибках, в силу специфики разметки страницы, не видны в браузере, хотя и присутствуют в её HTML-коде.
Защита от атак типа внедрение SQL-кода
Для защиты от данного типа атак необходимо тщательно фильтровать входные параметры, значения которых будут использованы для построения SQL-запроса.
Фильтрация строковых параметров
<?php
$query = "SELECT * FROM users WHERE user='".mysql_real_escape_string($user)."';";
?>
Фильтрация целочисленных параметров
<?php
$query = 'SELECT * FROM users WHERE id ='.(int)$id;
?>
Спасибо за внимание!
Я ушел приготовить кофе, если есть вопросы, то задавайте, приду - обязательно отвечу.
Благодарю) полезная тема)
Вот я никак не пойму, зачем писать то же самое что есть в сети, да еще и такое старое.
$query = 'SELECT * FROM users WHERE id ='.(int)$id; // Да ну нафиг так фильтровать
abs(intval($id)) //Вот фильтр для чисел.
Тема настолько полезная,что даже википедия ее копирнула у автора.
https://ru.wikipedia.org/wiki/Внедрение_SQL-кода
Но лично, меня всему на Хабре учили. У меня сохранились практически все статьи/уроки начиная от основ и на данный момент заканчивая ООП, чтобы если я вдруг, что-то забуду, то смог бы быстро найти и повторить.
Есть ещё круче filter_input() и filter_var().
Просто приведу пример из жизни:
Ты сразу, как родился научился красиво писать? Нет, конечно. Сначала выучил буквы, потом пунктуацию и орфографию. Так вот тут тоже самое. Чтобы выучить высшее нужно сначала выучить основы. Ты думаешь я сразу начал писать на ООП? Нет, конечно. Как думаешь почему более опытные используют PostgreSQL вместо MySQL? Потому что они учились на ошибках.
Что вы к автору привязались. Только тролите. Автор написал норм статью, пусть даже копирнул. Он пишет для новичков и незнающих. Знаете - идите мимо. Смысл тогда создавать тогда всякие вм, чтобы юзер читал всякий троллинг? который занял больше половины форума. Нужно помнить люди здесь разные, многие приходят хотя бы чему то учиться,
есть еще круче, называется подготовление запросов
Они не ценят чужой труд. Это был мой последний урок на этом форуме. В среду получу деньги от заказчик и уйду в высшие сообщества. Там настоящий рай - обращаются на вы, пишут грамотно, предлагают множество оптимальных вариантов и др. А здесь эти только гавкать научились и передают это младшему поколению. Если они меня учить собрались, пускай выкладут ссылки на свои сайты - посмотрим, кто умнее.