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


Дисклеймер:
Статья состоит из двух частей. Первая часть — организационная, которая определяет проблему, рассказывает в целом о подходах к тестам на проникновение и о наших путях решения поставленных задач (наверняка содержит информацию, которая многим известна). Вторая — более техническая, с описанием используемых тулзов и найденных уязвимостей.
Если ты, %username%, любишь технические детали, можешь переходить ко второй части.
И, конечно же, не забудь свой чай с печеньками.


Собираем и распределяем


Некоторое представление подходов к пентестам


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


Разовый тест на проникновение


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


Виды работ:


  • Аудит безопасности внешнего периметра
  • Аудит безопасности внутреннего периметра
  • Физическая безопасность
  • Мобильные приложения
  • Анализ кода
  • Социальная инженерия
  • И вообще все, что вы сможете придумать (но увлекаться сильно не стоит)

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


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


Тест на проникновение с повторением N раз в год


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


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


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


Багбаунти на аутсорсе


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


Возникает резонный вопрос: “Чем это отличается от HackerOne?” Основное отличие — в количестве исследователей и их скиллах. Для попадания в программу нужно пройти собеседование и тестовое задание, как при устройстве на работу в оффенсив-компанию. Следовательно, получается меньше участников, но выше общий уровень скиллов (и отсутствие всем известных нам персонажей, которые любят кидать отчеты сканеров).


Виды работ (в рамках данного подхода):


  • Аудит безопасности внешнего периметра
  • Мобильные приложения
  • Бинарные исследования

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


Несмотря вышеозначенные преимущества, у подхода есть и свои недостатки:


  • Ограниченный спектр работ в сравнении с классическим подходом к пентесту. Этот недостаток является следствием удаленной работы всех исследователей и популярности направлений в безопасности.
  • Зависимость результатов работы от выплат. Большое количество исследователей не гарантирует вовлеченность абсолютно каждого, размер вознаграждений оказывает сильное влияние на популярность программы.
  • Сложность в планировании бюджета — типичная проблема для любой багбаунти-программы.

Работы по анализу защищенности на постоянной основе


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


Список видов работ в данном случае несколько шире по сравнению с описанными выше подходами. Он включает в себя:


  • Аудит безопасности внешнего периметра
  • Аудит безопасности внутреннего периметра
  • Мобильные приложения
  • Десктопные приложения
  • Hardering (безопасная конфигурации серверов)
  • Обучение разработчиков

Что касается таких пунктов, как Десктопные приложения и Hardering, то задача не в поиске бинарных уязвимостей (если говорить о десктопах) и не в тотальном закручивании гаек (в случае с Hardering). Главное — это взгляд на систему с пентестерской стороны.


Особенность подхода состоит в том, что он максимально близок к работе безопасников на местах в компаниях, которые создают защиту изнутри, а именно:


  • Высокая осведомленность о работе (за счет доступа к документации и собственного эмпирического опыта при исследовании конкретного продукта) и разработке внутренних сервисов (возможность влиять на процесс разработки и непосредственно наблюдать за сроками).
  • Доступ к исходным кодам разрабатываемых продуктов.
  • Возможность участвовать в построении архитектуры. Это позволяет находить уязвимости до написания кода. Например, CSRF-токены. Иногда бывает, что люди просто забывают о такой важной и простой вещи, как токены. Если данная проблема вскроется после выката релиза, её исправление может стать дорогостоящим и трудоемким делом (хотя все, конечно же, зависит от размера системы).
  • Высокая актуальность исследуемых продуктов. При выпуске нового релиза или изменений парочки важных строк кода, влияющих на безопасность напрямую, мы сразу можем получить внесенные изменения и начинаем во всю их тестировать.

В итоге получается, что работы проводятся уже не черным, а всеми нами любимом белым ящиком.




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


Немного про SDLC и его друга SecureSDLC


SDLC


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


На данный момент существует большое количество моделей SDLC, самые известные из них — Waterfall, Iterative, Agile (подробнее о них можно почитать тут). Все они имеют свои достоинства и недостатки, каждая из них весьма вариативна в использовании; все зависит от размера проекта, бюджета, объема человеческих ресурсов и других особенностей. Их всех объединяет наличие шести ключевых этапов:


  • Планирование — один из основных шагов, на котором происходит определение решаемой проблемы, подсчет ресурсов и издержек, поиск альтернативных путей решения и т.д.
  • Анализ — разработка требований, осуществление технико-экономического обоснования и прочего, что мы так не любим.
  • Дизайн. На данном этапе происходит построение архитектуры, выделение компонентов, модулей, интерфейсов и т.п.
  • Разработка и внедрение — самый большой и важный этап, именно здесь происходит написание кода, конфигурация и настройка железной части проекта, если таковая существует.
  • Тестирование и интеграция — здесь мы проводим проверку того, насколько результаты соответствуют поставленным задачам.
  • Поддержка системы. Проведение контроля актуальности разработанной системы. Сюда входит как замена оборудования, так и обновление различных программных компонентов.



