Что такое уязвимость в игре

В клиенте Steam устранили опасную уязвимость, которая пряталась там десять лет

Что такое уязвимость в игре. . Что такое уязвимость в игре фото. Что такое уязвимость в игре-. картинка Что такое уязвимость в игре. картинка . Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

Внимательно следящие за безопасностью PC-игроки заметили, что недавно Valve выпустила новое обновление клиента Steam.

В этом посте я хочу оправдаться за то, что мы играем в игры на работе рассказать историю связанного с этим бага, существовавшего в клиенте Steam не меньше десяти лет, который до июля прошлого года мог приводить к удалённому выполнению кода (remote code execution, RCE) во всех 15 миллионах активных клиентов.

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

Мы заявили Valve об уязвимости 20 февраля 2018 года, и, к чести компании, она устранила её в бета-ветке меньше 12 часов спустя. Исправление было перенесено в стабильную ветку 22 марта 2018 года.

Что такое уязвимость в игре. SteamBug00 476 534 75. Что такое уязвимость в игре фото. Что такое уязвимость в игре-SteamBug00 476 534 75. картинка Что такое уязвимость в игре. картинка SteamBug00 476 534 75. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

Краткий обзор

Основа уязвимости заключалась в повреждении кучи внутри библиотеки клиента Steam, которое можно было вызвать удалённо, в той части кода, которая занималась восстановлением фрагментированной датаграммы из нескольких полученных UDP-пакетов.

Клиент Steam выполняет обмен данными через собственный протокол (Steam protocol), который реализован поверх UDP. В этом протоколе есть две области, особенно интересные в связи с уязвимостью:

Без дополнительных багов утечек данных повреждение кучи на современных операционных системах контролировать очень сложно, поэтому удалённое выполнение кода реализовать трудно. Однако в этом случае благодаря собственному распределителю памяти Steam и отсутствовавшей в двоичном файле steamclient.dll (до прошлого июля) ASLR, этот баг можно было использовать как основу для очень надёжного эксплойта.

Ниже представлено техническое описание уязвимости и связанного с ней эксплойта до момента
реализации выполнения кода.

Подробности уязвимости

Необходимая для понимания информация

Протокол

