Конкурс SQL-injection challenge

Всем привет!

В продолжение серии статей 1 2 3 4 5 6 я решил приготовить вам сюрприз в виде таска. По моей оценке сложность задачи 8 из 10 баллов. Предлагаю всем желающим пошевелить мозгами, и испытать свои навыки по внедрению произвольного кода в базы данных.

Условия конкурса

1. Взломать базу данных, и вытащить оттуда secret_key
2. Прислать своё решение мне в л.с. (подробное прохождение)
3. Дать свою оценку сложности таска по 10 балльной шкале

Конкурс продлится 10 дней, окончание конкурса 8 сентября в 23 ч по МСК.

Ответы от зарегистрированных на форуме после старта конкурса НЕ принимаются.

Администрация форума предоставила призы для конкурса:

1. Место - Alfa AWUS036H
2. Место - 500 рублей
3. Место - 500 рублей

Места победителей распределяются по очерёдности решения - кто первый выполнит задание, тот и первый, и т.д.
Запрещается писать до окончания конкурса в теме прохождение и подсказки. После окончания конкурса, будут опубликованы имена победителей и write up.

hacker.gif


GO!!!
 
Я догадался, что ты комменты просто вырезаешь. Поэтому нормализовал запрос из серии ' union select 1,2 union select 1,'2
 
Это другие комменты не катят. Проверять можно было примерно так:
1'-- -
1'--+
1'#
1';%00

Сравни эти запросы и увидишь разницу.

SooLFaa - подход с %27 работает очень ограниченно, поэтому дальше не пошло. Ни с limit ни group_concat уже не проходит.
 
Это другие комменты не катят. Проверять можно было примерно так:
1'-- -
1'--+
1'#
1';%00

Сравни эти запросы и увидишь разницу.

SooLFaa - подход с %27 работает очень ограниченно, поэтому дальше не пошло. Ни с limit ни group_concat уже не проходит.
Вот тут то и оно. Костыльно но прикольно. Дальше вектор как часы крутиться тем что я присылал.
 
SQLMAP даже справляется если его правильно сварить.
 
Поскольку первое место выиграно, выкладываю подсказку.
Вся проблема у участников возникла прямо на ровном месте, там где я вообще не ожидал. Начинать таск нужно было с подбора комментария. Разве сложно несколько комментов проверить???

Старт решения таска id=1';%00
SooLFaa мог бы решить в первый день, если бы правильный коммент поставил в запросах.
Теперь должны решить те кто не догадался раньше. Если за сутки остальные 2 места не заберут, то выложу завтра вторую подсказку.
Расскажешь о типах комментариев? Вообще не представлял, что есть нечто подобное, что браузер не станет декодировать в обычный символ
 
Тебе нужно было не в безопасность, а в рекламу и маркетинг - господи помилуй, да что ж такое. Но хорошо, id=1';%00 так id=1';%00.
 