SecureSDLC


SecureSDLC — тот же SDLC, но с приставкой Secure. Просто добавляешь приставку, и все становится безопасным (нет). Суть всего этого весьма проста: как видно на прекрасной картинке из Интернета, к каждому из этапов разработки добавляются действия, связанные с безопасностью (расчеты рисков, статический\динамический анализ кода, фаззинг, обучение и т.п.).


image


В классической реализаций SDLC проверка безопасности ограничивалась стадией тестирования, если вообще проводились.


Расширенная реализация нацелена на:


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

На чем же всё базируется?


В настоящее время имеется большое количество компаний, практикующих безопасную разработку. Например, такие крупные и известные, как Microsoft, Cisco, Dell. Сегодня любой уважающий себя вендор следит за безопасностью своих решений (но не всегда это получается). Абсолютно у каждого производителя есть свой подход, который формируется, исходя из внутренних особенностей разработки.


В качестве скелета при построении своей безопасной разработки многие используют общепринятые в мире практики:


  • Open Security Assurance Maturity Model (OpenSAMM) от OWASP
  • Microsoft Security Development Lifecycle (SDL). Process Guidance.

На очередной картинке из Интернета можно увидеть соответствие бизнес-функций и практик безопасности.




Условия задачи


В настоящее время мы ведем большой проект (подробности и особенности — далее), работая по двум большим направлениям: “пентест” разрабатываемых продуктов и бинарные исследования. В данной статье мы сосредоточимся на пентестерской части.


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


Что же не устроило нас в классических подходах? У разового пентеста есть некоторые недостатки:


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

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




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


Собираем список продуктов


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




Перед началом работ над таким обширным продуктом, как «МойОфис», необходимо выделить основные его модули и части (даже с виду неделимые), чтобы не получилось той самой книжной полки. Это необходимо и для лучшего понимания внутренних процессов приложений и распределения ресурсов команды.


У нас это получилось таким образом:


  • Web — это настоящее SPA приложение, только js/css/html файлы. Сервисы, которые входят в этот компонент: Почта, Календарь, Контакты, Диск, Редактор документов, Панель управления администратора, Logos (мессенджер).
  • Мобильные приложения — по три приложения (Редактор Документов, Почтовый Клиент, Logos — мессенджер) под каждую из платформ — iOS, Android, Tizen (да-да, не удивляйтесь).
  • Десктопные приложения (Документы, Почта, Мессенджер) под три платформы — Linux, OS X, Windows.
  • Серверное API, доступное публично.
  • Внутренние сервисы, которые общаются друг с другом (Redis, Swift и другие).

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


Планирование спринтов


Чтобы “бесшовно” встроиться в процесс разработки такого продукта, нам необходимо адаптироваться к его глобальным циклам планирования, в нашем случае — релизным циклам. Релиз новых версий «МойОфис» происходит каждые три месяца. Поэтому мы живем спринтами как раз по три месяца. Что же такое спринт в нашем понимании?


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


Естественно, мы понимаем, что планирование сроков в разработке, мягко говоря, получается очень плохо, потому ожидаем законного вопроса: “А если сроки едут, что делаете?”




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


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


Пример одного из спринтов (первое число — номер недели спринта):


  1. Веб-приложения компонентов (Почта, Контакты, Календарь)
  2. Веб-приложения компонентов (Почта, Контакты, Календарь)
  3. Нативные мобильные приложения для Android, iOS, Tizen
  4. Нативные мобильные приложения для Android, iOS, Tizen
  5. Сервер аутентификации; Бекенд веб-приложений
  6. Бекенд файлового сервера, Веб-панель и API администратора
  7. Веб-панель редактора документов, Бекенд редакторов
  8. Десктопный клиент для файлового сервера
  9. Десктопный клиента для почты, календаря, контактов, документов
  10. Мессенджеры для Web, MacOS, Win, Linux и их API
  11. Misc
  12. Misc
  13. Misc

Misc — это как раз те свободные слоты, их наличие очень важно. Как можно заметить, на некоторые, довольно большие части (как Веб, где проверяется и API-часть), мы закладываем больше времени (10 рабочих дней). Также в Misc попадают дополнительные исследования и совместная проработка security-ориентированной архитектуры совместно со специалистами заказчика.


Команда аудиторов


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


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


Стенды


В своих тестах мы используем полную копию того, что поставляется клиентам, со всеми свежайшими обновлениями. Забегая вперед, скажем, что мы посчитали довольно важным развернуть полностью весь «МойОфис» с нуля и понять каждый шаг, где, что и как деплоится и настраивается, попутно пытаясь сравнить это с документацией. Учитывая, что наша специализация — далеко не системное администрирование, это была сложная задача для “падавана юного”.


Отчетность


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


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


  • Название
  • Тип тикета
  • Критичность уязвимости
  • В каких компонентах проявляется
  • Описание уязвимости — действия для повторения



При таком донесении информации абсолютно любой человек поймет, насколько эта уязвимость критична, даже без какой-либо квалификации в безопасности или вообще в IT.


Анализ защищенности. Немножко практики


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


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


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


‘“><svg onload=alert(1)>{{7*7}}

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

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


  • Пользователю доступны два порта (80 и 443). Все, что за ними, считается кластером и доверенной зоной.
  • Кластер — это может быть неограниченное количество серверных машин (в нашей инсталляции — 2), на которых работает целый пучок микросервисов (java, go, c++ — ядерная часть редактора, базы данных, SWIFT и другие).
  • Часть сервисов ставится из RPM-пакетов, часть — docker-контейнеры (что дает дополнительную изоляцию, это особенно важно при работе с конвертацией документов).

Web


Клиентская часть — это AngularJS и полноценное SPA без явных костылей со стороны серверного API (таких как “а вот тут отдадим формочку с бекенда!”).


Серверная часть — по-разному, в качестве фронта используется nginx, за ним множество java/golang сервисов, которые обрабатывают клиентские запросы.


Анализировать SPA-приложения очень круто и довольно удобно, с точки зрения запросов-ответов все логично и складно. Поиск уязвимостей в самом SPA, конечно же, довольно сложная задача.


Burp Suite


Да, тут нет секрета, мы, как и многие, используем Burp (никакого Larry Lau, только лицензия) и его модули для поиска разного рода уязвимостей (инъекции, IDOR, SSTI и другие). Без этого инструмента вообще никак.


Также его могут применять разработчики, чтобы проверить результат после исправления уязвимости, вместо того, чтобы просить нас и растягивать весь этот процесс. Для этого будет достаточно бесплатной версии и двух вкладок Proxy и Repeater.




Также мы используем пучок кастомных скриптов, рассмотрим один из них.


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


В security-мире есть исследователь Mario Heiderich @0x6D6172696F (.mario), который много времени посвятил поиску XSS в разных крупных сервисах вроде Google, участвовал в создании библиотеки DOMPurify для безопасной подстановки unsafe html сразу в DOM (подробнее о ней будет рассказано ниже). А главное — он опубликовал для нее автотесты, которые используют различные хитрости и тонкости работы браузеров и HTML5. Идеальное решение для тестирования почтового сервиса на возможность внедрения JS.


> Ссылка на демо и тесты
> И не забудьте о специальных векторах для HTML5


Что мы сделали? Мы взяли эти тесты (+ дописали некоторые свои из секретных закромов) и отослали на IMAP-сервер своим скриптом на Python в десять строчек, ибо обычно HTML нельзя отправлять из Веб-клиента, а только напрямую на почтовый сервер, попутно открывая письма в браузере. Исполнился JS? Заводим тикет.


Наверняка все знают, что можно обнаружить открытие письма пользователем с помощью картинки (тег img) в письме, но и другие теги могут позволить нам это сделать. Тут нам опять поможет репозиторий Cure53. С его помощью можно обнаружить теги, которые сливают информацию о пользователях.


Ограничение схем для некоторых тегов, например, почему нельзя использовать file:/// для тех же "img src" (подробно по ссылке от ValdikSS), были сразу учтены при разработке.


Следующая проблема — это вложения. Обязательно нужно тестировать вложения разных форматов с XSS-нагрузкой, их можно взять тут. Этим мы проверим, как сервер хранит и отдает вложенные файлы в письмах.


Мобильные приложения


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


Для исследования iOS и Android используются оба подхода: автоматизированный и ручной. Для Tizen — только ручной. Про автоматизированный — в снятии “низко висящих фруктов” здесь очень помогает MobSF.




Он позволяет автоматически собрать типичные проблемы, сделать ревью ресиверов, сервисов и т.п. вещей в Android и даже осуществляет некоторое подобие анализа исходного кода (после декомпиляции). Также проверяет флаги (Stack smashing protection, PIE ...) при компиляции.


Ручной анализ — Android (+root), iOS + jailbreak (на данный момент мы используем последний доступный джейл для iOS 9.3.3).


А вот с Tizen не все так просто. Сам он очень странный и непривычный. Система является одним большим браузером с поддержкой HTML5, давно находится в разработке и тоже представляет интерес для исследователей безопасности, как что-то новое и неизученное.


Для начала вопрос — сколько вы вообще держали телефонов c TizenOS? Вот столько же статей и security-тулз для этой платформы. Мы пошли по developer way — скачали Tizen SDK, подключились к телефону и дебажили приложение. В этом режиме можно просмотреть файловую систему, получить debug console и делать другие вещи, позволяющие найти проблемы в безопасности. К сожалению, функционал достаточно ограничен, и нет прямого консольного доступа к OS.


Инструмент находится на официальном сайте Tizen. Можно использовать эмулятор, если есть желание познакомиться с этой операционной системой.




Сама платформа Tizen на данный момент имеет большое количество недостатков со стороны безопасности. Можно вспомнить недавнюю новость о сорока зеродеях в платформе и вот эту публикацию. Также о некоторых уязвимостях в SmartTV, где был затронут и TizenOS, рассказывал BeLoveпрезентация.


Desktop


Про десктопные приложения «МойОфис» будет отдельная статья, посвященная бинарному фаззингу. В рамках же данных работ (именно в пентестах) смотрятся такие области, как взаимодействие с файловой системой (временные папки, права на них и т.п.), DLL hijacking, работа с сетью (передача данных по защищенным каналам — TLS), хранение токенов и подобное.


Многие десктопные приложения написаны на основе Electron, на котором созданы решения GitHub, Slack, Discord и многие другие. Сам Electron является открытым проектом и представляет собой webview, то есть небольшой браузер, который визуально не отличить от нативного приложения.


Исследование сторонних продуктов. DOMPurify и причем тут Safari


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


При исследовании одного из компонентов нами была найдена довольно критичная уязвимость клиентской части — внедрение JS-кода, ну или просто XSS. Изначально было непонятно, почему так произошло, ведь данный компонент использовал ту самую JS библиотеку DOMPurify для защиты от XSS.


DOMPurify — это средство только для DOM-а, сверхбыстрое, убер-толерантное XSS-дезинфицирующее решение для HTML, MathML и SVG (немножко описания с Гита). MathML — это язык разметки на основе XML для представления математических символов и формул. Все это, конечно, работает и в контексте HTML5 фишек. То есть в этом продукте собрано все самое новое и современное.


Он написан на JavaScript и работает во всех популярных браузерах:


  • Safari
  • Opera (15+)
  • Internet Explorer (10+)
  • Firefox
  • Chrome
  • Все, что использует Blink or WebKit

Разрабатывает инструмент компания Cure53, в частности, Mario Heiderich @0x6D6172696F (.mario), а контрибьютят туда такие известные ребята, как @filedescriptor, @shafigullin и другие. Выходит, такая сборная самых крутых исследователей веб-безопасности трудится над открытым программным средством для защиты от уязвимостей клиентской стороны.


Ссылочка на Гит.


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


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


Payload: <svg onload=alert(document.domain)>



Ребята быстро исправили уязвимость, а компания FastMail, которая взяла DOMPurify под крыло своей багбаунти-программы, выплатила нам немножко денег “на пиво”.


Но на этом все не закончилось, поскольку дыра работала только для Safari, мы немного копнули в его сторону и получилось, что функция DOMParser работает некорректно, и при парсинге html страницы исполняет JS, что никакой браузер из популярных не делает (да-да, даже IE), о чем мы сообщили в Apple.


Payload: new DOMParser().parseFromString('<svg onload=alert(document.domain)>', 'text/html');



И буквально на днях Apple выдало CVE-2017-7038 — что-то очень похожее на UXSS-уязвимость, но без обхода SOP. Подробнее обо всех возможных уязвимых функциях, возможно, мы когда-нибудь опишем в отдельной статье.


В итоге, получилась такая нетривиальная схема: XSS в приложении «МойОфис» была возможна из-за подключения DOMPurify-библиотеки, которая не обрабатывала SVG теги (хотя должна была), а отдавала напрямую стандартной браузерной функции DOMParser, которая была реализована с ошибкой.


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


Реальные уязвимости


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


Внедрение внешних сущностей XML


Поскольку у нас есть хранение и редактирование документов, мы каким-то образом должны отрисовывать пользователю документ и вносить изменения в них, если это нужно. Как вы можете знать, современные офисные документы — это набор XML-файлов, упакованных в архив. А какое редактирование документов без парсера XML?


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


  • Загружаем документ
  • Сервер распаковывает архив
  • Пытается преобразовать XML во внутренний формат
  • Сохраняет в нужном себе формате на сервере

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


  • Создали валидный .docx документ
  • Распаковали
  • В один из xml файлов добавили

<!DOCTYPE foo [  
   <!ELEMENT foo ANY >
   <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
…
<foo>&xxe;</foo>

  • Запаковали обратно, переименовали в .docx
  • Загрузили на сервер

И после обработки увидели содержимое /etc/passwd. Но с помощью этой уязвимости можно не только читать файлы на сервере.




Так или иначе, нам не удалось ничего важного прочитать, поскольку весь парсинг происходит в изолированном контейнере (docker). Уязвимость была оперативно закрыта.


Кстати, для генерации подобных файлов и проверки XXE можно использовать тулзу. С её помощью некоторые исследователи находили XXE и в багбаунти-программах тоже.


Remote Command Execution via EL Injection


Расскажем и про честное RCE — удаленное выполнение команд OS на сервере. Некоторая часть микросервисов написана на Java, в том числе, с применением Spring. Уязвимости такого рода (EL Injection) для Spring (и не только) очень хорошо поддаются фаззингу, если вы отправите на сервер {{7*7}}, то в ответе на странице получите выполнение математической функции равное 49.


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


${T(java.lang.Runtime).getRuntime().exec("ls")}

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


Но в нашей конкретной ситуации такая простая отправка пейлоада не работала, поскольку при отправке запроса на Веб-сервер наши кавычки проходили URL-encode и не воспринимались Spring-ом как спецсимволы. Что же делать в такой ситуации? Все достаточно просто: можно, используя стандартные средства языка, провести кодировку из числовых значений в символы с помощью функции java.lang.Character.toString() и конкатенировать все символы. Про данный трюк можно прочитать тут.


В итоге, у нас получился большой и страшный пейлоад (чтение /etc/passwd/):


${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())}

Стоит отметить, что RCE было также внутри docker-контейнера, и хоть он создан не для защиты, но все же дает некую изоляцию.


Заключение


Уф, вот и подошла к концу статья. Давайте теперь суммируем, чем отличается наш подход от классических тестов на проникновение:


  • Аудиторы больше знают о процессе разработки и работе продукта. Осведомленность достигается за счет доступа к документации и возможности следить за темпами разработки.
  • Возможность участвовать в построении архитектуры, что позволяет находить проблемы и уязвимости на стадии планирования.
  • Доступ к исходным кодам.
  • Смещение работ от черного ящика к белому ящику. Классические тесты обычно сильно ограничены в этом плане.
  • Ликвидация проблемы генерации больших отчетов.
  • Грамотное распределение ресурсов аудиторов. Все расписано по неделям, время используется эффективно, и всегда в проекте участвуют люди, осведомленные о внутренних особенностях компонентов.
  • Повышение уровня экспертизы за счет исследования большого количества разнообразных сервисов.
  • Наличие возможности искать уязвимости в сторонних продуктах, которые используются в разработке, и делать мир “чище и приятней” .
  • Более подробное изучение системы. За счет перехода от поверхностного сбора “низко висящих фруктов” к исследованию каждого компонента в отдельности, следовательно, возможно осуществлять поиск более сложных уязвимостей.

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


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


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


Полезные ссылки



P.S. Выражаю благодарность за помощь в подготовке материала BeLove.

Поделиться с друзьями
-->

Комментарии (6)


  1. g0rd1as
    03.08.2017 00:10
    +4

    Гигантскую работу, однако, проделали! Статью сохраняю в закладки и буду регулярно перечитывать.


  1. BonBonSlick
    03.08.2017 00:10

    Годно, хотя многое непонятно)


    1. GShikari
      03.08.2017 00:11

      Можете подробнее сказать, что непонятно? Я в следующих статьях постараюсь учесть.


      1. BonBonSlick
        03.08.2017 09:31
        +1

        Много новых слов во второй части, и пару в первой. Для понимания что происходит и общей картинки, пришлось почитать в гугле еще кусочки. А в целом статья хорошая, спасибо.

        Примеры новых терминов для меня, как для того кто провел 0 пентестов:
        Burp Suite, Larry Lau, IDOR, SSTI, Tizen, MobSF, jailbreak, XXE, EL Injection, RCE.
        Большая часть ссылок есть в статье.


        1. GShikari
          03.08.2017 11:51
          +2

          Добавил всякого рода аннотация к сокращениям, чтобы было понятно, что именно искать)


  1. anador
    03.08.2017 14:32
    +1

    Очень качественная статья, спасибо