Сторонние лица (например https://imfreedom.org/wiki/Steam_Friends) на основе анализа генерируемого клиентом Steam трафика выполнили реверс-инжиниринг и создали подробную документацию протокола Steam. Изначально протокол был задокументирован в 2008 году и с тех пор сильно не менялся.

Протокол реализован как протокол передачи с установлением соединения поверх потока датаграмм UDP. Пакеты, в соответствии с документацией по ссылке выше, имеют следующую структуру:

Что такое уязвимость в игре. SteamBug000 743 113 75. Что такое уязвимость в игре фото. Что такое уязвимость в игре-SteamBug000 743 113 75. картинка Что такое уязвимость в игре. картинка SteamBug000 743 113 75. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

Шифрование

Полезная информация пакета датаграммы зашифрована AES-256 с помощью ключа, согласуемого между клиентом и сервером в каждой сессии. Согласование ключей выполняется следующим образом:

Уязвимость

Уязвимость присутствует внутри метода RecvFragment класса CUDPConnection. В релизной версии библиотеки steamclient символы отсутствуют, однако при поиске по строкам бинарника в интересующей нас функции обнаруживается ссылка на «CUDPConnection::RecvFragment«. Вход в эту функцию выполняется, когда клиент получает UDP-пакет, содержащий датаграмму Steam типа 0x6 («фрагмент датаграммы»).

1. Функция начинается с проверки состояния подключения, чтобы убедиться, что находится в состоянии «Connected«.
2. Затем проверяется поле data_len в датаграмме Steam, чтобы убедиться, что оно содержит меньше 0x20000060 байт (похоже, это значение выбрано произвольно).
3. Если проверка пройдена, то функция проверяет, собирает ли соединение фрагменты какой-то датаграммы, или это первый пакет потока.

Что такое уязвимость в игре. SteamBug Fig1 1491 977 75. Что такое уязвимость в игре фото. Что такое уязвимость в игре-SteamBug Fig1 1491 977 75. картинка Что такое уязвимость в игре. картинка SteamBug Fig1 1491 977 75. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

4. Если это первый пакет в потоке, то затем проверяется поле split_count, чтобы узнать, на сколько пакетов растянется этот поток
5. Если поток разделён на несколько пакетов, то проверяется поле seq_no_of_first_pkt, чтобы убедиться, что оно совпадает с порядковым номером текущего пакета. Это гарантирует, что пакет является первым в потоке.
6. Поле data_len снова проверяется относительно ограничения в 0x20000060 байт. Кроме того, проверяется, что split_count меньше 0x709b пакетов.

Что такое уязвимость в игре. SteamBug Fig2 1003 963 75. Что такое уязвимость в игре фото. Что такое уязвимость в игре-SteamBug Fig2 1003 963 75. картинка Что такое уязвимость в игре. картинка SteamBug Fig2 1003 963 75. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

7. Если эти условия соблюдаются, то задаётся булево значение, обозначающее, что теперь мы собираем фрагменты. Также выполняется проверка того, что у нас ещё нет буфера, выделенного для хранения фрагментов.

Что такое уязвимость в игре. SteamBug Fig3 722 725 75. Что такое уязвимость в игре фото. Что такое уязвимость в игре-SteamBug Fig3 722 725 75. картинка Что такое уязвимость в игре. картинка SteamBug Fig3 722 725 75. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

8. Если указатель на буфер сбора фрагментов не равен нулю, то текущий буфер сбора фрагментов освобождается и выделяется новый буфер (см. жёлтый прямоугольник на рисунке ниже). Именно здесь проявляется ошибка. Ожидается, что буфер сбора фрагментов выделяется в размере data_len байтов. Если всё выполнено успешно (а код не выполняет проверку — незначительная ошибка), то затем полезная информация датаграммы копируется в этот буфер с помощью memmove, доверяя тому, что в packet_len указано количество байтов для копирования.

Важнейшим недосмотром разработчика стало то, что не выполняется проверка «packet_len меньше или равен data_len«. Это значит, что существует возможность передать data_len меньше чем packet_len и иметь до 64 КБ данных (из-за того, что поле packet_len имеет ширину 2 байта), скопированных в очень маленький буфер, что приводит к возможности эксплойта повреждения кучи.

Что такое уязвимость в игре. SteamBug Fig4 661 816 75. Что такое уязвимость в игре фото. Что такое уязвимость в игре-SteamBug Fig4 661 816 75. картинка Что такое уязвимость в игре. картинка SteamBug Fig4 661 816 75. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

Эксплуатация уязвимости

В этом разделе подразумевается, что присутствует способ обхода ASLR. Это приводит к тому, что перед началом эксплуатации известен начальный адрес steamclient.dll.

Спуфинг пакетов

Управление памятью

Для выделения памяти больше 1024 (0x400) байт используется стандартный системный распределитель. Для выделения памяти меньше или равной 1024 байтам Steam использует собственный распределитель, работающий одинаково на всех поддерживаемых платформах. В этой статье не будет подробного обсуждения этого распределителя, за исключением следующих ключевых аспектов:

Выделение памяти

При выделении памяти первый свободный блок отсоединяется от вершины списка свободной памяти, а первые 4 байта этого блока, соответствующие next_free_block, копируются в переменную-член freelist_head внутри класса распределителя.

Освобождение памяти

При освобождении блока поле freelist_head копируется в первые 4 байта освобождаемого блока (next_free_block), а адрес освобождаемого блока копируется в переменную-член freelist_head класса распределителя.

Как получить примитив записи

В куче возникает переполнение буфера, и в зависимости от размера вызвавших повреждение пакетов выделение памяти может управляться или стандартным распределителем Windows (при выделении памяти больше 0x400 байт) или собственным распределителем Steam (при выделении памяти меньше 0x400 байт). Из-за нехватки мер обеспечения безопасности в собственном распределителе Steam, я решил, что для эксплойта проще использовать его.

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

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

Что использовать: датаграммы или фрагменты

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

Но очевидно, что это не такой случай, потому что наш первый пакет уже нарушил это правило (существование ошибки возможно пропуску этой проверки) и возникнет ошибка. Чтобы избежать этого, нужно после повреждения памяти избежать метода CUDPConnection::RecvFragment().

К счастью, CUDPConnection::RecvDatagram() по-прежнему может получать и обрабатывать отправляемые пакеты типа 7 (датаграммы), пока RecvFragment() не действует, и это можно использовать для запуска примитива записи.

Проблемы с шифрованием

Ожидается, что пакеты, получаемые RecvDatagram() и RecvFragment(), будут зашифрованы. В случае RecvDatagram() расшифровка выполняется почти сразу после получения. В случае RecvFragment() она происходит после получения последнего фрагмента в сессии.

Возникает проблема эксплуатации уязвимости, потому что мы не знаем ключа шифрования, который создаётся в каждой сессии. Это значит, что любой OP-код/шелл-код, который мы отправим, будет «расшифрован» с помощью AES256, что превратит наши данные в мусор. Поэтому необходимо найти способ эксплуатации, возможный почти сразу после получения пакета, прежде чем процедуры расшифровки получат возможность обработать полезную информацию, содержащуюся в буфере пакетов.

Как добиться выполнения кода

Учитывая описанное выше ограничение расшифровки, эксплуатация должна выполняться до расшифровки входящих данных. Это накладывает дополнительные ограничения, но задача всё равно выполнима: можно перезаписать указатель так, чтобы он указывал на объект CWorkThreadPool, хранящийся в предсказуемом месте внутри раздела данных двоичного файла. Хотя подробности и внутренний функционал этого класса неизвестны, по его имени можно предположить, что он поддерживает пул потоков, которые можно использовать, когда необходимо выполнить «работу». Изучив несколько отладочных строк в двоичном файле, можно понять, что среди таких работ есть шифрование и расшифровка (CWorkItemNetFilterEncrypt, CWorkItemNetFilterDecrypt), поэтому когда эти задачи ставятся в очередь, применяется класс CWorkThreadPool. Перезаписав этот указатель и записав в него нужное нам место, мы сможем имитировать указатель vtable и связанную с ним vtable, что позволяет нам выполнить код, например, при вызове CWorkThreadPool::AddWorkItem(), который обязательно происходит до любых процессов расшифровки.

На рисунке ниже показана успешная эксплуатация уязвимости до этапа получения управления над регистром EIP.

Что такое уязвимость в игре. SteamBug Fig5 1187 1011 75. Что такое уязвимость в игре фото. Что такое уязвимость в игре-SteamBug Fig5 1187 1011 75. картинка Что такое уязвимость в игре. картинка SteamBug Fig5 1187 1011 75. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

С этого момента можно создать цепочку ROP, приводящую к выполнению произвольного кода. В видео ниже показано, как злоумышленник удалённо запускает калькулятор Windows в полностью пропатченной версии Windows 10.

Подводим итоги

Если вы добрались до этой части статьи, до благодарю вас за упорство! Надеюсь, вам стало понятно, что это очень простой баг, который было довольно легко эксплуатировать из-за нехватки современных средств защиты от эксплойтов. Вероятно, уязвимый код был очень старым, но во всём остальном он хорошо работал, поэтому разработчики не видели необходимости исследовать его или обновлять скрипты его сборки. Урок здесь заключается в том, что разработчикам важно периодически проводить ревью старого кода и систем сборки, чтобы убедиться в их соответствии современным стандартам безопасности, даже если сам функционал кода остаётся неизменным. Было удивительно найти в 2018 году такой простой баг, обладающий столь серьёзными последствиями на очень популярной программной платформе. Это должно стать стимулом к поиску таких уязвимостей для всех исследователей!

Источник

Frontend Security: о чем вы хотели бы забыть, но не сможете

Какие атаки на клиентскую часть веб-ресурсов вы знаете? XSS, CSRF, HTTP Response Splitting, Clickjacking, CSHM, атаки на CORS, следствия других ошибок программистов? В среднем разработчик вспоминает не половину, и даже не треть. Разнообразие атак зависит только от фантазии и любопытства злоумышленников, и все они созданы, чтобы навредить вашим клиентам, а значит — и вам.

Татьяна Новикова — ex-пентестер с опытом в безопасности около четырех лет, а ныне Application Security Engineer. В команде ЦАРКА (Центр анализа и расследования кибератак) она занималась пентестом — полной проверкой веб-ресурсов на безопасность. В том числе команда работала с white-box, то есть с исходными кодами, и разбирала безопасность не только бэкенда, но и фронтенда. Сейчас Татьяна перешла в Beeline Казахстан и занимается обеспечением процессов безопасной разработки.

На основе своего опыта она выступила на конференции Frontend Conf Live 2020. В одной статье, конечно, невозможно покрыть все уязвимости и потенциальные опасности, поэтому сегодня будет самое актуальное и страшное из доклада — то, что может нанести максимальный ущерб.

Что такое уязвимость в игре. 1e14f656e04c6bf04355a93eccea1901. Что такое уязвимость в игре фото. Что такое уязвимость в игре-1e14f656e04c6bf04355a93eccea1901. картинка Что такое уязвимость в игре. картинка 1e14f656e04c6bf04355a93eccea1901. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

Когда мы задумываемся о наличии уязвимостей в своих продуктах, важно помнить один момент: они могут быть даже в тех кусочках кода, которые не вызывают у вас подозрений. На протяжении трех последних лет статистика PTSecurity утверждает, что 9 из 10 веб-приложений в нашем интернете уязвимы к атакам client-side. Но это не значит, что одно приложение из десяти не уязвимо: скорее всего, уязвимость в нем просто еще не выявили. Мы поговорим сегодня о некоторых видах атак, с которыми может столкнуться каждый разработчик.

XSS (Cross-Site Scripting)

Начать, наверное, стоит с HTML инъекций. На первый взгляд они кажутся безобидными, но по факту могут привести к очень неприятным последствиям, особенно для рядовых пользователей, которые зашли на ваш веб-ресурс. Чаще всего обычный пользователь ресурса не имеет навыков в разработке и плохо представляет, как всё работает, и поэтому не может опознать HTML-инъекцию или атаку, которая идет на него. Форма ввода пароля, которая отрисована на странице, обычно вызывает у него доверие, а в адресную строку, где могла притаиться вредоносная нагрузка, он чаще всего не смотрит. А это прекрасная почва для социальных инженеров.

Инъекции в JavaScript распространены и интересны злоумышленникам еще больше.

Что такое уязвимость в игре. 348d552142d0b52b48d7f45ff6b0c437. Что такое уязвимость в игре фото. Что такое уязвимость в игре-348d552142d0b52b48d7f45ff6b0c437. картинка Что такое уязвимость в игре. картинка 348d552142d0b52b48d7f45ff6b0c437. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.Места для инъекций (даже в CSS их делают, но это экзотика)

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

К сожалению, очень часто такие уязвимости эксплуатируются так называемыми script kiddie. Это люди, которые начинают изучать безопасность или хотят дешево и не прилагая особых усилий кого-то взломать — им прикольно или даже выгодно посмотреть, как работает уязвимость, для которой уже кем-то создан эксплойт (эксплойтом называют скрипт, который позволяет эксплуатировать уязвимости). Но довольно часто их действия не настолько обдуманы, как у настоящих хакеров, и навредить они могут просто потому, что не до конца продумали свою атаку.

Проект OWASP (Open Web Application Security Project) агрегирует огромное количество информации о том, как бороться с самыми разными уязвимостями, и какие куски кода могут привести к тому, что у вас появятся те или иные уязвимости. Его подпроект OWASP Top Ten — статистический топ уязвимостей, которые в веб-ресурсах появляются. XSS атаки уже много лет входят в топ-10.

Что такое уязвимость в игре. 65b9233e8ff8e8b9d46c932300e91f93. Что такое уязвимость в игре фото. Что такое уязвимость в игре-65b9233e8ff8e8b9d46c932300e91f93. картинка Что такое уязвимость в игре. картинка 65b9233e8ff8e8b9d46c932300e91f93. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

В 2013 году они были на 3 месте, а в 2017 спустились на 7 позицию. Однако не стоит думать, что XSS атаки сдали свои позиции, нет. Скорее просто другие уязвимости набрали больше оборотов. К тому же это деление достаточно условное.

Виды XSS

Сегодня известно 3 вида XSS: Reflected (отраженные атаки), Stored (хранимые атаки) и атаки на DOM. Список на самом деле условный, и он может измениться. Например, атаки на DOM активно стали эксплуатироваться только в последнюю пятилетку, так что через пару лет могут появиться и другие атаки.

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

Reflected XSS

В разной литературе отраженные атаки называют по-разному (например, моментальными XSS), но суть одна и та же: страница, к которой вы обращаетесь, возвращает пользователю фрагменты запроса.

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

Stored XSS

Раз это хранимые XSS — значит, они где-то хранятся, и чаще всего это база данных бэкенда. Это могут быть сообщения на форуме, комментарии к записям, и по большому счету всё, что угодно — любое сохраняемое сообщение от пользователя. И здесь важно помнить: если при сохранении в БД программисты-бэкендеры обычно (будем оптимистами) думают о защите от SQL-инъекций, то о защите от XSS при записи в базу они задумываются гораздо реже, что, наверное, вполне логично.

Хранимые XSS для злоумышленника — это клондайк. Достаточно оставить, к примеру, комментарий с XSS, и код из него выполнится у любого человека, попавшего на эту страницу, в контексте его браузера.

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

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

Этот пример весьма забавный: мы подсовываем в запросе битую ссылку на картинку и говорим: если произойдет ошибка, выполни алерт. Поскольку ссылка битая, ошибка, конечно, произойдет, и алерт выполнится. И это всё, что нужно злоумышленнику — его js-код уже отработал. А что он внутри себя сделает — отправит куда-то куки или что-то еще — это другой вопрос.

DOM-based XSS

Это атаки, которые пытаются манипулировать Document Object Model из JavaScript. Если хранимые и отраженные XSS попадают на сервер, то его защита (например, Web Application Firewall) может их распознать. Но здесь ситуация страшнее, потому что DOM-based XSS до сервера вообще не дойдет. Все изменения будут происходить исключительно на стороне клиента, в браузере. Поймать его на сервере крайне тяжело.

Пример кода, который может привести к DOM-based XSS:

Если злоумышленник будет знать, что у вас есть такой кусочек кода, то ему достаточно после символа # указать alert(document.cookie). После чего отработает eval, и тот код, который был указан после #, будет выполнен.

В XSS-игре это третий уровень. Изменяя DOM, мы можем менять картинку, которую нам демонстрируют. Точно также можно вызвать выполнение какого-либо JavaScript-кода либо по ошибке, либо по наведению клика мыши — не принципиально, главное, чтобы ваш код выполнился.

Другие атаки по поведению очень схожи с XSS. Какие-то эксплуатируют XSS, но не крадут куки пользователя, а делают что-то другое. Посмотрим несколько самых распространенных вариантов, что может сделать злоумышленник, если найдет у вас уязвимость.

Что хакер может сделать?

Украсть куки и токены

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

Примерно такой запрос он захочет выполнить в контексте вашего домена:

Чтобы собрать куки и токены ваших пользователей, ему нужно где-то на своем домене либо на чужом взломанном домене разместить специальный скрипт — сниффер. Скрипт будет слушать все запросы от вашего сервера и отлавливать те, у которых в качестве параметра “c” что-то есть. Здесь приведен простой пример, но все снифферы ведут себя примерно одинаково. Они собирают куки со всех пользователей, в браузере которых по каким-либо причинам может отработать XSS.

Но это, на самом деле, далеко не все. Что еще может сделать злоумышленник, найдя уязвимость во фронтовой части ресурса?

Выполнить действия от имени пользователя

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

В этом случае злоумышленник может воспользоваться CSRF (Cross-Site Request Forgery). Несмотря на то, что и XSS, и CSRF начинаются со слов Cross-Site, по поведению эта атака имеет совсем другую логику. Но на HackerOne примеры использования CSRF встречаются в среднем раз в неделю.

Как происходит обычное нормальное стандартное взаимодействие между браузером и каким-либо сервером?

Браузер шлет GET-запрос — дай мне страничку.

Сервер отвечает страничкой, в которой есть форма авторизации.

Пользователь заполняет форму в браузере и отправляет POST-запрос. Хотя в интернете до сих пор, к сожалению, можно найти сайты, которые шлют авторизационные данные GET-запросом.

После того как POST-запрос ушел, на сервере проверяются данные пользователя, то есть валидность логина-пароля.

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

Давайте допустим, что на нашем ресурсе есть уязвимость, приводящая к CSRF. А что произойдет, если наш пользователь зайдет на какой-то сервер, подвластный злоумышленнику? Который злодей либо взломал, либо это изначально вообще его веб-сервер, который он полностью контролирует.

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

Что такое уязвимость в игре. f19421f672a4217b782e1e06bc1c0f39. Что такое уязвимость в игре фото. Что такое уязвимость в игре-f19421f672a4217b782e1e06bc1c0f39. картинка Что такое уязвимость в игре. картинка f19421f672a4217b782e1e06bc1c0f39. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.CSRF — Cross-site Request Forgery

Это пример с GET-запросом, но важно понимать, что с POST-запросом это отработает так же успешно, просто атака будет немного сложнее. Потому что надо будет отправлять параметры и каким-то образом смоделировать клик на стороне уязвимого сайта. Однако, это тоже можно сделать JavaScript’ом.

CSRF-атаку очень часто используют в совершенно неочевидных местах. В качестве примера можно привести реальный кейс из практики: на одном ресурсе для смены пароля не надо было вводить старый пароль, а достаточно было два раза ввести новый и нажать кнопку SUBMIT (тоже небезопасно, однако уязвимости действительно чаще всего эксплуатируются в связках).

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

Один из классических примеров, как еще можно эксплуатировать CSRF:

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

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

Еще один распространенный вариант — это смена e-mail адреса. Его можно поменять от имени пользователя, и он об этом не узнает. Но вот доступ к своему личному кабинету потеряет, как только прервет сессию. Никому в голову не придет каждую сессию перепроверять в личном кабинете, всё ли в порядке с его e-mail адресом.

Но это тоже еще не всё, что хакер может сделать.

Подделать поля, наложить фреймы

Эта атака связана с внедрением JavaScript-кода — так называемый clickjacking или кража кликов, когда злоумышленник подделывает какие-то поля или накладывает абсолютно прозрачные фреймы поверх фреймов на вашей странице. При клике на них выполняется не то действие, которое указано на вашей странице, а другое.

Что такое уязвимость в игре. c5a367fecd590153f223077cd0136711. Что такое уязвимость в игре фото. Что такое уязвимость в игре-c5a367fecd590153f223077cd0136711. картинка Что такое уязвимость в игре. картинка c5a367fecd590153f223077cd0136711. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.Подделка полей, наложение фреймов — clickjacking

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

При этом Clickjacking довольно сложно поймать.

Хакер может даже получить исполнение кода

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

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

Суть атаки в добавлении желтого поля “Additional plugins are required to display all the media on this page”. Оно очень похоже на то, что выдает браузер, когда ему действительно не хватает каких-то плагинов. Проблема в том, что выдается это на территории веб-страницы, то есть окно накладывается поверх нее.

Что такое уязвимость в игре. b8964711c96be5e5692c86b7d9422ce1. Что такое уязвимость в игре фото. Что такое уязвимость в игре-b8964711c96be5e5692c86b7d9422ce1. картинка Что такое уязвимость в игре. картинка b8964711c96be5e5692c86b7d9422ce1. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

Был случай, когда злоумышленники, внедрив JavaScript-код, отрисовали аналогичное поле, и при клике на Install Missing Plugins с их сервера скачивался исполняемый файл. После его установки злоумышленник мог делать на компьютере жертвы всё что угодно.

Использовать фреймворки, причем для обеих сторон

У злоумышленников сейчас есть много инструментов для автоматизации самых разных процессов, в том числе и фреймворки, которые анализируют сайты и подсказывает, куда, как и где можно встроить код. Фреймворки могут полностью скопировать визуальное оформление страниц или проверить, к чему и какие действия на вашем сайте могут привести. Например, есть фреймворк Browser Exploitation Framework (BeEF), который регулярно обновляется.

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

Потому что практически в каждом фреймворке, вне зависимости от того, client-side это или server-side, есть какая-нибудь небезопасная конструкция. И на сайте каждого разработчика фреймворка напротив этой конструкции будет стоять либо жирный восклицательный знак, либо целая плашка с текстом: «Внимание, если вы будете это использовать, то ответственность за безопасность ваших клиентов лежит только на вас!»:

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

Был случай, когда уязвимость в Vue-коде получилось найти только после чтения исходников. Выяснилось, что программисты использовали v-HTML и передавали туда данные с сервера, абсолютно никак их не обрабатывая.

Вот так это можно сделать на Vue:

Возьмем простую страничку, где есть поле «Добро пожаловать» и какая-то ссылка в HTML. В данном случае код записан прямо здесь, но в реальности он будет получен с сервера, onmouseover=alert(. ). Если сервер никаким образом этот текст не обработал, то, понятно, что вы его тоже получите в том же виде, и эта уязвимость обязательно отработает.

Для остальных фреймворков много примеров можно найти в интернете, или почитать документацию и понять, как это делается. А мы, тем временем, подходим к главному вопросу.

Как защищаться?

Санитизировать приходящие от пользователей и от бэкенда данные (все, вообще, совсем)

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

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

Следить за подключаемыми библиотеками/уязвимостями в используемых фреймворках

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

Что такое уязвимость в игре. e9777715ddaa93b0f54cf920791b4cb8. Что такое уязвимость в игре фото. Что такое уязвимость в игре-e9777715ddaa93b0f54cf920791b4cb8. картинка Что такое уязвимость в игре. картинка e9777715ddaa93b0f54cf920791b4cb8. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

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

Ресурс snyk.io предлагает довольно неплохую базу уязвимостей с достаточно быстрой актуализацией — как только уязвимость заявили и выпустили патч, в этой базе появляется запись об этом. У них также есть неплохие блоги про всё, что связано с безопасностью фронтенда и не только.

А если мне кажется, что я защищен?

На все описанное выше кто-то может сказать, что он достаточно защищен, т.к., например? у него есть Web Application Firewall. Но, во-первых, мы уже видели пример уязвимости, с которой не сможет справиться WAF — это уже рассмотренный DOM-based XSS. А во-вторых — что такое Web Application Firewall? Это механизм, действующий на основе набора сигнатур (с использованием, возможно, какого-то машинного обучения), который получает запрос, смотрит на него и выявляет, по каким критериям этот запрос может быть подозрительным.

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

Так они могут, как кошка с мышкой, бегать друг за другом постоянно. Эта война, скорее всего, никогда не прекратится, ведь вероятность того, что создадут WAF, который умеет блокировать абсолютно все вредоносные запросы, стремится к нулю, потому что человеческая фантазия безгранична.

Кроме того, с каждой новой появляющейся технологией появляются новые уязвимости.

Что такое уязвимость в игре. 2824d9acc660b3be62dd5922e4f3d6a0. Что такое уязвимость в игре фото. Что такое уязвимость в игре-2824d9acc660b3be62dd5922e4f3d6a0. картинка Что такое уязвимость в игре. картинка 2824d9acc660b3be62dd5922e4f3d6a0. Ведущий исследователь Том Корт из компании Context, предоставляющей услуги информационной безопасности, рассказывает о том, как ему удалось обнаружить потенциально опасный баг в коде клиента Steam.

Это так называемый Polyglot XSS — специальная нагрузка, которую злоумышленники используют для проверки того, используется ли на сайте WAF. Для этого какой-либо фрагмент этой нагрузки вставляется в запрос и проверяется, среагирует сайт или нет. Ещё два года назад ни один WAF эту нагрузку не блокировал. Сейчас какие-то уже умеют это делать, но всё еще не все. Да и таких “полиглотов” в интернете очень много.

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

Остается центральный вопрос — а что же делать со всем этим?

Правильно устанавливать заголовки безопасности

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

CSP (Content-Security-Policy)

Content-Security-Policy, пожалуй, самый важный из них. Он устанавливается в качестве HTTP header и говорит о том, откуда можно брать контент для выполнения на вашей странице. К примеру, если вы тянете JavaScript-файлы со своего собственного домена, то все ОК. Туда также можно прописать CDN, с которого вы подтягиваете какие-то скрипты или другие вещи.

Content-Security-Policy: default-src ‘self’ *.trusted.com

Из крутого — туда можно прописать report-uri. Report-uri хорош тем, что если вы его укажете в своей policy, то все попытки обойти CSP будут вам репортиться именно на этот адрес:

Content-Security-Policy: default-src ‘self’; report-uri

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

HSTS (Strict Transport Security)

Этот заголовок безопасности говорит, что если доступен сертификат безопасности, и если на этот сайт пришли по HTTPS, то все подзапросы, которые с него будут уходить, должны идти тоже по шифрованному соединению, да и в целом на сайт можно попасть только по https.

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

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

SOP (Same origin policy)

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

В SOP всегда имеет смысл прописать полный список доменов вместе со схемами и портами, которым вы полностью доверяете.

Заключение

В заключение несколько пунктов:

Следите за новостями безопасности, даже если вам кажется, что вас это не касается. Каждый день обнаруживаются новые уязвимости и всегда может всплыть что-то, что связано с используемыми вами технологиями. Буквально за полгода может измениться абсолютно все. Может найтись какая-то новая уязвимость, которую никто раньше никогда не эксплуатировал. Например, тот же CSRF можно было реализовать еще с 1992 года, но только недавно его начали активно использовать.

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

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

Берегите своих пользователей. Постарайтесь не подставлять их лишний раз и не подвергать опасности.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *