Если вы когда-нибудь сталкивались с SSTI в Jinja2, то вы наверняка гуглили RCE payload и находили что-то монструозное вроде этого:
{{''.__class__.mro()[1].__subclasses__()[46]('touch /tmp/rce',shell=True)}}
Этот пейлоад достает класс
Popen по индексу из наследников
object и исполняет команду. Он не очень-то удобен: индекс
Popen (который в примере равен 46) различается от сетапа к сетапу, поэтому его нужно подбирать.
К счастью, всё можно сделать гораздо проще:
{{lipsum.__globals__["__builtins__"].eval("<python code>")}}
Здесь мы используем встроенную в Jinja функцию
lipsum (она возвращает текст "Lorem ipsum dolor..."), но вместо того чтобы вызывать её, мы через
__globals__ достаем её глобальные переменные — а в них нас ждет модуль
__builtins__ с функцией
eval.
Вообще, при эксплуатации SSTI-подобных уязвимостей в питоне полезно помнить о существовании свойства
__globals__ у всех питоновских функций (кроме встроенных). Если в вашем окружении нет функций, а только объекты — не беда, найдите у него любой метод и возьмите свойство
__func__. Вы получите unbound функцию, у которой уже будет
__globals__.
Обсуждение 0
Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.
Обсудить в Telegram