комментарии вроде бываю 3 видов
- -, /*, #
А %00 видимо что бы обрубить какой то фильтр
 
Расскажешь о типах комментариев? Вообще не представлял, что есть нечто подобное, что браузер не станет декодировать в обычный символ
Уже рассказывал, и даже в этой теме давал ссылку на статью
Здесь использовался нулевой байт %00, 0x00, null byte это недокументированный комментарий. Нулевой байт применяется в языке СИ, и является концом строки. Таким образом он работает.
комментарии вроде бываю 3 видов
- -, /*, #
А %00 видимо что бы обрубить какой то фильтр
Нет, больше, ещё есть
 
  • Нравится
Реакции: HebiNeco
Осталось 36 часов до окончания. Пересмотрел логи. Есть несколько человек, которые ходят прямо рядом, но почему-то до сих пор используют не то окончание в запросах. И часть юзеров поняли буквально мою подсказку и ставят запрос после id=1';%00payload а нужно id=1'payload;%00

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

Вторая подсказка
Это уже даже больше чем подсказка routed injection
Кто не знает что это гуглим.
 
Последние новости - есть ещё один решивший. Хочу сказать, что он проявил адскую настойчивость и очень старался. Только за настойчивость можно дать высокую оценку.
Так что как говорится "дорогу осилит идущий". Большое спасибо за участие!!!

Осталось ещё достаточно времени чтобы решить, хоть уже и с подсказкой. Самое главное в этом таске - не пытаться сразу делать сложные запросы, всё проще, чем кажется. Уделяйте внимание мелочам.
 
Может, я конечно, чего-то не понимаю (99,9% так и есть), но, эм, где собственно база данных? На адресе открытой базы нету (есть только защищённая брандмауэром). Вроде люди говорят про то, что на главной странице есть запросы к базе данных, но эм, как на такой странице
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SQL Injection</title>
</head>
<body>
<style>
.marginauto {
    margin: 10px auto 20px;
    display: block;
    
}
@media (max-width:600px)
{
.marginauto{width: 100%;}
}
</style>
You Hacker???<div>
<br>
<p>Bla-bla-bla!</p>
</div>
</body>
</html>
где-то могут быть вообще какие-то запросы? Вроде как получить исходный php код страницы можно только с помощью некоторых уяизвимостей, которых, судя по всему, на сервере нет.
 
Может, я конечно, чего-то не понимаю (99,9% так и есть), но, эм, где собственно база данных?
где-то могут быть вообще какие-то запросы? Вроде как получить исходный php код страницы можно только с помощью некоторых уяизвимостей, которых, судя по всему, на сервере нет.

Исходный код php вы и не должны видеть, а он есть ) Если коротко - PHP предназначен для сервера, а для клиента HTML. Поэтому исходный код страницы полностью увидеть нельзя, кроме случаев когда есть на сайте уязвимости позволяющие это сделать.

База данных находится собственно в базе данных, тут у вас огромный пробел в понимании. Чтобы с этим вопросом разобраться у меня написана серия статей, ссылки есть в начале темы. Первые 3 ссылки как раз по работе с БД.

Запрос к базе данных здесь bypassing.su/?id=1
В коде страницы запрос выглядит примерно так $sql="SELECT *** FROM *** WHERE id='$id'";
звёздочек там нет конечно, а есть обращение к конкретным столбцам из таблицы.
 
  • Нравится
Реакции: ilyamikheevcoder
Сегодня в 23 часа конкурс завершается!

Ещё есть много времени чтобы решить, с такими подсказками первая вторая там уже ничего не остаётся как обойти фильтрацию средней сложности и всё.
 
  • Нравится
Реакции: ilyamikheevcoder
Это сообщение "Discovered Hacker!" меня уже совсем с толку сбивает. Что это? Сообщение от фильтра? Перехват ошибки? И то и другое? Аааааааа...
 
Это сообщение "Discovered Hacker!" меня уже совсем с толку сбивает. Что это? Сообщение от фильтра? Перехват ошибки? И то и другое? Аааааааа...
Дам уже третью подсказку - это сообщение выходит и при ошибке БД, и при срабатывании фильтра. Таким образом я всех запутал ))) Однако эту логику несложно было отследить, и понять когда есть начальная страница, а когда картинка появляется.
 
Конкурс завершился!

Результаты конкурса

Решили задачу 3 человека:

Первый решил sinner67 максимально близко к задуманному
Второй решил Bidjo111 раскрутив таск вслепую
Третий решил SooLFaa грязновато, но всё же результат получил

sinner67 сказал, что он решает вне конкурса, чисто для себя. Таким образом результаты выглядят так:

1 место - Bidjo111
2 место - SooLFaa
3 место - не занял никто


Что я задумывал в задаче:

Сделать её достаточно сложной, амбициозной, но одновременно решаемой несложными запросами.
Сделать решение невозможным при помощи автоматизированных программ, и наглядно показать что "sqlmap не панацея".

Мои впечатления и наблюдения:

Таск задумывался чтобы оценить общий уровень подготовки форумчан. К большому сожалению он оказался весьма низким. Я рассчитывал, что решивших будет больше. Я считаю, что такие уязвимости как SQL и XSS, все интересующиеся ИБ должны знать не ниже чем на среднем уровне. Эти уязвимости бессменно входят в OWASP Top 10.

Хочу сказать огромное спасибо ВСЕМ кто участвовал в конкурсе! Ваша активность была колоссальной!!! Сервер кряхтел и дымился от шквала запросов.

Несмотря на мои многократные предупреждения, насчёт использования программ, 99% запросов были автоматическими. И лишь неделю спустя после старта конкурса, стало заметно больше ручных запросов.

По ходу конкурса я не раз давал намёки, а потом и подсказки. Тем не менее решивших очень мало. Я покажу вам наглядный пример, как один из участников Bidjo111 проявил внимательность к моим комментариям, и поэтому смог решить таск ещё до выкладывания конкретных подсказок.

Bidjo111 прислал мне отчёт по таску, которым я просто зачитался. Выражаю огромную благодарность тебе за столь замечательное описание прохождения задачи!!!
-------------------------------------------------------------
Отчёт от Bidjo111:

Настроившись на то, что таск будет сложным, сразу же начал решать не с того конца. Вместо подстановки одного из самых популярных параметров в запрос GET, я начал искать уязвимость в заголовках http. Перепробовав кучу вариантов все-таки вспомнил про самый простой. Вспоминается совет на форумах HTB, где одной из самых часто встречаемых подсказок является ”Don’t overthink”.

Итак мы имеем:

?id=1
...что дает нам задуманный разработчиком результат.

Далее, разумеется, сразу полетела кавычка, которая получила в ответ алерт. Так как я заранее знал, что на этой странице должна присутствовать инъекция, то закомментировал строку всеми способами, которые помнил. Но ни один из них не сработал. Далее подставлял другие кавычки, игрался со скобками и т.п. Попробовав разные комбинации с символами вспомнил, что помимо кавычек и скобок уязвимость может быть в ошибке логики запроса. И тут, сделав вполне закономерный запрос, но категорически неправильный вывод, я совершил фатальную ошибку:

?id=0 or 1
...который выдает результат при id=1 и

?id=0 or 0
...который выдает результат при id=0. Идеально.

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

Дальше в ход пошел брат Гугл, всевозможные мануалы, методички из курса WAPT. Тут я совершил вторую ошибку. Проштудировав вдоль и поперек материалы курса, в моей голове в переменной методичка было решительно выставлено значение «полностью усвоено», отчего впоследствии я к ней не возвращался ни разу, что в дальнейшем кардинально повлияло на ход решения.

Прочитав первый намек создателя таска на то, что подсказка находится в его статьях, полез читать их, перечитывать и разбирать все мало-мальски непонятные моменты. Тут уже и наткнулся на комментарий вида ;%00, который прекрасно подошел к запросу

?id=1’;%00
Дальше следовали многие часы долбежки в стену головой из-за того самого неправильного вывода, пробела и операторов and и or. Причем все трое тихонько отфильтровывались и я получал ерунду на выходе. Западня заключалась в том, что в большинстве запросов я одновременно использовал и пробел и оператор сравнения и догадаться, что они могут оба фильтроваться я никак не мог. Часто приходили мысли о том, что что-то из этого отбрасывается, применял соответствующие техники, но не одновременно к обоим объектам.

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

?id=0’ %7c%7c sleep(10);%00

Настроение улучшилось, так как наконец-то найден способ влиять на БД. Тут уже стало ясно, что и and и or отбрасываются фильтром, и про символ пробела я на время уж тем более забил. Дальше по технике timebased стал потихоньку раскручивать это дело. Получалось что-то вроде этого:

/?id=1’ %26%26 if(true,sleep(3),0);%00
...этот запрос работал, за ним шел
?id=1’ %26%26 if((ascii(substring(‘a’,1,1))>96),sleep(3),0);%00
...который тоже работал. Решив, что дело в шляпе тут же шмальнул

?id=1’ %26%26 if((ascii(substring((select database()),1,1))>96),sleep(3),0);%00
Тут я растерялся ибо все шло вроде нормально, и на ровном месте запрос не сработал. Напомню, что про пробел я на тот момент еще не знал. Более того в начале запроса стояли пробелы и, не смотря на это, все работало. Перепробовав разные варианты я чуть ли не случайно сделал следующий запрос

?id=1’ %26%26 if((ascii(substring((database()),1,1))>96),sleep(3),0);%00
...и был в шоке. Запрос дал задержку по времени.

Вытащив название базы и юзера начал уже мозговать, отчего и почему так. Стал разбирать не “почему работает без select”, а “почему НЕ работает С select”. Решив, что SELECT как-то фильтруется, стал применять техники обхода. Каково было мое удивление, когда сработал следующий запрос:

?id=1’ %26%26 if((ascii(substring((select @@version),1,1))>96),sleep(3),0);%00
Это был «контрольный выстрел». Тем не менее такой конструкцией удалось вытащить имя одного из «хозяев» денег. А так же наугад подобрал несколько названий колонок.

Так как хоть какой-то вывод на экран значений из БД у нас есть, изменил запрос, чтобы избавится от sleep().

?id=1’ %26%26 if((ascii(substring((select @@version),1,1))>96),1,0);%00
Тут на экране получаем «500000», если выражение в if верно и «You hacker», если нет.

В общем на этом этапе, кроме имен в колонке “name”, я больше не понял как и что вытаскивать. Здесь на ход решения повлиял комментарий тов. Explorer-а о том, что я пошел самым нерациональным путем. С одной стороны я обрадовался, что данный метод все-таки может увенчаться успехом, но с другой обидно, что за столько времени так и не удалось напасть на правильный след.

На следующий день выдалась пара свободных минут, и я попробовал пару идей из браузера телефона. Там было жутко неудобно редактировать длинные запросы, поэтому я решил заодно поискать тот самый «рациональный» путь. Для этого вернулся к исходному простому запросу, который не работал.

К тому моменту я уже понял, что когда мы видим «Hacker detected», то это значит, что наш запрос — неправильный с точки зрения синтаксиса или логики. Но еще и отфильтровываются некоторые символы/строки. В результате, даже если мы составим правильный/рабочий запрос, то если будут вырезаны некоторые символы, то либо синтаксис либо логика запроса будет нарушена и в итоге запрос будет «сломан» и мы получим алерт.

Итак я ввел исходный

?id=1%27;%00

Здесь никак не хотели работать ни «union select» ни «group by». Но по вышеуказанным причинам я был уверен, что фильтруются строки. И тут наконец-то пришла спасительная мысль, что все дело в символе пробела. Проверив, оказалось, что так и есть:

?id=1%27group/**/by/**/1;%00
Запрос прекрасно работал и показал мне количество столбцов. Все эти несколько дней я не замечал такой простой вещи и из-за этого получал странные результаты, которые в свою очередь толкали меня к неверным выводам.

