Flask SSTI 利用方式探索
Flask SSTI 利用方式探索
python 语言基础
在 python 中,object 类是 Python 中所有类的基类,如果定义一个类时没有指定继承哪个类,则默认继承 object 类。 每个类都有的魔术变量 __class__
,表示当前类。
|
|
每个类都有一个 __base__
属性,列出其基类:
列出所有基类:__bases__
列举类的调用顺序:__mro__
获取子类集合:''.__class__.__mro__[1].__subclasses__()
接下来寻找可以执行命令的子类:os._wrap_close(133)
查找可使用的变量和方法:"".__class__.__mro__[1].__subclasses__()[133].__init__.__globals__
执行系统命令:"".__class__.__mro__[1].__subclasses__()[133].__init__.__globals__['popen']('ls').read()
读取文件内容:"".__class__.__mro__[1].__subclasses__()[133].__init__.__globals__["__builtins__"]["open"]("flag.txt").read()
SSTI 简介 & 环境搭建
模板
一个统一风格的站点,其大多数页面样式都是一致的,只是每个页面显示的内容各不相同。要是所有的逻辑都放在前端进行,无疑会影响响应效果和效率,很不现实。把所有的逻辑放在后端,又会导致太过复杂,前轻后重
模板的诞生是为了将显示与数据分离,让前端工作人员专注表现设计,后台人员注重业务逻辑,同时简化代码的复杂程度。模板技术多种多样,但其本质是将模板文件和数据通过模板引擎生成最终的HTML代码。
Flask
使用 Jinja2
作为模板引擎,Jinja
的语法很简单,大致有这么几种:
|
|
SSTI
在 SSTI 漏洞点中,{{x}} 里面的内容会被执行。
SSTI,又称服务端模板注入攻击
。jinja2 模板中使用 {}
语法表示一个变量,它是一种特殊的占位符。当利用 jinja2 进行渲染的时候,它会把这些特殊的占位符进行填充/替换。但是在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而可能导致了敏感信息泄露
、代码执行
、 GetShell
等问题
环境搭建
测试环境搭建:Ubuntu + Docker
环境:
https://github.com/Tiaonmmn/pasecactf_2019_web_honey_shop
敏感信息泄露导致身份伪造
flask session 机制
通过.
隔开的 3 段内容,第一段其实就是 base64encode 后的内容,但去掉了填充用的等号,若 decode 失败,自己需要补上 1-3 个等号补全。中间内容为时间戳,在 flask 中时间戳若超过 31 天则视为无效。最后一段则是安全签名,将 session data
,时间戳
和 flask
的 secretkey
通过 sha1
运算的结果。
方法一
该应用在 /hello
下存在 SSTI
漏洞:
config
下泄露了 SECRET_KEY
:
使用 flask-unsign
工具(使用 pip
安装)伪造 Cookie:
|
|
方法二
http://127.0.0.1:8345/download?image=1.jpg
存在任意文件下载漏洞,下载环境变量文件:
http://127.0.0.1:8345/download?image=../../../../../../../../../proc/self/environ
Flask PIN 码利用
Flask PIN 码
Flask Debug 应用在模式下提供的一种页面端的交互调试工具,和我们平时使用的 Python 命令行是一样的,也就是给我们提供了一个交互式的 web 端 shell。但是 PIN 码的生成规则是有规律可循的,使得获取 PIN 码成为可能,之后能够利用的方式有很多。
|
|
脚本中 6 个参数的获取方法:
username
运行 flask 的用户,之前读取 /etc/passwd
获取
modname
一般默认即可
app name
一般默认即可
路径
debug 下报错
网络地址
读取:/sys/class/net/eth0/address
|
|
机器码
读取:/etc/machine-id
或者 /proc/self/cgroup
执行脚本
SSTI 导致 RCE
代码执行
|
|
python 魔法函数 + 内置函数
魔法函数
所谓魔法函数(Magic Methods),是 Python 的一种高级语法,允许你在类中自定义函数(函数名格式一般为 __x__
),并绑定到类的特殊方法中。比如在类 A 中自定义 __str__
函数,则在调用 str(A)
时,会自动调用 __str__
函数,并返回相应的结果。在我们平时的使用中,可能经常使用 __init__
函数和 __del__
函数,其实这也是魔法函数的一种。
内置函数
在 python 中输入 help(__builtins__)
,可以查看帮助,简单地说就是 Python 中自带的函数
|
|