ssti уязвимость что это
Ssti уязвимость что это
Server-Side Template Injection или SSTI представляет собой механизм атаки, при котором злоумышленник внедряет в шаблон вредоносный код. Так как инъекция шаблона производится на стороне сервера, то многие защитные программы, фильтрующие трафик со стороны пользования, не обнаруживают постороннего вмешательства.
Каковы особенности атаки SSTI и каким образом можно защититься от них?
Что такое шаблонизация
Механизм шаблонов разработан для того, чтобы на их основе упростить процесс создания интернет-страниц с использованием динамичных данных. Пользователь использует шаблон для основного оформления страницы, но вставляет в него собственный контент.
Атака с использованием шаблона на стороне сервера производится в момент, когда пользовательская информация объединяется с шаблоном. Благодаря этому хакеры могут вводить произвольные директивы шаблонов и манипулировать ими с целью получения контроля над сервером.
Опасность внедрения шаблона на стороне сервера
Как понятно из названия, Server-Side Template Injection выполняется на стороне сервера, что делает такую атаку особенно опасной. Сайт может подвергаться различным атакам в зависимости от типа шаблона и того, каким образом он используется на сервере. В некоторых случаях само внедрение вредоносного кода не несет повышенной опасности, но оно готовит почву под более опасные атаки.
В наиболее опасных случаях злоумышленник может инициировать удаленное выполнение кода и получить полный контроль над сервером. В дальнейшем он может использоваться для атак на внутреннюю информационную инфраструктуру компании.
Если установленное защитное ПО не дает выполнить опасный код, механизм внедрения шаблона на стороне сервера может открыть для чтения конфиденциальные данные на сервере.
Как предотвратить атаку SSTI
В зависимости от ситуации можно использовать несколько способов защиты от Server-Side Template Injection:
Обзор SSTI-уязвимостей для приложений, разработанных на Flask/Jinja2
Если вы ни разу не слышали об инжектирования в шаблоны на стороне сервера (Server-Side Template Injection, SSTI) или не уверены, что хорошо знаете эту технологию, рекомендую предварительно ознакомиться со статьей Джеймса Кеттла (James Kettle).
Если вы ни разу не слышали об инжектирования в шаблоны на стороне сервера (Server-Side Template Injection, SSTI) или не уверены, что хорошо знаете эту технологию, рекомендую предварительно ознакомиться со статьей Джеймса Кеттла (James Kettle).
Как профессионалы в сфере безопасности мы помогаем организациям, которые принимают решения, несущие определенные риски. Если рассматривать риск в разрезе влияния и вероятности возникновения той или иной ситуации, без истинного знания о влиянии уязвимости мы не сможем правильно рассчитать риск. Недавно Джеймс надоумил меня провести исследование, суть которого сводится к оценке влияния SSTI-уязвимостей на приложения, разработанные на фреймворке Flask и шаблонизаторе Jinja2. Эта статья – результат данного исследования. Если вы хотите чуть больше погрузиться в данную тему, рекомендую ознакомиться со статьей Райана Рейда (Ryan Reid), где подробно рассказывается о том, что представляет собой SSTI в приложениях, написанных на Flask/Jinja2.
Для того чтобы оценить степень влияния SSTI, мы будем использовать тестовое приложение, содержащее следующее представление.
Суть работы данного приложения заключается в следующем. Разработчик решил отказаться от отдельного шаблона под 404 страницу, а создал строку для шаблона внутри функции представления, отвечающего за отображение 404 страницы. При возникновении ошибки пользователю возвращается URL с ошибкой, но вместо передачи URL в контекст шаблона через функцию render_template_string, используется строковое форматирование для динамически добавляемого URL к строке шаблона. Вполне резонно, не правда ли? Я видел ситуации хуже.
При выполнении кода выше, получаем ожидаемый результат:
Рисунок 1: Страница с ошибкой 404
Многие читатели тут же подумали об XSS и были правы. Если в конец URL добавить script > alert (42) script >, получим XSS-уязвимость.
Рисунок 2: Эксплуатация XSS-уязвимости
Рисунок 3: Результат добавления выражения << 7+7 >> в конец URL
Теперь рассмотрим подробнее, как использовать технологию SSTI на примере нашего приложения.
После получения первого рабочего эксплоита, мы будем более глубоко исследовать шаблон и искать SSTI-уязвимость. Модифицированная уязвимая функция представления тестового приложения будет выглядеть так.
Но вначале сделаем небольшую паузу и поговорим о том, что говорится в документации относительно такого понятия как «контекст шаблона». Существует несколько источников, откуда объекты попадают в контекст шаблона.
Объекты, добавленные разработчиком.
Нас больше всего интересуют пункты 1 и 2, поскольку эти объекты доступны во всех приложениях, где используется Flask/Jinja2. Объекты из пункта 3 уже будут варьировать в зависимости от конкретного приложения, к которым можно получить доступ различными способами. На сайте StackOverflow есть несколько примеров. Мы не будем глубоко погружаться в исследование нестандартных объектов (пункт 3), поскольку здесь требуется статический анализ кода.
Методология анализа и поиска уязвимостей на базе пунктов 1 и 2 будет выглядеть примерно так.
Исследуем объект locals при помощи dir на предмет того, что доступно в контексте шаблона.
Исследуем все найденные объекты, используя dir и help.
Анализируем исходный код на предмет присутствия чего-нибудь интересного.
Не спасает и хранение этих данных в переменных среды окружения, поскольку объект config содержит все переменные, связанные с конфигурацией, ПОСЛЕ обработки фреймворком.
Рисунок 5: Содержимое объекта config
Рисунок 6: Содержимое объекта config после импортирования новых элементов
Как было сказано ранее, любой объект, добавленный в config, можно вызвать через SSTI-уязвимость (конечно, при условии, что сам элемент вообще способен быть вызванным). Следующий шаг: поиск нужного функционала внутри доступных к импорту модулей, который поможет выйти за пределы песочницы шаблона.
Скрипт ниже повторяет алгоритм методов from _ object и import _ string и анализирует Python Standard Library на предмет объектов, доступных для импорта.
Ниже показаны некоторые наиболее интересные результаты работы скрипта, который был запущен в среде с Python 2.7, включая наиболее интересные объекты, доступные для импорта.
Далее мы используем нашу методологию к наиболее интересным элементам в надежде найти нечто, что поможет нам выйти за границы песочницы.
Спойлер: среди найденных результатов я не смог найти что-то, что помогло бы мне «покинуть» песочницу. Однако в целях обнародования результатов моего исследования ниже представлена дополнительная информация касательно найденных объектов, которую вы, при необходимости, можете использовать в будущих собственных исследованиях.
HTB Spider. Эксплуатируем инъекцию шаблонов и уязвимость в XML
Содержание статьи
warning
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
Разведка. Сканирование портов
Добавляем IP-адрес машины в / etc/ hosts :
И запускаем сканирование портов.
Справка: сканирование портов
Сканирование портов — стандартный первый шаг при любой атаке. Он позволяет атакующему узнать, какие службы на хосте принимают соединение. На основе этой информации выбирается следующий шаг к получению точки входа.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта.
Находим два открытых порта: 22 (служба SSH) и 80 — веб‑сервер nginx 1.14.0.
Первым делом открываем сайт. На нем можно зарегистрироваться — лучше сразу же это сделать, чтобы получить доступ к большему числу функций, которые можно тестировать.
Стартовая страница сайта
На что стоит обратить внимание? Так как это интернет‑магазин, здесь можно добавлять товары в корзину. При этом используются cookie, но сделать с ними ничего интересного пока нельзя, поскольку они закодированы.
Еще на сайте есть форма поиска. Я попробовал скармливать ей разные интересные последовательности из своих словарей, но уязвимостей не нашел.
Сканирование поддоменов, директорий и другого контента тоже ничего не дало. Поэтому я решил вернуться к формам регистрации и авторизации.
Первое, на что натыкаемся, — это ограничение длины имени пользователя.
Сообщение об ограничении длины логина
Точка входа
На любые кавычки и комментарии при регистрации имени пользователя admin; # форма никак не реагировала.
Отображение имени пользователя на главной странице
Отображение имени пользователя на странице user
Отображение имени пользователя на главной странице
Отображение имени пользователя на странице user
В подобных случаях, когда работают теги HTML, стоит сразу проверить возможность внедрить шаблон (server-side template injection). Очень часто подобные уязвимости совместимы с SSTI. И при использовании имени пользователя << 7*7>> на странице / user обнаружим, что шаблон сработал!
Отображение имени пользователя на главной странице
Отображение имени пользователя на странице user
Уязвимость SSTI
Server-side template injection (SSTI) — это атака, при которой злоумышленник внедряет в шаблон вредоносный код. Шаблоны страниц придуманы для того, чтобы отделить верстку страниц от кода, но возможность вставлять в них динамические данные иногда открывает новые горизонты.
Если злоумышленнику удается отправить на сервер данные, которые будут распознаны шаблонизатором как директивы внутри шаблона, это позволит манипулировать данными и в некоторых случаях получить контроль над сервером.
Продолжение доступно только участникам
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Присоединяйся к сообществу «Xakep.ru»!
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Ssti уязвимость что это
Есть такой вид атак, как Template Injection (Внедрение шаблона). Данный вид атак делится на два вида: Server Side Template Injection (SSTI) и Client Side Template Injection(CSTI). В данной статье мы рассмотрим SSTI, а в следующей — CSTI.
Введение
Для разделения бизнес-логики (логика, которая получает и обрабатывает данные) и представления данных (логика, которая показывает данные пользователю), в современных веб-приложениях часто используются шаблонизаторы. То есть шаблонизаторы (в вебе) используются для того, чтобы отделить HTML код(представление данных) от кода языка, ответственного за бизнес-логику (PHP, Java, Python, Ruby/Rails, Perl, JavaScript). Что же такое шаблон? Шаблон – это файл, содержащий HTML и некоторые маркеры, позволяющий этот шаблон обработать и сформировать на его основе конечный HTML код.
Из-за чего возникают уязвимость SSTI? Конечно же, из-за неверной обработки пользовательских данных. В отличии от XSS (с которой SSTI очень легко спутать), Template Injection можно использовать для получения удаленного выполнения команд (RCE).
Но об этом ниже.
Простой маленький пример: предположим, что у нас есть приложение, которое на основе пользовательского ввода, отправляет email с определенным содержанием. Например, представим, что пользователь должен ввести своё имя и в ответ ему придёт email, с его именем:
Смотрим далее:
custom_email=<<7*7>>
49
custom_email=<
Object of class __TwigTemplate_7ae62e582f8a35e5ea6cc639800ecf15b96c0d6f78db3538221c1145580ca4a5 could not be converted to string
Что мы здесь видим? Явное исполнение кода(на стороне сервера) внутри песочницы. В зависимости от используемого шаблонизатора, может стать возможным побег из песочницы и выполнение произвольного кода.
Уязвимость часто возникает из-за того, что разработчики дают возможность пользователю изменять шаблон (некоторые шаблонизаторы предлагают безопасный режим для этих целей).
Все функции, которые используют данные введенные пользователем, могут быть уязвимы, в том числе вики-страницы, ревью и комментарии. Также, причиной уязвимости может быть то, что пользовательские данные вставляются непосредственно в шаблон.
Обнаружение SSTI
Данная методика была представлена на конференции Black Hat USA 2015.
Итак, есть два способа использования введённых пользователем данных.
personal_greeting=username>>
Hello user01
Идентификация
После обнаружения SSTI, мы должны выяснить, какой шаблонизатор используется. Сделать это очень просто, так как есть готовая схема для этой цели. Этот процесс выглядит так:
Нам всего-то нужно подставлять конкретные выражения и следить за ответом сервера. В некоторых случаях одно выражаение может приводить к разным ответам сервера (в зависимость от того, какой шаблонизатор используется). Например, <<7*’7′>> вернёт 49, если используется Twig, 7777777, если используется Jinja2 и не вернёт ничего, если шаблонизатор не используется.
Эксплуатация
После того, как мы выяснили какой шаблонизатор используется, следующий наш шаг — чтение документации. Вот ключевые области на которые стоит обратить внимание:
В том случае, если в документации не будет говориться о встроенных переменных, то нам придётся их брутить. Нужные словари находятся в Burp Intruder и FuzzDB.
Практика
Давайте теперь рассмотрим один пример на практике. В качестве подопытного мы возьмём Twig.
Twig — это популярный шаблонизатор PHP. Итак, для демонстрации атаки, я использовал php файл со следующим содержанием (обратите внимание на то, что вам нужно установить и подключить Twig):
Параметр name отображается в браузере. Присвоим параметру name значение DEFCON:
Ага, всё работает, но давайте передадим <<9*9>> в качестве значения:
А вот и SSTI 🙂 Пришла очередь документации.
Через 30 секунд поиска находим список глобальных переменных, которые всегда доступны в шаблоне, и среди них есть обьект _self:
Документация говорит, что Twig имеет обьект _self, который имеет атрибут env (является ссылкой на Twig_Evironment).В процессе чтения документации, мы приходим к рабочей полезной нагрузке <<_self.env.registerUndefinedFilterCallback(«exec»)>><<_self.env.getFilter(«id»)>>
Сначала мы регистрируем exec, а потом вызываем системную комманду id:
Вот мы и получили RCE 🙂 Для автоматического обнаружения SSTI существует инструмент TPLMap.
А вот отчёт на HackerOne, где иследователю удалось найти SSTI в Uber.
Выводы
Уязвимость SSTI действительно очень опасная, так как с её помощью мы можем добиться RCE. Обнаружить уязвимость очень просто (хотя часто её можно перепутать с XSS), а вот поиск/разработка полезной нагрузки — очень трудоёмкий процесс (правда, не во всех случаях). Кстати, для этой цели, на Github есть отличная шпаргалка.
Ssti уязвимость что это
В предыдущей статье, мы рассмотрели SSTI, а теперь пришла очередь Client Side Template Injection (CSTI). Главным героем этой статьи станет AngularJS.
Введение или Отличия CSTI от SSTI
Уязвимость Template Injection возникает, когда приложение, используя какой-нибудь шаблонизатор, динамически внедряет пользовательский ввод в веб-страницу. Когда страница отображается, фреймворк ищёт в странице шаблонное выражение и выполняет его.
Основное отличие CSTI от SSTI заключается в том, что при CSTI мы можем добиться лишь выполнения произвольного JavaScript кода, то есть XSS.
Критичность CSTI уже будет зависеть от самого приложения, данных и функционала, которые содержит данное приложение и т.д. Если приложение используется только для того, чтобы отображать определенный контент без аутентификации или контроля доступа, тогда CSTI не принесёт особого вреда для приложения. Но если используются, например, куки от другого, более важного с точки зрения безопасности, домена, то CSTI может быть использована для атаки на это приложение, что приводит нас уже к очень высокому риску.
Кстати, браузеры не способны засечь и предотвратить CSTI.
ВНИМАНИЕ: сразу хочу предупредить, что в этой статье я решил не изобретать велосипед, а использовать уже существующий. Поэтому данная статья будет базироваться на исследованиях автора канала LiveOverflow.
AngularJS и его проблемы
AngularJS — это JavaScript-фреймворк с открытым исходным кодом, который предназначен для разработки одностраничных приложений.
Обнаружить использование AngularJS легко: в исходном коде веб-страницы, которую вы просматриваете, будет такая строка, как ‘ng-app‘ (в основном, либо в качестве атрибута элемента html, либо в качестве атрибута элемента body), например:
Шаблоны Angular могут содержать выражения — JavaScript-подобный код, размещенный внутри <<ваш_код_здесь>>. Аналогично SSTI, если мы на вход приложению дадим <<1+1>>, то на выходе получим 2. Выражения AngularJS не зловредны сами по себе и не могут нанести значительного вреда, но если мы обьеденим их с побегом из песочницы, то мы можем добиться выполнения стороннего JavaScript кода и нанести вред.
Давайте рассмотрим пример.
Этот код динамически внедряет пользовательский ввод, но, поскольку используется htmlspecialchars, XSS не возникает.
А теперь самое интересное: данный код использует AngularJS и тоже использует функцию htmlspecialchars, но если мы внедрим шаблонное выражение (и совместим с побегом из песочницы), то получим XSS. Да-да, htmlspecialchars нас здесь не защитит (вообще, в документации говорится, что не следует использовать выражения Angular в php коде, если это касается пользовательского ввода… но кто же читает эти документации…).Заметьте, что нам нужно, чтобы ‘ng-app‘ находился выше нашего выражения в DOM.
Побег из песочницы в AngularJS 1.0.8
Представим, что у нас есть очень простая веб-страница, которая получает на вход Angular выражение и возвращает его уже в обработаном виде.
Теперь представим, что главным обьектом у нас является scope. Все, что мы будем писать в форме, будет признано как свойство обьекта scope. То есть, если мы вставим в форму <
a =
К этим свойствам можно обратиться двумя способами: a.b вернёт 1 и a[«b»] вёрнёт 1. Обьект a вызывает функцию toString():
Вот и получается, что обьект a имеет ещё и свойство toString:
Именно поэтому <
Так как мы можем выйти за предели этой песочницы? Обьект scope, как и все JavaScript обьекты, имеет свойство constructor. То есть scope.constructor — это конструктор обьекта, но scope.constructor.constructor — это уже конструктор функции:
Function(«alert(1)») создаст функцию alert(1), а вот Function(«alert(1)»)() уже вызовет нашу функцию alert(1). Вот и всё. В качестве Function() у нас constructor.constructor(), а чтобы вызвать alert(1), нам нужно ввести следущее выражение: <
Побег из песочницы в AngularJS 1.4.7
В версии 1.4.8, как вы догадались, многое изменилось в сравнении с версией 1.0.8.
Вот наше уязвимое веб-приложение.
Давайте кратко ознакомимся с одной функцией. Функция ensureSafeObject() — выполняет проверку, является ли обьект конструктором функции, окном или конструктором обьекта. Если любая из этих проверок вернёт TRUE, то возбудится исключение и обработка выражения остановится.
Именно функция ensureSafeObject() не даёт нам воспользоваться конструктором. так как использование конструкторов объектов и конструкторов функций запрещено.
Для демонстрации побега из песочницы, вам нужно будет узнать ещё одну вещь. Когда мы даём на вход приложению выражение, например, <<1+1>>, то в итоге его обрабатывает функция $eval(), то есть $eval(«1+1»).
Условно нашу полезную нагрузку можно разделить на две части: ‘a’.constructor.prototype.charAt=’a’.concat; и $eval(‘exploit=1 > > >;alert(1)//’);. Теперь давайте рассмотрим каждую часть подробней. ‘a’.constructor — это конструктор строки:
Предыдущий скрин аналогичен записи String(«b») (т.к. это конструктор строк). С помощью выражения ‘a’.constructor.prototype.charAt, мы сссылаемся на функцию charAt(), которую поддерживают все обьекты String. Давайте посмотрим на функцию concat():
Думаю, здесь всё понятно. Но самое интересное, что ‘a’.constructor.prototype.charAt=’b’.concat полностью разрушает логикку функции charAt и функция charAt() становится функцией concat():
Тперь давайте посмотрим, как будет обрабатываться наше выражение внутри программы. Сначало наше выражение попадает к функции lex(). Lex() — это функция, которая выполняет лексический анализ нашего выражения. Что такое лексический анализ? Это когда вы даёте на вход функции последовательность символ, а она формирует на их основе токены.Вот вам очень краткий пример: мы дали на вход функции строку new_var = assets и она вернёт нам такую последовательность токенов, как ИМЯ «new_var», ПРИСВАИВАНИЕ, ИМЯ «assets». Лексический анализ — это первый шаг, который выполняет компилятор. Да-да, внутри AngularJS находится JavaScript компилято 🙂 Вот мы передали наше выражение функции lex() и на выходе она вернула нам массив токенов, которые являются обьектами. И вот, что получается:
Теперь мы пропустим значительную часть этого процеса и вёрнемся к тому, что на выходе даёт компилятор. А на выходе он даёт функцию, которая проверяет с помощью функции ensureSafeObject(), является ли объект безопасным конструктором функции, и это так, т.к. конструктор String() вполне безопасен. Затем сслыка на prototype помещается в переменную, а далее выполяется проверка на то, имеет ли prototype свойство charAt (конечно же). И вот здесь компилятор допускает ошибку, так как следующим его шагом является проверка строки ‘b’.concat на то, является ли она безопасной. И..да, она является безопасной, но только эта строка полностью переписывает функцию charAt! Далее обрабатывается выражение, которое начинается с функции $eval(). Наше выражение передаётся функции lex(), разбивается на токены. Но теперь каждый символ запрашивается через функцию charAt(), а charAt() теперь у нас concat():
В итоге при дальнейшей проверке, вот что произойдёт с переменной v5:
Уязвимость CSTI не так опасна, как SSTI, но тоже может нести печальные последствия. Так что всем советую читать в документациях раздел Security Consideration, если такой есть.