Поиск, методы выявления sql-injection

Тема в разделе "Статьи", создана пользователем NetSky, 14 окт 2008.

  1. NetSky
    NetSky Guest
    [INTRO]​
    Всем привет. Собственно решил написать статью на эту тему, т.к не смотря на то что тема затрагивается довольно часто во всех статьях о скл-инж, но вроде как самое основное - поиск (обнаружение) самой уязвимости, затрагивается лишь вскользь. В своей статье я не буду рассказывать о применении данной уязвимости, а постараюсь собрать как можно больше материала по поиску и методам выявления. Также расскажу об основах которые необходимо знать чтобы понять как работает скл-инж, немного о логике ее применения и работы, о проблемах которые могут возникнуть. Сразу скажу, пишу КАК НАЧИНАЮЩИЙ в этом деле человек, для новичков. Пожалуй хватит прилюдий, перейдем к телу. Автор предполагает что пиво, кофе, моск и руки уже при вас...
    [ - ]​
    Начнем пожалуй с самых низов, а именно с четкого определения различий между html и PHP (хотя проще было бы расписать в чем они схожи). Пропустить этот пункт не мог по той причине, что многие люди после прочтения какой-либо статьи на подобную тему, сразу же рвутся испробовать этот материал в действии, не понимая при этом простейших вещей, а потом задают очень глупые вопросы. Приступим.

    Надеюсь что такое статическая(html) страничка знают все?!

    Словарь иностранных слов:
    ----------------------------------------------------------------------------------------------------
    статический - относящийся к статике; неподвижный; рассматриваемый в состоянии покоя и равновесия.
    ----------------------------------------------------------------------------------------------------

    В нашем случае статическая страничка это неизменная страничка, то есть та, на которую, без непосредственного редактирования, мы повлиять не можем. Хтмл-код любой странички можно спокойно просмотреть в любом браузере. Чем же отличается страничка на php? PHP - язык программирования выполняемый на сервере, с помощью интерпретатора языка php. Последовательность команд на языке php, которая выполняется этим самым интерпретатором на сервере, называется скриптом. То есть до браузера юзера, код на php не доходит. В итоге браузер
    юзера получит обычный хтмл код или любой другой вывод, но не путайте, вы никак не сможете посмотреть php код странички на удаленном сервере через браузер, т.к. он до вас не доходит, до вас доходит результат его выполнения.

    Пойдем дальше. Есть такое понятие как реляционная база данных (SQL).

    Вики:
    На самом деле все не так сложно, как кажется на первый взгляд. Рассмотрим простейший пример базы данных (бд)
    на примере из жизни. Возьмем небольшой фрагмент из записной книги.

    Код:
    |---|-----------------|---------------------|--------------------|-------------------------------|
    | № |       Имя	      |	      Фамилия	    |   Номер телефона   |             Адрес             |
    |---|-----------------|---------------------|--------------------|-------------------------------|
    | 1 |     Василий     |        Дудкин       |    066-1234567     |     Ул. Ульяновых, дом 71     |
    |---|-----------------|---------------------|--------------------|-------------------------------|
    | 2 |      Федор      |        Уткин        |    066-7654321     |     Ул. Ульяновых, дом 63     |
    |---|-----------------|---------------------|--------------------|-------------------------------|
    | 3 |     Евгений     |       Макаров       |    066-1233214     |     Ул. Ульяновых, дом 25     |
    |---|-----------------|---------------------|--------------------|-------------------------------|
    Просто?! У нас есть таблица, в нашей бд. Что мы о ней можем сказать? Например что под номером "2", в графе Фамилия, содержится запись "Уткин", в графе Адрес, напротив графы с Фамилией "Дудкин", записан адрес "Ул. Ульяновых, дом 71".

    На обычном, нашем с вами, языке, мы можем спокойно сказать: "Вася, кто там у нас 3-й по счету, в очереди к за колбасой?", на языке php же, обращение к базе выглядит несколько иначе. Ну уж что такое параметр, аль переменная, знают все? (x=1, y=2 - x,y переменные & 1,2 - параметры) Обратиться к бд в PHP мы можем посредством операторов, которые можно понимать как ключевые слова, играющие роль нашей фразы "Вася, кто там у нас 3-й по счету в очереди за колбасой?". Только вот кусочки фразы такие как "Вася", "3-й", "в очереди", "за колбасой" - это наши параметры и переменные, а все остальное -
    операторы. С основными операторами для обращения к базе данных вы можете ознакомиться в любом FAQ по реляционным базам данных, в частности MySQL.

    Вот исчерпывающий FAQ по языку SQL:
    ----------------------------------------------------------------------------------------------------
    _http://www.lib.csu.ru/dl/bases/prg/kompress/articles/2000_10_DBMS6/#03
    ----------------------------------------------------------------------------------------------------

    Основные операторы, с которыми мы будем работать:

    И так у нас есть страничка на php, которая взаимодействует с SQL базой данных. Представим себе форму авторизации. И так, перед нами обычная форма авторизации, с полями для ввода логина и пароля. Как только вы заполняете оба поля и топите кнопку "Логин", если данные верны, вы видите перед собой свой акк, если нет, на страничке вылетает ошибка, типа "Неверный логин или пароль". Что же в это время происходит на самом деле? Нажав на "кнопочку", в php-скрипт, двум переменным, например $login и $password, передаются ваши логин и пароль соответственно. В скрипте формируется запрос к базе данных, вида:

    Где "members" - это наша таблица в бд, а "admin" и "pwd" - введенные нами данные.

    Примерно также происходит и в обычном скрипте новостного портала. Но тут уже наша переменная и ее параметр находятся непосредственно в ссылке. Пример:

    А вот так это выглядит в запросе к бд:

    Где "news_id" - наша переменная из ссылки, а "1" после знака равно - наш параметр. Числовые параметры кавычками не обрамляются. И забыл о главном, в форме авторизации, в первом примере, данные в скрипте передаются методом POST, то есть в адресной строке мы их не видим, а во втором случае с новостным движком, данные передаются методом GET и переменная с параметром отображается в адресной строке, что удобнее для нас. Подробнее о методах GET и POST можно почитать в гугле.


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

    То есть начальный запрос к бд (Базе Данных) выглядит так:

    -------------------------------

    Уязвимость состоит в том, что переменная "news_id" в скрипте - не фильтруется, от параметров отличных от нормальных. То есть мы можем внедрить в ссылку свой запрос и он выполнится как часть скрипта.

    -------------------------------

    Например:

    Код:
    _http://site.com/script.php?news_id=1+SELECT+FROM+users+password+WHERE+login+LIKE+%27admin%27;
    Это не практичный вариант, зато очень наглядный, как пример, и логически правильный. В результате перехода по такой ссылке, запрос в скрипте становится другим, т.к. мы передаем в переменной свой запрос к серверу и просим его чтобы он нам вывел пароль из таблицы "users" где логин = админ. Замете, в конце запроса мы добавляем знак начала комментария, в нашем случае "; -- ", обычно он необходим, но иногда не важно стоит ли он, иногда необходим, а иногда наоборот, с ним, ничего не выходит. Самый распространенный знак начала комментария - "/*", также есть "--", "#", пробуйте разные или вообще без, если что-то не получается, но об этом мы еще поговорим.

    Напомню, в ссылку мы внедрили наш код, напомню ссылку:

    Код:
    _http://site.com/script.php?news_id=1+SELECT+FROM+users+password+WHERE+login+LIKE+'admin';
    --

    Смотрим что же у нас получилось в самом PHP скрипте (помним что "+" - это пробел):

    Видим что все плюсы из адресной строки у нас превратились в пробелы и что после "1" стоит теперь наш запрос к серверу, в котором, как я уже упоминал, мы просим его вывести пароль админа. Вот так вот, на первый взгляд все просто, но на самом деле, только в идеале все настолько просто.


    Ну что, это была теория (много теории), теперь перейдем непосредственно к практике. Как я уже говорил, речь пойдет о методах обнаружения (поиска) скл-инж. Начнем с самой обычной скули.
    Так, как я и обещал банальная скуль:

    Начальная ссылка:

    -------------------------------

    Подставляем кавычку:

    Так, тут, если скуль самая обыденная, выскакивает ошибка типа:

    Т.к. мы решили начать с самого простого, можете сразу начать подбирать столбцы (об этом я тоже расскажу, но о "раскрутке" уязвимости можете почитать в статьях, которые приведу ниже, в моей статье я буду доходить максимум до вывода версии).

    --------------------------------------------------------
    Сразу расскажу об операторе "order by":

    --------------------------------------------------------

    Пробуем :

    Смотрим ответ сервера, предположительно должна вылететь ошибка, т.к. обычно столбцов от одного до тридцати, но этот навык у вас успеет наработаться со временем. Теперь пробуем уменьшить количество столбцов до минимума, чтобы знать точно что в данном случае уязвимость есть.

    Пробуем:

    Так, видим что страничка отобразилась корректно, значит в таблице как минимум один столбец.

    Теперь пробуем например 10:

    Отобразилась с ошибкой?! Делаем вывод, столбцов меньше 10-ти.
    И так перебераем вниз от 10-ти пока страничка опять не отобразится корректно, можно сразу попробовать 5, а потом в зависимости от наличия или не наличия ошибки идти вниз(5,4,3,2) от 5 или вверх(6,7,8,9). Так, страничка с "+order+by+7" отобразилась некорректно (с ошибкой), а "+order+by+6" - нормально, значит столбцов 6. Можем выводить версию. Для Вывода данных используется дует "union+select" за что отвечают эти операторы, вы уже знаете.
    Начнем.

    Заметили что после запроса "юнион+селект" я выписал через запятую номера столбцов то 1-го до 6-ти, т.к. столбцов у

    нас 6.
    Если все получилось, то на страничке отобразится одна из циферок которые вы вписали, она может быть где угодно, но выглядит она обычно не так как весь остальной текст на страничке (которого в идеале, должно почти не быть). К примеру на страничке отобразилась цифра "3", поздравляю, можете менять запрос и выводить версию (с того самого 3-го столбца):

    Код:
    _http://site.com/script.php?id=1+union+select+1,2,version(),4,5,6/*
    Ну что, увидели версию базы? Можете двигаться дальше, ну а об этом уже читайте в многочисленных статьях о скл-инъекции. (ссылочки, как и обещал, приведу ниже). Так, это мы обсудили простейшую ситуацию, когда вам очень повезло и никакую галамурину мутить не пришлось... Теперь пойдем посложнее, основы я объяснил, в дальнейшем буду эти самые действия описывать более коротко. Так, помним, что чтобы обратится к столбцам из таблицы для вывода данных из них, мы подобрали, чуть раньше, количество столбцов в этой саймой таблице, которая расположена на нашем псевдо сервере, в базе данных

    Ну что, у нас тот же самый сайт:

    Та же ошибка, представим что мы подобрали столбцы ордером, но вывода нет... Формируем запрос:

    Отображается обычная, заполненная контентом страничка, нету вывода, ну нету его, что делать?

    Просто меняем начальный параметр параметр переменной (в нашем случае - "1", если до кого не дошло, меняем в ссылке, вот в этом месте - id=1) на несуществующий (отрицательный, мегабольшой, а лучше и то и другое)

    Получаем:

    В итоге страничка отображается коряво, зато мы видим вывод. А дальше все по инструкции. Если еще в начале всех этих действий, как раз там где начинаем подбирать столбцы ордером, все время высвечивается ошибка или наоборот контент, но мы уверены что инъект там есть, пробуем оставить кавычку, то есть:

    Либо "поиграть" с окончанием запроса (знаком начала комментария):

    Помните, вы должны среди всей этой тучи запросов найти логику!


    Ну что, поговорим о логике?! Сейчас познакомимся с применением операторов and (логическое "и") и or (логическое "или") при выявлении скл-инж.

    Задействуем опять наш универсальный сайтег (надеюсь все понимают что это "манекен" и такого сайта не существует?! о_0)

    Только теперь у нас есть способ пограмотнее, причем именно этим способом можно найти скл-инж при самых адекватных ответах сервера (если она там есть). Имеется ввиду что приведенная мною ссылка на страничку (в примере), является полноценной, то есть страничка отображается, например, на странице расположена новость... Теперь немного поговорим о правде и лже, все знают что это такое. Так вот у нас своя истина и ложь, имеется ввиду ответ сервера (ложный - страница с ошибкой или нормальная но...) либо правдивый (нормальная страничка или страничка обозначающая "истину"). Истина и ложь в булевом представлении это 1 и 0 относительно. Если не слышали про такое, почитайте самоучитель по паскалю, аль васике например, даже если не собираетесь кодить, просто лучше знать хотя бы
    основы (да и логику кодинг развивает)... Ну что 1 - истина, 0 - ложь, уяснили? Теперь попробуем "поболтать" с сервером посредством этих двух цифер о_0 и оператора and/or.

    Берем обычную нормальную страничку, приведенную мной чуток выше. Отображается обычная статья. Теперь подставляем оператор and и булево представление правды(1).

    И видим что статья осталась по прежнему той же, тут либо есть скуль, либо сервер не реагирует на все что мы дописали после начального параметра. Сейчас выясним что же это. Добавляем нолик - булево представление лжи.

    Страничка отобразалась некорректно, с ошибкой, отобразилось нормально, но другая?! Тогда это скуль.
    Дальше все как обычно, подбираем столбцы...


    Если вывод ошибки есть, вы увидите ошибку, если нет, но страничка отобразилось некорректно, или отобразилась та же страничка что и при "and+0", но отличная от "and+1", могу поздравить, у вас есть "ваша ложь", а если есть ложь и истина, что мешает нам спрашивать у сервера что правильно а что нет, если не вывода ошибки например, либо ошибка не меняется и не объясняет что, к примеру, здесь не то количество столбцов подставили, а здесь не совпадает кодировка...
    Пользуйтесь этим чтобы выведать где вы ошиблись, а где все сделали правильно.

    Поздравляю, у вас 5 колонок, принцип понятен?! В таком случае идем дальше... Подобрали мы столбцы, ищем столбец с выводом...

    Опять нормальная страничка с контентом, а вывода нет? Помните что мы делали в прошлый раз, меняли начальный параметр на несуществующий, сейчас не обязательно, ведь мы можем вежливо попросить вывести нам "ложную"(некорректную) страничку, чтобы найти на ней вывод.

    - как видно, теперь вместо "and+1"

    мы подставили "and+0", теперь наша "правдивая" страничка отобразится "ложно" и мы получим вывод. Также экспериментируйте и с оператором or. Разницу почувствуете сами, но в основном стабильно работает и and... Быть может такое, что до вывода вы так и не достучитесь, бывает и такое, называется Blind SQL-injection (слепая скл-инж), это отдельная тема и рассуждать я об этом сейчас не буду, но работает по тому же принципу, истина-ложь. Ведь иногда кажется что либо здесь слепая скл-инж, либо ее нет вообще, но этот метод выручал, пройдя долгий путь по подбору колонок ,оперируя, казалось бы нормальными страничками, без вывода свойственных скл-инж ошибок, подобрав таким методом
    колонки, я доходил до долгожнанного вывода.

    Один вам совет с этим всем, экспериментируйте, экспериментируйте и еще раз экспериментируйте!


    Теперь рассмотрим еще пару совсем маленьких примеров, а потом вам приведу пример из жизни. Ситуация обыденная, подобрали столбцы, есть вывод.

    Отобразилась цифра "2" например, выводим версию.

    Такс, вывод ошибок либо отключен, либо он не сигнализирует нам о главном. Облом, бред какой то, все подобрал, а версию не выводит ту же версию, пробуем закодировать запрос в char(). Эта кодировка распространена когда magic quotes на сервере включены (настройка такая) и кавычки в запросе фильтруются, приходится кодировать запрос либо в чар-код либо в хекс-код. Об этих кодировках вы можете найти много материала помучав гугл, а я сразу к примеру...

     
    Последнее редактирование модератором: 30 ноя 2008
    14 окт 2008
    6 пользователям это понравилось.
  2. Хел
    Хел Guest
    добавлю еще как выяснить количество колонок в таблице:
    Код:
    http://***********.com/*****/news_****.php?Re*********er=-135+and+(select+*+from+login+limit+0,1)=(1,1,1,1,1,1,1)
    
    это в качестве примера. Соответственно колонок 6, подбираем массивом чисел во второй части. Думаю метод ясен.
     
    14 окт 2008
    2 пользователям это понравилось.
Загрузка...