3500 долларов за слепую SQL-инъекцию в GraphQL

3500 долларов за слепую SQL-инъекцию в GraphQL

SHADOW:Group

Оригинал статьи на английском тут.

Итак, я просидел несколько часов и вернулся со статьей об ещё одной серьезной, но простой SQL-инъекции, которую я недавно обнаружил в веб-приложении.

Несмотря, на частное приглашение, это приложение очень популярно среди хакеров, и многие из них уже попробовали там свои силы. Когда я получил приглашение, я заметил, что цель уже находится на BugCrowd более 2 лет, где было обнаружено и вознаграждено более 250 багов. Когда я нажал на кнопку "Принять приглашение", я уже знал, что нелегко найти даже ошибки P3, не говоря уже о P1 или P2, но я также знал, что я должен быть творческим и мыслить нестандартно, чтобы найти что-то, что никто больше не обнаружил.

SQL инъекция в GraphQL запросе

Таргет имел огромный скоуп, но поддомены в него не входили. Скоуп выглядел примерно так target.*. Мне показалось интересным, что он охватывает широкий спектр TLD (например: target.co.uk, target.it, target.ae, target.co.in, target.com и т. д.).

Так как наша цель присутствовала в каждой стране мира, я знал, что можно легко найти TLD с помощью certificate transparency (CT), поэтому я открыл главный веб-сайт target.com у себя в Firefox, чтобы найти название организации в SSL (как на скриншоте приведенном ниже) и скопировал его.

Стоит отметить, что большинство организаций регистрируют свой SSL-сертификат под названием организации, например, "Twitter, Inc". Поэтому при поиске поддоменов или TLD убедитесь, что вы выполняете поиск по имени организации.

Затем я использовал netlas.io и crt.sh, чтобы найти все возможные домены TLD в этой организации. После объединения результатов было более 7 тысяч строк, включая поддомены. После фильтрации осталось всего 64 конечные точки.

HTTP Probing и обнаружение параметров

Я скопировал этот список на свою виртуальную машину Kali и прогнал через httpx. В результате осталось 57 конечных точек.

Затем, я прогнал этот список через ParamSpider, используя следующую команду с флагом --subs False, чтобы исключить поддомены.

cat targets | xargs -n 1 -I {} python3 ~/ParamSpider/paramspider.py --subs False --domain {} --level high | urldedupe >> all-param.txt

ParamSpider выполнял свою работу некоторое время и вернул около 20 тысяч URL-адресов. Я удалил мусорные данные, чтобы получить окончательный список из 12 тысяч хороших URL-адресов.

Я начал проверять параметры и URL-адреса, но, к сожалению, обнаружил, что большинство из них похожи на страницы с товарам , например:

https://www.target.co.xx/en/xxxx/category2/men/t-shirts.xxx?n=xx&s=xx&ww=xxx

Они были безполезны для меня, так как один и тот же параметр присутствовал более чем в 10 тыс. URL-адресах. Я протестировал пару из них на SQL-инъекции и XSS и обнаружил, что они не уязвимы.

Я отфильтровал все эти URL-адреса с товарами и составил хороший список из 1,6 тыс. URL-адресов.

Сканирование Nuclei

Поскольку я хотел проверить технологии, лежащие в основе этого списка, я запустил дефолтное сканирование Nuclei.

Через несколько секунд у меня были результаты. Один из них привлек мое внимание. В одной из стран используется GraphQL, но похоже, что в нем есть неправильная конфигурация.

Сканирование Burp Suite

Когда есть подсказка, я всегда подтверждаю её через Burp Scanner. То же самое и здесь, я отправил URL-адреса через Burp и начал активное сканирование. Через несколько минут, бурп обнаружил потенциальную SQL-инъекцию в запросе, когда в теле запроса была отправлена одинарная кавычка ('). Сервер ответил "500 Internal Server Error".

Однако Burp Suite пометил проблему как требующую проверки, поэтому я не был уверен, есть ли здесь уязвимость SQL инъекции или это просто ложное срабатывание.

SQLMAP и Ghauri не смогли найти инъекцию

Я скопировал запрос и отправил его в SQLMAP и Гаури, но они оба не смогли найти никаких инъекций.

Я решил взять все в свои руки и провести ручное тестирование, так как доверял Burp Suites в его способности найти такую уязвимость, и был уверен, что она не может быть ложноположительной. Забудьте обо всех других конечных точках, пока я не подтвержу, что SQLi невозможен.

Поиск правильного запроса GraphQL

Я открыл Burp и послал запрос на уязвимый URL-адрес, а также выполнил перехват запроса, чтобы проанализировать, как он реагирует на различные типы запросов.

Проведя час, я, наконец, захватил полный запрос, который использовался для получения "гендерных" данных пользователя. Запрос принимает 3 ключевых слова "M,F,NA", которые являются сокращением для ключевых слов Male, Female и Not Applicable.

Пример запроса приведен ниже:

{
  "query":
  "query ($_key***_0:String!, $_***_0:Int!) {*****
  (keyword:$_key***_0, ****:$_***_0){ key***_text, number_of_result, 
  number_of_uses, ***_id, gender_cd, url }}",
  "variables":{
    "_key***_0":"M",
    "_***_0":"1"
  }
}

Поиск слепой SQL-инъекции

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

Из сканирования Nuclei я знаю, что приложение использует PHP и работает на Apache. Я начал отправлять полезные нагрузки Sleep для MySQL. Для одной из них сервер задержал ответ на 10,121 секунду. Я подтвердил уязвимость, используя несколько полезных нагрузок с разными временными задержками.

XOR(if(now()=sysdate(),sleep(9),0))XOR\"Z

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

Я немедленно подготовил отчет и представил его. Отчет был принят и программа заплатила мне 3500 долларов за усилия + 40 баллов.

На этом все, спасибо за просмотр!

Подпишись на канал - @shadow_group_tg.

Report Page