РАЗБОР
На проверке
Разбор атаки SSTI Standoff 365: от инъекции до root
Режим чтения
[ обложка статьи ]
На Standoff 365 за последний год я прошёл семь машин с веб-компонентом - в четырёх начальная точка входа оказалась SSTI. Машина Messenger стала показательным кейсом: от
{{7*7}} в поле профиля до root-шелла и двух реализованных бизнес-рисков за четыре часа. Ниже - пошаговый разбор атаки SSTI Standoff 365 с payload'ами, командами и объяснением логики на каждом этапе. Без воды, без «давайте рассмотрим» - только цепочка.Эксплуатация уязвимости шаблонизатора: разведка и детект SSTI
Любой взлом веб-приложения на кибербитве начинается с разведки.nmap -sV -sC по хосту Messenger показал три открытых порта: SSH (22), nginx (80) и tcpwrapped (3000). На 80-м - самописный мессенджер на Python/FastAPI. На 3000-м порт отображался как tcpwrapped, но при обращении через браузер обнаружился Gitness - опенсорсная платформа для хостинга Git-репозиториев и CI/CD-пайплайнов.Самописное приложение - известных CVE не будет. Уязвимости придётся копать вручную.
Фаззинг директорий через
ffuf -w wordlist.txt -u http://target/api/FUZZ дал ключевой результат: Swagger-документация на /api/swagger раскрыла все эндпоинты API. Среди них - friendship summary, описанный как «Get Friendships Html Table Api View». Все прочие эндпоинты возвращали JSON, а этот - HTML. Если FastAPI-приложение рендерит HTML на стороне сервера, используется шаблонизатор. Для Python-стека это почти наверняка Jinja2.Как отличить Server-Side Template Injection от обычного XSS? Согласно методологии PortSwigger, ключевой тест - отправить в контролируемое поле математическое выражение
{{7*7}}. Сервер вернул 49 вместо текста - ввод обрабатывается как код шаблонизатора. Это SSTI - A03:2021 (Injection) по классификации OWASP Top 10, Exploit Public-Facing Application (T1190, Initial Access) по MITRE ATT&CK.Дальше - развилка из HackTricks для определения движка: payload
{{7*'7'}} возвращает 49 в Twig (PHP) и 7777777 в Jinja2 (Python). На Messenger вернулось 7777777 - Jinja2 подтверждён. В Burp Repeater такие тесты занимают минуту, но экономят час неверных payload'ов.Цепочка атаки RCE: SSTI to RCE через Jinja2
,
stty raw -echo; fg. Без этого интерактивные команды не работают, а на кибербитве терять время на нестабильный шелл - значит подставляться под SOC.Повышение привилегий: кейс с кредами в конфигах
Post-exploitation начинается с базовой разведки:whoami, id, uname -a - System Information Discovery (T1082). Затем - поиск privilege escalation techniques.На машинах Standoff 365 мне встречались три вектора повышения привилегий:
- SUID-бинарники -
find / -perm -4000 -type f 2>/dev/nullвыдаёт бинарники с установленным SUID-битом. Нестандартные утилиты в списке - потенциальный вектор через GTFOBins. - Креды в файлах - Credentials In Files (T1552.001). Конфигурации
.env, захардкоженные токены в исходниках, секреты в переменных окружения. - Docker-сокет - если приложение крутится в контейнере и сокет
/var/run/docker.sockдоступен непривилегированному пользователю, это часто прямой путь к root на хосте.
Для автоматизации поиска -
linpeas.sh. Скрипт проходит по типичным мисконфигам: SUID, cron, writable paths, чувствительные файлы. На Standoff запускать сразу после стабилизации шелла - экономит время, которое на кибербитве критично. Но целиком полагаться на автоматику не стоит: grep -r "password\|secret\|token" /app/ 2>/dev/null иногда находит то, что linpeas пропускает. На одной машине именно ручной grep выдал токен в комментарии к коду - linpeas прошёл мимо.Захват инфраструктуры: lateral movement и пентест соседних сервисов
С добытыми токенами - этап захвата инфраструктуры. На Messenger рядом стоял Gitness на порту 3000. Токены из конфигов дали авторизацию и доступ к Git-репозиториям с исходниками приложения.В репозиториях обнаружились дополнительные секреты: конфигурации RabbitMQ, адреса Redis, внутренние API-ключи. Через RabbitMQ удалось отправить crafted-сообщение, обработанное worker-процессом. Через Redis - перехватить данные из очереди задач. Exploitation of Remote Services (T1210, Lateral Movement). Каждый сервис - новая точка опоры.
На Standoff 365 каждый такой шаг - реализация бизнес-риска. На Messenger их два: «Получение доступа к корпоративной переписке разработчиков» и «Получение ключа шифрования мессенджера». Оба закрыты через описанную цепочку. Для SOC-команды на защите - два «недопустимых события», которые она не предотвратила.
Атака на веб-приложение пошагово: kill chain и MITRE ATT&CK
Разбор CTF Standoff полезно маппить на kill chain - структурирует мышление и помогает не пропускать этапы на следующих машинах.| Этап | Действие | MITRE ATT&CK |
|---|---|---|
| Initial Access | SSTI в Jinja2 через поле профиля | T1190 |
| Execution | Реверс-шелл через os.popen | T1059.004 |
| Discovery | whoami, id, анализ файловой системы | T1082 |
| Credential Access | Токены в конфигах приложения | T1552.001 |
| Privilege Escalation | Переиспользование JWT-секретов | T1078 |
| Lateral Movement | Захват Gitness, RabbitMQ, Redis | T1210 |
| Persistence | Web Shell при закреплении | T1505.003 |
Вся цепочка атаки RCE и последующая post-exploitation начинаются с одной точки - несанитизированного пользовательского ввода в функции
render(). Одна ошибка разработчика - полная компрометация инфраструктуры.Зачем это реальному злоумышленнику, а не CTF-игроку? Мотивация при SSTI to RCE в продакшене - получить foothold в корпоративной сети через публичное веб-приложение. Дальше - данные клиентов, финансовые системы, ransomware. На Standoff 365 эта логика моделируется через бизнес-риски: каждый флаг - конкретный ущерб для виртуальной компании.
Разбор атаки SSTI Standoff 365 вроде этого вызывает предсказуемый скепсис: «на реальной инфре WAF и сегментация, такое не пройдёт». Верно - наполовину. SSTI в продакшене встречается реже, чем на CTF-стендах. Но в моей практике на самописных Python-сервисах с шаблонизатором SSTI или соседняя инъекция находится нередко. Причина одна: разработчики не воспринимают шаблонизатор как поверхность атаки. Защищают SQL-запросы, проверяют JWT, ставят rate limit - и при этом передают пользовательский ввод напрямую в
render(). Шаблонизатор для них - «просто рендер HTML», а не точка входа.Privilege escalation через креды в файлах - не слабость CTF-стенда, а паттерн из реальных проектов. Захардкоженные секреты убивают инфраструктуру чаще, чем 0-day. Цепочка post-exploitation на Standoff и на пентесте отличается не техниками, а скоростью: на кибербитве SOC-команда, по моему опыту, может отрубить шелл за несколько минут. Полная цепочка - от SSTI до lateral movement - строится не из сложных эксплойтов, а из последовательных мелких ошибок. Тренировать навык сборки таких цепочек - единственный способ не зависать на каждом этапе в реальном проекте. На WAPT эту цепочку проходят в течение двух модулей с лабами.
AI-выжимка
сгенерировано ИИ
Тезисы статьи скоро
Статья читается полностью. Тезисы со ссылками на разделы появятся позже.
Содержание
Codeby Academy
Практика и мастерство
От основ до продвинутого — программы для практиков Codeby.
Перейти к курсу →
Поиск в обсуждении
Карта ветки
Продолжить чтение
Следующий разбор
LLM в WAPT: Полезные модели и гайд "как настроить".
Ещё по теме
- Статья
- Статья
- Статья
Комментарии
0