Далее сразу же последовало

?id=1%27union/**/select/**/1,2;%00
...на что алерта не последовало, что говорило о синтаксической правильности запроса, но результата я на экране не увидел. Здесь как раз и сыграла свою роль моя неуместная уверенность в том, что я уже перечитал и перегуглил все, что можно на эту тему. И если задача и решается дальше, то каким-то экзотическим методом, которого я еще не нашел. Зато теперь можно было продолжать мой «нерациональный» путь, что я и сделал, так как хотел решить таск как можно скорее.

?id=1%27%20%26%26%20if((ascii(substring((select/**/table_name/**/from/**/info%2brmation_schema.tables/**/where/**/table_schema/**/like/**/database()/**/limit/**/0,1),1,1))>96),1,0);%00
Учитывая, что строка «or» и символ «=» фильтруются, применил техники обхода. Запрос сработал. Я так обрадовался, что яростно стал подбирать всю необходимую информацию и в итоге нашел ключ. Но на это потребовалось время. Благо база была всего из двух таблиц и нужная таблица лежала именно в этой базе.

Когда узнал про routed sql, осознал до конца свою главную ошибку. Этот метод русским по белому был подробно описан в методичках WAPT, но увы, мой неметодичный подход к решению наказал меня.

С другой стороны, если метод «timebased» вообще не работал и я бы не тратил на него столько времени, думаю, рано или поздно я бы догадался про routed.

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

Explorer, большое спасибо за задачу и конкурсную мотивацию!
-------------------------------------
Послесловие:

Очень неожиданно и прямо эпично получилось с участниками:
sinner67 - инструктор курса WAPT от Codeby
Bidjo111 - ученик из TOP-а курса WAPT
Ну и создатель таска оттуда же )

Скрин с курса WAPT:

123.png


Так что наглядно видно, что курс от Codeby даёт реальные результаты. К слову говоря, после того как Bidjo111 прислал мне secret_key, я ему дал подсказку routed sql и предложил перерешать. Менее чем за пол-часа он уже прислал мне payload на 100% повторяющий оригинальную задумку!!! Меня это здорово порадовало. Мой большой респект, человек умеет думать, учитесь )

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

Ещё раз всем огромное спасибо, до встречи!
 

Вложения

  • 123.png
    123.png
    21,8 КБ · Просмотры: 160
Спасибо Сереж. Вот это номер. Я ему UNION - Based в итоге сварил, а он говорит грязное.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab