автордың кітабын онлайн тегін оқу Ловушка для багов. Полевое руководство по веб-хакингу
Переводчик С. Черников
Литературный редактор А. Руденко
Художник В. Мостипан
Корректоры Н. Сидорова, Г. Шкатова
Питер Яворски
Ловушка для багов. Полевое руководство по веб-хакингу. — СПб.: Питер, 2020.
ISBN 978-5-4461-1708-6
© ООО Издательство "Питер", 2020
Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.
Об авторе
Питер Яворски стал хакером, самостоятельно изучая опыт предшественников (некоторые из них упоминаются в книге). Ныне это успешный охотник за уязвимостями, на счету которого благодарности от Salesforce, Twitter, Airbnb, Verizon Media, Министерства обороны США и др., сейчас он является инженером по безопасности приложений в Shopify.
О научном редакторе
Цан Чи Хонг, известный под псевдонимом FileDescriptor, — пентестер и охотник за уязвимостями. Проживает в Гонконге, пишет статьи о веб-безопасности на сайте blog.innerht.ml, интересуется саундтреками и криптовалютой.
Предисловие
Чтобы чему-то научиться, надо применять знания на практике. Именно так мы освоили ремесло взлома.
Как и у всех в этом деле, нашей главной мотивацией было любопытство. Мы обожали компьютерные игры, и к 12 годам захотели создавать собственные программы. Освоить программирование на Visual Basic и PHP нам помогли книжки из библиотеки.
Имея некоторое представление о разработке ПО, мы начали находить ошибки разработчиков. И перешли от созидания к разрушению. Чтобы отпраздновать окончание средней школы, мы перехватили управление каналом телевещания и прокрутили ролик с поздравлением нашего класса. Это казалось забавным, пока мы не узнали о последствиях подобных действий — такой хакинг не поощрялся. Мы были наказаны и провели все лето за мытьем окон. В колледже нас занимал доходный консалтинговый бизнес, который обслуживал государственных и частных клиентов во всем мире. А кульминацией нашего опыта стала компания HackerOne, которую мы основали в 2012 году. Мы хотели, чтобы любая организация могла сотрудничать с хакерами, и это остается нашей миссией по сей день.
Если вы это читаете, вам присуще любопытство хакера. Эта книга станет для вас отличным путеводителем. Она полна показательных примеров нахождения уязвимостей.
Чрезвычайно важна и ее направленность на этичный хакинг. Умение взламывать дает человеку рачаги влияния, которые, как мы надеемся, будут использованы во благо. Успешные хакеры умеют балансировать на тонкой грани между добром и злом. Разрушать могут многие, и на этом даже можно подзаработать. Но сделать интернет безопаснее, сотрудничать с крупными компаниями и получать серьезные вознаграждения смогут не все. Надеемся, что вы направите ваш талант на безопасность людей и их данных.
Мы бесконечно благодарны Питу за то, что он задокументировал множество примеров и сделал это настолько выразительно. Жаль, что в начале нашего пути не было такого материала. Эту книгу приятно читать, и в ней есть вся информация, необходимая для начинающего хакера.
Приятного чтения и хакинга!
Будьте ответственным хакером.
Майкл Принс и Йоберт Абма, соучредители HackerOne
Благодарности
Эта книга стала возможной благодаря сообществу HackerOne. Я хочу поблагодарить генерального директора HackerOne Мартена Микоса, который связался со мной в самом начале пути и неустанно делился своими впечатлениями и идеями, помогая сделать книгу лучше. Он даже заплатил за профессиональный дизайн обложки, когда изданием занимался я сам.
Также хочу выразить признательность соучредителям HackerOne Михелю Принсу и Джоберту Абме, которые поучаствовали в написании некоторых глав, когда я работал над ранними версиями книги. Джоберт выполнил редактуру каждой главы, предоставив технический анализ. Его правки укрепили мою уверенность и многому меня научили.
Не могу не упомянуть Адама Бакуса, который прочитал эту книгу через пять дней после начала своей работы в HackerOne. Он предложил свои правки и объяснил, что чувствует человек, получающий отчеты об уязвимостях. Компания HackerOne с большим вниманием отнеслась к созданию книги, направленной на поддержку сообщества хакеров.
Хочу поблагодарить отдельно Бена Садегипура, Патрика Ференбаха, Франса Розена, Филиппа Хэрвуда, Джейсона Хэддикса, Арне Свиннена, FileDescriptor и других опытных хакеров, поделившихся своими знаниями.
Эта книга не появилась бы на свет, если бы хакеры не обменивались информацией и не раскрывали обнаруженные ими уязвимости. Спасибо вам всем.
И, наконец, именно благодаря любви и поддержке жены и двух дочерей я стал успешным хакером и сумел собрать этот материал. А также большое спасибо остальным членам моей семьи, особенно моим родителям, которые вместо приставки Nintendo дарили мне компьютеры, приговаривая, что за ними будущее.
Введение
Эта книга познакомит вас с этичным хакингом — поиском уязвимостей безопасности для уведомления владельца приложения о находках, заслуживающих внимания. Меня всегда интересовали не только сами уязвимости, но и то, как они были найдены.
Я не мог ответить на вопросы:
• Какие уязвимости хакеры находят в приложениях?
• Откуда хакеры узнают об этих уязвимостях?
• С чего начинается проникновение на сайт?
• Как выглядит процесс взлома? Как он выполняется: автоматически или вручную?
• Каким образом я могу начать заниматься хакингом?
В конце концов я остановился на платформе для поиска уязвимостей за вознаграждение HackerOne — связующем звене между этичными хакерами и компаниями, заинтересованными в них. Возможности, заложенные в HackerOne, позволяют хакерам и компаниям раскрывать найденные и исправленные ошибки.
Но мне приходилось перечитывать раскрытые отчеты по два-три раза, чтобы в них разобраться. Так и возникла идея доступного описания реальных уязвимостей для новичков.
«Ловушка для багов» — это заслуживающий доверия справочник, который поможет понять разного рода веб-уязвимости, найти программные ошибки, сообщить о них, получить вознаграждение и написать защитный код. Но эта книга охватывает не только успешные примеры: в ней вы найдете ошибки и извлеченные уроки, многие из которых взяты из моего личного опыта.
Чтение этой книги — первый шаг к безопасному интернету и дополнительному доходу.
На кого рассчитана эта книга
Книга написана для начинающих хакеров. Ими могут быть веб-разработчики, веб-дизайнеры, родители в декрете, школьники, пенсионеры и др.
Конечно, опыт программирования и общее представление о веб-технологиях пригодятся, но не будут обязательным условием для хакинга.
Навыки программирования могут облегчить поиск уязвимостей, связанных с программной логикой. Если вы сможете поставить себя на место программиста или прочитать его код (если таковой доступен), ваши шансы на успех будут выше.
Издательство No Starch Press предлагает много книг по программированию. Также существуют бесплатные обучающие курсы на Udacity и Coursera. Дополнительные ресурсы перечислены в Приложении Б.
Как читать эту книгу
Каждая глава описывает определенный тип уязвимостей и имеет следующую структуру:
1. Описание типа уязвимости.
2. Примеры уязвимости этого типа.
3. Краткий обзор с выводами.
Каждый пример уязвимости содержит пояснения:
• Моя оценка сложности поиска и подтверждения уязвимости.
• URL-адрес места обнаружения уязвимости.
• Ссылка на исходный отчет о раскрытии или статью.
• Дата подачи отчета об уязвимости.
• Сумма, полученная за предоставление информации об уязвимости.
• Четкое описание уязвимости.
• Выводы.
Главы необязательно читать по порядку. Если вас интересуют отдельные темы, можете начать с них. В некоторых случаях я ссылаюсь на концепции, описанные в предыдущих главах, но при этом стараюсь указывать, где находится определение соответствующего понятия. Держите эту книгу открытой во время занятия хакингом.
О чем эта книга
Ниже дается краткое описание содержания каждой главы:
Глава 1. Основы охоты за уязвимостями. Вы узнаете, что такое уязвимости и награды за их обнаружение и в чем разница между клиентами и серверами. Также мы рассмотрим работу интернета: HTTP-запросы, ответы и методы и отсутствие состояния в протоколе HTTP.
Глава 2. Open Redirect. Мы опишем атаку, при которой доверенный домен перенаправляет пользователей на адрес злоумышленника.
Глава 3. Засорение HTTP-параметров. Мы рассмотрим внедрение в HTTP-запрос дополнительных параметров.
Глава 4. Межсайтовая подделка запросов. Вы узнаете, как с помощью вредоносного веб-сайта заставить браузер послать другому сайту HTTP-запрос, который будет принят.
Глава 5. Внедрение HTML и подмена содержимого. Мы объясним, как злоумышленники внедряют собственные HTML-элементы в веб-страницы атакуемого сайта.
Глава 6. Внедрение символов переноса строки. Вы научитесь внедрять закодированные символы в HTTP-сообщения, чтобы повлиять на их интерпретацию сервером, прокси и браузером.
Глава 7. Межсайтовый скриптинг. Мы объясним, как злоумышленники запускают собственный JavaScript-код на сайте, не фильтрующем пользовательский ввод.
Глава 8. Внедрение шаблонов. Вы научитесь использовать движки шаблонизации на сайте, который не фильтрует пользовательский ввод. Эта глава содержит клиентские и серверные примеры.
Глава 9. Внедрение SQL. Мы опишем, как злоумышленник запрашивает информацию у базы данных или атакует ее.
Глава 10. Подделка серверных запросов. Мы объясним, каким образом злоумышленник может заставить серверную платформу выполнять непреднамеренные сетевые запросы.
Глава 11. Внешние XML-сущности. Мы покажем, как пользоваться ошибками, которые допускает приложение в ходе анализа XML-ввода и обработки включения в этот ввод внешних сущностей.
Глава 12. Удаленное выполнение кода. Мы рассмотрим примеры эксплуатации злоумышленниками серверов и приложений для выполнения собственного кода.
Глава 13. Уязвимости памяти. Вы узнаете, как использовать механизм управления памятью приложения, чтобы спровоцировать непреднамеренное поведение, в том числе выполнение команд.
Глава 14. Захват поддомена. Мы покажем, как злоумышленник может управлять поддоменом от имени реального родительского домена.
Глава 15. Состояние гонки. Вы научитесь пользоваться ситуациями, в которых процессы сайта выполняют работу с учетом исходных условий, которые во время выполнения становятся недействительными.
Глава 16. Небезопасные прямые ссылки на объекты. Вы научитесь получать несанкционированный доступ к ссылке на объект, такой как файл, запись базы данных или учетная запись.
Глава 17. Уязвимости в OAuth. Мы опишем ошибки в реализации протокола, призванного упростить и стандартизировать безопасную авторизацию в веб, на мобильных устройствах и в настольных приложениях.
Глава 18. Уязвимости в логике и конфигурации приложений. Вы научитесь пользоваться ошибкой в программной логике или конфигурации приложения, чтобы заставить сайт выполнять действия.
Глава 19. Самостоятельный поиск уязвимостей. Мы опишем, где и как искать уязвимости, с учетом опыта и методологии. Эта глава не является пошаговой инструкцией для взлома сайтов.
Глава 20. Отчеты об уязвимостях. Мы расскажем, как писать информативные и заслуживающие доверия отчеты об уязвимостях, чтобы найденные вами ошибки не были проигнорированы.
Приложение А. Инструменты. Мы перечислим инструменты, предназначенные для хакинга, в том числе для проксирования веб-трафика, составления перечня поддоменов, создания снимков экрана и т.д.
Приложение Б. Дополнительный материал. Мы перечислим дополнительные ресурсы для расширения ваших хакерских познаний (онлайн-обучение, платформы для охоты за уязвимостями, блоги и т.д.)
Замечания о хакинге
Если почитать о публичном раскрытии уязвимостей и о том, сколько денег получают хакеры, может сложиться впечатление, что это простой и короткий путь к богатству. Но это не так. Хакинг может быть прибыльным, но мало кто пишет о неудачах в этом деле (я написал).
Возможно, успех придет к вам быстро. Но пока уязвимость не найдена, продолжайте копать. Разработчики безустанно пишут новый код, и ошибки неизбежно попадают в приложения. С каждой новой попыткой хакинг становится проще.
На этой ноте позвольте завершить введение. О своих успехах можете писать мне в Twitter: @yaworsk. Пишите, даже если что-то не получается, не держите в себе. А потом вместе отпразднуем победу, и, возможно, вашу находку я смогу добавить в следующее издание этой книги.
Удачи и веселого хакинга!
От издательства
Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.
1. Основы охоты за уязвимостями
Начнем с обсуждения, как работает интернет и что происходит, когда вы вводите URL в адресную строку браузера. Открытие веб-сайта выглядит просто, но оно включает в себя множество скрытых процессов, таких как подготовка HTTP-запроса, идентификация домена, к которому нужно обратиться, перевод доменного имени в IP-адрес, отправка запроса, вывод ответа и т.д.
В этой главе рассмотрены основные понятия и термины, такие как уязвимость, награда за нахождение ошибок, клиент, сервер, IP-адрес и HTTP. Вы узнаете, как выполнение несанкционированных действий и предоставление доступа к закрытой информации может привести к уязвимостям. Мы детально разберем ввод URL в адресную строку браузера, HTTP-запрос и ответ на него, а также методы, которые поддерживает HTTP. В конце главы мы поговорим о том, что подразумевает отсутствие состояния в протоколе HTTP.
Уязвимости и награды за их нахождение
Уязвимость (vulnerability) — это слабое место в приложении, с помощью которого злоумышленник может выполнять действия или получить несанкционированный доступ к информации.
Уязвимости могут возникать в результате выполнения как стандартных, так и непредвиденных действий, таких как изменение идентификатора записи для доступа к закрытой информации.
Представьте веб-сайт, который позволяет создать профиль с личными данными, доступными только вашим друзьям. Добавление вас в «друзья» без вашего разрешения будет уязвимостью. В ходе проверки сайта ставьте себя на место злоумышленника.
Bug Bounty — это система вознаграждения, которое владелец веб-сайта или другая компания выплачивает человеку, сообщившему о реальной уязвимости с соблюдением этики. Их материальное выражение находится в диапазоне от десяти до десятков тысяч долларов либо представляет собой криптовалюту, авиабилеты, бонусные очки, скидки и т.д.
Компания, предлагающая вознаграждение, обычно создает специальную программу — набор правил и ограничений для поиска уязвимостей на ее сайте. Она отличается от программы раскрытия уязвимостей (vulnerability disclosure program, или VDP) — механизма этичного сообщения об уязвимости, который не предусматривает оплаты. И хотя не все находки, описанные в этой книге, привели к награде, каждая из них — это пример участия хакера в программах Bug Bounty.
Клиент и сервер
Ваш браузер работает с интернетом — сетью компьютеров, которые обмениваются сообщениями — пакетами. Пакеты содержат данные и сведения о том, куда и откуда эти данные передаются. Каждый компьютер в сети имеет адрес. Но некоторые компьютеры имеют доступ только к пакетам определенного типа и / или адресам из ограниченного списка. Принимающая сторона сама решает, что делать с пакетами и как на них отвечать. В этой книге мы сосредоточимcя на данных, а именно на HTTP-сообщениях.
Инициатора запроса — компьютер с браузером, командной строкой или др. — называют клиентом. Веб-сайты и веб-приложения, которые получают запросы, называются серверами. Если какая-то концепция применима и к клиентам и к серверам, я буду использовать общий термин «компьютер».
Количество компьютеров, которые общаются между собой через интернет, не ограниченно, поэтому их взаимодействие требует стандартизации. Документы 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 и включает адреса из восьми групп по четыре шестнадцатеричных цифры, разделенных двоеточиями. 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 <IP-адрес> 80. В этой строке для создания сетевого соединения с возможностью чтения и записи сообщений используется утилита 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/octet-stream и text/plain. Наконец, в заголовке User-Agent указано программное обеспечение, ответственное за отправку запроса.
Шаг 5. Ответ сервера
В ответ на запрос сервер должен вернуть нечто, похожее на листинг 1.2:
Листинг 1.2. Ответ сервера
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<head>
<title>Google.com</title>
</head>
<body>
--пропуск--
</body>
</html>
Мы получили 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.
Получив ответ 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).
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, которая определяет ресурс и его местоположение в сети. Например, и /<example>/file.txt — корректные URI-адреса, но только первый из них соответствует спецификации URL, так как идентифицирует способ обращения к ресурсу по его домену http://www.google.com. Несмотря на этот нюанс, дальше в книге мы будем называть любые идентификаторы ресурсов URL-адресами.
GET-запросы не должны изменять данные. Их задача — извлекать информацию из сервера и возвращать ее в теле HTTP-сообщения. Но этому поведению угрожает межсайтовая подделка запросов (глава 4), и само посещение URL-адреса или ссылки на веб-сайте заставляет браузер отправлять соответствующему серверу 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-запросы не имеют состояния. Это означает, что сервер не знает о прошлом взаимодействии с вашим браузером. В большинстве случаев сайтам нужно помнить, кто вы, чтобы не заставлять вас заново вводить свои имя пользователя, пароль и другие данные при отправлении каждого 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
Уязвимость Open Redirect возникает, когда разработчик по ошибке позволяет через ввод перенаправить браузер к другому сайту. Обычно для этого применяются параметры URL-адреса, HTML-теги <meta> для обновления страницы или свойство 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.<attacker>.com/. Заманив вас на вредоносный сайт, злоумышленник может выполнить другие атаки.
При поиске таких уязвимостей обращайте внимание на параметры URL-адреса с определенными именами, такими как url=, redirect=, next= и т.д. Они могут обозначать адрес, по которому будет перенаправлен пользователь. Также помните, что параметры перенаправления могут называться по-разному на разных сайтах или даже в пределах одного сайта. Иногда они обозначаются одним символом — например, r= или u=.
Атаки с перенаправлением могут основываться не только на параметрах, но и на HTML-тегах <meta> или JavaScript. HTML-тег <meta> может заставить браузер обновить страницу и выполнить GET-запрос по URL-адресу, указанному в атрибуте content этого тега. Вот как это может выглядеть:
<meta http-equiv="refresh" content="0; url=https://www.google.com/">
Атрибут content состоит из двух частей. Одна из них заставляет браузер подождать какое-то время, прежде чем переходить по заданному URL-адресу; в данном случае указано 0 секунд. Другая содержит URL-адрес, по которому нужно перейти; в нашем примере это https://www.google.com. Злоумышленники могут этим воспользоваться, имея возможность изменить атрибут content тега <meta> или внедрить собственный тег с помощью какой-то другой уязвимости.
Для перенаправления пользователей также применяется 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
Сложность: низкая
URL:
Источник: 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://<attacker>.com/admin/.
Выводы
Не все уязвимости сложны: для перенаправления пользователя к внешнему сайту может быть достаточно изменения значения параметра.
Open Redirect на странице входа в Shopify
Сложность: низкая
URL:http://mystore.myshopify.com/account/login/
Источник:www.hackerone.com/reports/103772/
Дата подачи отчета: 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.<attacker>.com/ не принадлежит домену Shopify.
Поскольку URL-адрес заканчивается на .<attacker>.com, а DNS-запросы начинают интерпретацию доменов справа налево, перенаправление привело бы к домену <attacker>.com. Так злоумышленник мог организовать перенаправление к другому домену, добавляя специальные символы к доступным значениям.
Выводы
Если вы можете контролировать только часть итогового URL-адреса, добавление специальных символов может изменить его интерпретацию и перенаправить пользователя к другому домену. Подставьте специальные символы вроде точки или @, чтобы проверить нюансы перенаправления.
Перенаправление на межсайтовой странице HackerOne
Сложность: низкая
URL: отсутствует
Источник:www.hackerone.com/reports/111968/
Дата подачи отчета: 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:
<script>document.location.href = "http://evil.com";</script>
Тег <script> обозначает код, встроенный в HTML, document представляет содержимое веб-страницы, а свойства документа разделены точками. Свойство location позволяет управлять страницей, которую отображает ваш браузер, а его дочернее свойство href — перенаправлять браузер к заданному веб-сайту. По ссылке жертва переходила на поддомен Zendesk, принадлежащий Джамалу, а браузер жертвы выполнял скрипт Джамала и перенаправлял ее к http://evil.com:
Поскольку ссылка содержала домен hackerone.com, межсайтовая страница не выводилась, и пользователь не знал, что он попадает на небезопасный веб-сайт. Интересно, что в Zendesk проигнорировали отчет Джамала, но он продолжил исследовать проблему и организовал атаку перенаправления с помощью JavaScript, что убедило компанию HackerOne выплатить ему вознаграждение.
Выводы
В процессе поиска уязвимостей обращайте внимание, могут ли сервисы, которые использует веб-сайт, допускать атаки.
Учитесь доказывать серьезность последствий найденной уязвимости, умейте общаться как хакер (глава 19).
Если представители компании с вами не согласны, следуйте примеру Джамала и демонстрируйте найденные пробелы в сочетании с другими уязвимостями.
Итоги
Уязвимости Open Redirect позволяют злоумышленнику перенаправлять пользователей к вредоносным веб-сайтам без их ведома. Параметры перенаправления со значениями вроде redirect_to=, domain_name= или checkout_url= легко заметить. Труднее найти значения r=, u= и т.д.
Эта уязвимость основана на злоупотреблении доверием. Жертва может воспринять веб-сайт злоумышленника как знакомую страницу. Если вы заметите потенциально уязвимые параметры, проверьте их, добавляя специальные символы, такие как точка, и попробуйте изменить часть URL-адреса.
Межсайтовое перенаправление в HackerOne демонстрирует, что при охоте на уязвимости важно идентифицировать инструменты и сервисы, которые использует веб-сайт. Помните, что иногда следует проявить исследовательскую настойчивость, чтобы убедить компанию выплатить вознаграждение.
1 Теперь HackerOne перенаправляет https://support.hackerone.com к docs.hackerone.com, если вы не подаете заявку в службу поддержки через адрес /hc/en-us/requests/new.
Теперь HackerOne перенаправляет https://support.hackerone.com к docs.hackerone.com, если вы не подаете заявку в службу поддержки через адрес /hc/en-us/requests/new.
Межсайтовые страницы дополнили работу HackerOne с компанией Zendesk. Раньше, когда вы добавляли /zendesk_session к hackerone.com, ваш браузер перенаправлялся из платформы HackerOne непосредственно на надежную платформу Zendesk1. Но в Zendesk любой пользователь мог создать учетную запись, указать ее адрес в параметре /redirect_to_account?state= и тем самым перенаправить браузер к внешнему веб-сайту. Чтобы решить эту проблему, в HackerOne стали считать ссылки, содержащие zendesk_session, внешними и сопровождать переход по ним межсайтовой страницей с предупреждением о смене домена.
