Python安全 - CTF培训¶
By HnuSec https://www.bx33661.com/blog/z8x9w23/
课程介绍¶
🎯 课程目标¶
本课程旨在帮助同学们从0开始,了解和掌握 Python 在 Web 安全与 CTF 竞赛中的核心安全知识与攻防技巧。
学习过程中,将通过实战案例、漏洞原理解析、CTF 题目演练等方式,掌握以下能力:
- 理解 Python 语言自身的特性与潜在安全隐患;
- 掌握常见的 Python 安全漏洞类型及其利用方式;
- 了解 Python Web 开发常见风险点(如模板注入、反序列化等);
- 掌握 CTF 中出现频率较高的 Python 安全题型的解题思路;
- 培养安全意识与防御思维,提升代码审计能力。
🛠️ 0. 环境准备与依赖安装¶
为了更高效地参与本课程的学习与实战演练,请大家在课前完成以下环境准备和基础知识补充:
建议使用 本地 Linux / WSL / 虚拟机环境
本课程推荐使用 Miniconda 来创建隔离的 Python 学习环境,避免污染全局依赖。
✅ 创建并激活课程环境:¶
1 2 |
|
或者是
- ✅ 安装软件/工具:
- Python 3.8+(建议使用 pyenv 管理多个版本)
- pip / pipx
- Git
- 常用编辑器:VSCode,Pycharm 等等
- Burp Suite(用于 Web 安全测试)
requests、flask、jinja2 等基础库
1 |
|
📌建议统一使用 Python 虚拟环境(如 venv
或 virtualenv
)管理依赖。
小 demo¶
为了更好理解整个流程,大家熟悉整个漏洞复现,漏洞利用,环境搭建的整个过程
vulhub/gradio/CVE-2024-1561 at master · vulhub/vulhub
大家可以参考这个 vulhub 靶场去复现一下 CVE-2024-1561 漏洞
具体复现细节见
写了一个小小流程示例,没有具体代码分析,为的就是会利用,知道流程
Python 应用¶
Python 脚本演示¶
Python 在 CTF 中比赛中是脚本的主要实现语言
爆破密码登录账号的例子
flask 简单登录逻辑实现
1 2 3 4 5 6 7 8 9 10 11 12 |
|
爆破脚本如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
最后响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Python 的特性¶
一切皆对象¶
- 基本类型如
int
,str
,list
,function
,module
都是对象。 - 每个对象都可以访问其类(
__class__
)与继承链(__mro__
)等元信息。
这部分重点看 SSTI 中演示
高度动态的运行环境(Dynamic Execution)¶
- 支持运行时执行字符串:
eval()
、exec()
、compile()
- 可以动态导入模块:
__import__('os')
📌 在漏洞中可能被滥用:
1 2 |
|
攻击者可通过构造对象链访问
eval
、os.system
、__import__
等功能函数
这里介绍一下 Python 的“危险函数”
函数 | 功能 | 返回值 | 风险等级 | 常见于攻击场景 |
---|---|---|---|---|
eval() | 执行表达式 | 返回结果 | 🔥🔥🔥 | SSTI、反序列化、Webshell |
exec() | 执行语句代码块 | 无返回 | 🔥🔥🔥🔥 | 模板注入、反射创建对象 |
compile() | 将字符串编译为代码对象 | 代码对象 | 🔥 | 高级动态执行 |
__import__() | 动态导入模块 | 模块对象 | 🔥🔥🔥 | 绕过检测、命令执行 |
os.system() | 执行系统命令(无回显) | 返回码 | 🔥🔥🔥 | Webshell、SSTI |
subprocess.*() | 执行系统命令(可捕获输出) | 输出/状态码 | 🔥🔥🔥🔥 | 高级RCE、文件读写、持久化 |
input() (Py2) | 动态输入执行 | 用户输入 | 🔥🔥 | Python2特有漏洞点 |
📌 1. eval(expr)¶
- 功能: 执行字符串表达式,并返回结果。
- 语法:
eval("1 + 2") → 3
- 本质: 执行表达式(Expression),返回值。
⚠️ 危险性:高
- 若拼接用户输入,极易被注入执行恶意代码。
- 常见于模板注入、命令注入、Webshell。
🧪 利用示例:
1 |
|
📌 2. exec(code)¶
- 功能: 执行一段代码(可包含多行、语句块)。
- 语法:
1 |
|
- 本质: 执行语句(Statement),无返回值。
⚠️ 危险性:极高
- 可动态创建变量、函数、类,甚至修改上下文环境。
- 比
eval
更强大、也更危险。
🧪 攻击示例:
1 |
|
📌 3. compile(source, filename, mode)¶
- 功能: 将字符串编译成可执行代码对象。
- 常配合 eval/exec 使用。
- mode:
"eval"
/"exec"
/"single"
🧪 例子:
1 2 |
|
⚠️ 危险性:中
- 本身不执行,但常用于构建动态代码流程。
📌 4. import('modulename')¶
- 功能: 动态导入模块,相当于
import modulename
- 在安全漏洞中可用于:
- 绕过静态分析工具
- 动态调用系统模块
🧪 例子:
1 2 |
|
⚠️ 危险性:高
- 通常与
eval()
、getattr()
等组合使用,从用户输入导入任意模块。
📌 5. os.system(cmd)¶
- 功能: 调用系统 shell 执行命令(平台相关)
- 返回值: Shell 的退出码(不是命令输出)
🧪 例子:
1 2 |
|
⚠️ 危险性:高
- 执行命令无回显,适合静默攻击。
- 容易造成远程命令执行(RCE)。
📌 6. subprocess 系列(推荐攻击者使用)¶
- 比
os.system
更强大,可获取命令输出。
1 2 |
|
其他变种:
subprocess.call()
subprocess.run()
subprocess.Popen()
⚠️ 危险性:极高
- 支持输入输出控制、环境变量控制,利于构造复杂攻击链。
📌 7. input()¶
- Python 2 中
input()
相当于eval(raw_input())
- 可造成代码执行(已废弃)
1 2 3 |
|
🏗️ SSTI 漏洞了解¶
“一次模板、一条语句、一条命令。”
什么是 SSTI?¶
术语 | 全称 | 定义 |
---|---|---|
SSTI | Server-Side Template Injection | 用户输入被直接拼接到服务器模板代码中,未经转义或沙箱隔离,导致模板引擎解析并执行攻击者可控的表达式。 |
- 本质:模板→数据替换 的过程被逆转:
数据(用户可控)→ 模板语法 → 引擎解析 → 代码执行(RCE)。
什么是模板,如何理解模板¶
模板就是一段带有占位符的字符串,模板引擎会用实际数据替换这些占位符,然后生成最终的 HTML 页面或文本内容。
举个例子(以 Jinja2 为例):
1 |
|
如果变量 name = "bx"
,那么模板引擎渲染后会输出:
1 |
|
How to Work?
- 模板文件
- 传入数据
- 模板引擎渲染
- 输出内容
比如在 Flask 中使用 Jinja2:
1 2 3 4 5 |
|
对应模板:
1 |
|
渲染后浏览器看到的是:
1 |
|
漏洞形成流程图
模板引擎速查表与语法指纹
语言 | 常见引擎 | 识别语法 | 快速 PoC |
---|---|---|---|
Python | Jinja2 / Mako | {{7*7}} → 49 | {{ ''.__class__.__mro__[1].__subclasses__()[...] |
PHP | Twig / Smarty | {{7*7}} / {{$smarty} | {{_self.env.setCacheDir("/tmp")}} |
Java | FreeMarker | ${7*7} | ${"freemarker.template.utility.Execute"?new()("id")} |
Node.js | Nunjucks / EJS | <%= 7*7 %> | {{range.constructor("return process.mainModule.require('child_process').execSync('id')")()}} |
Jinja2 经典利用链(含命令执行)¶
以 Python + Flask(Jinja2)为示例
基本信息泄露
1 |
|
RCE(Python3 链)
1 |
|
最通用的 os.popen 链
1 |
|
Stage | Explanation |
---|---|
self | Jinja2 内建对象 |
.__init__ | ⇒ 函数对象 |
.__globals__ | ⇒ 全局命名空间 |
.__builtins__.os | 获得 os 模块 |
popen | ⇒ RCE |
漏洞检测¶
漏洞检测
测试点 | 操作 | 现象 |
---|---|---|
数学表达式 | {{7*7}} | 输出 49 或异常 |
报错信息 | {{7/0}} | 泄露模板引擎类型、源码路径 |
对象链 | {{ ''.__class__ }} | 返回 <class 'str'> 等 |
手段--手工¶
常见姿势
- URL 参数
1 |
|
- 表单字段
1 |
|
- Cookie 注入
1 |
|
- HTTP 头部注入
1 |
|
自动化工具¶
- Fenjing(这个推荐大家多看看)
- 用于检测 Flask/Jinja2 等模板引擎的 SSTI 漏洞
- 支持对 GET、POST 请求的 fuzz 测试
-
可自定义 payload 模板进行批量注入测试
-
Tplmap
- 支持多种模板引擎(Jinja2, Twig, Velocity, Smarty 等)
- 自动化识别模板引擎类型,并尝试执行命令
-
可用于本地调试模板注入链路
-
BurpSuite 插件
结合 bp 自动化测试
....
防御与修复¶
措施 | 示例 |
---|---|
沙箱 + 白名单 | Jinja2 SandboxedEnvironment |
纯数据注入 | 用 {{ user.name }} 而非 {{ user }} |
模板分隔符转义 | 替换 {{ 、{% 为 {[{ 、HTML entity |
严格输出编码 | `{{ user.comment |
禁止危险 globals | 禁掉 __builtins__ 、__import__ 、open |
课堂演示¶
一个 flask 随便起的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
实战演练靶场¶
可以具体看一下
- NSSCTF-web 部分
- BUUCTF-web 部分
- Damn Vulnerable Web Application - DVWA
- PortSwigger Labs - 「Server-side template injection」章节
https://portswigger.net/web-security/all-topics
- Hack The Box - 「Jeeves」靶机
SSTI 深入学习¶
Python 链子介绍¶
:::info Python-万物皆对象
:::
1 2 3 4 |
|
绕过¶
基类
1 2 3 |
|
.
被ban
1 2 |
|
利用这两种方法
1 2 3 4 |
|
_
被ban
1 2 3 4 |
|
赋值方法:
这个主要用于单双引号被ban的情况
request.args.x
,传递get参数request.cookies.x
,=传递cookie参数request.values.x
,传递post参数
花括号{}被ban:
在jinjia引擎中可以使用{% %}
1 |
|
编码
1 |
|
贴一个脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
直接方法
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
...
还有很多很多
题目实战¶
NSSCTF--[HNCTF 2022 WEEK2]ez_SSTI¶
- 手工
Payload:
1 |
|
我看了一下app.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
- 利用工具--fenjing
[安洵杯 2020]Normal SSTI¶
- 使用Fenjing
[HNCTF 2022 WEEK3]ssssti¶
- 使用使用Fenjing
CTFSHOW----web361¶
手工¶
1 2 3 4 5 6 |
|
打开文件
1 |
|
使用Tplmap¶
1 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
参考文章&学习资料¶
- HelloCTF
https://hello-ctf.com/hc-web/ssti/
- 跳跳糖社区
其他知识¶
这部分就是比较零碎的了
Python 版本切换¶
这里介绍一下 Pyenv 工具
只说明一下具体命令
安装 Python 版本
1 2 |
|
列出可用版本:
1 |
|
🔁 设置版本
- 设置全局默认版本:
1 |
|
- 设置当前 shell 会话使用的版本:
1 |
|
- 设置某个项目目录的版本(会创建
**.python-version**
文件):
1 |
|
查看当前使用的版本
1 2 |
|
flask-session 伪造问题¶
对于 flask 框架的深入
Flask之session伪造 - FreeBuf网络安全行业门户
GitHub - noraj/flask-session-cookie-manager: Flask Session Cookie Decoder/Encoder
Python 内存马问题¶
...
📚 Python 安全内容¶
本课程内容覆盖基础、漏洞原理、高级利用与 CTF 实战四大模块,具体包括:
- ✅ Python语言基础与安全特性
- 数据类型与作用域
eval
/exec
等内置函数风险- 动态执行与类型转换陷阱
- ✅ Python高级特性与安全隐患
- 反射机制与魔术方法
__import__
与模块滥用- introspection(自省)与代码注入
- ✅ Python内存管理与安全
- 引用计数与垃圾回收机制
- 内存泄漏、对象生命周期与漏洞场景
- ✅ Python并发编程与安全
threading
,multiprocessing
,asyncio
- 线程安全问题与共享资源管理
- ✅ 常见的Python应用场景与安全风险
- Web 后端 / 脚本自动化 / 数据处理中的误用问题
- 风险案例解析:权限绕过、命令注入、信息泄露等
- ✅ SSTI(服务器端模板注入)
- 常见模板引擎:Jinja2、Tornado Templates
- Payload 构造与远程命令执行
- ✅ Python反序列化漏洞
pickle
/marshal
/yaml
等模块的风险对比- CTF中基于
pickle.loads()
的利用技巧
- ✅ Python沙箱逃逸
- 沙箱设计思路与常见绕过点
- 动态代码执行限制的逃逸方法
- ✅ Python原型链污染(Prototype Pollution)
- 类属性注入与动态对象污染
- Python 与 JS 中该漏洞的对比解析
- ✅ Python Web框架安全问题
- Flask / Django 的配置与路由漏洞
- Session伪造、调试模式RCE、静态文件绕过
- ✅ CTF中的Python安全挑战
- 沙箱题、模板注入题、反序列化题
- 解题技巧:构造Payload、源代码审计、黑盒分析等
- ✅ 总结与防御措施
- Python安全编码规范
- 常用静态/动态审计工具(如 Bandit、pylint、pyre-check 等)
- 安全开发生命周期与持续集成中的防御机制