一、HTTP/HTTPS 协议详解
1. HTTP协议基础
什么是 HTTP?
HTTP(HyperText Transfer Protocol)是互联网中浏览器和服务器之间传输数据的协议,基于请求-响应模式。它是一个无状态协议,意思是每次请求都是独立的,服务器不会记住之前的请求状态。
HTTP 工作模式
-
客户端(浏览器、爬虫等)发起请求
-
服务器接收请求,处理后返回响应
-
双方通过TCP连接(通常是80端口)进行通信
2. HTTP 请求结构
HTTP 请求由四部分组成:
bash
请求行(Request Line)
请求头(Request Headers)
空行
请求体(Request Body,可选)
1)请求行
格式:
bash
METHOD URL HTTP/VERSION
-
METHOD :请求方法,如
GET
、POST
、PUT
、DELETE
等 -
URL:请求的资源路径和参数
-
HTTP/VERSION :HTTP版本,如
HTTP/1.1
示例:
bash
GET /index.html HTTP/1.1
2)请求头
键值对格式,告知服务器客户端信息:
-
Host
: 必须,目标服务器域名和端口 -
User-Agent
: 客户端软件信息 -
Accept
: 可接受的数据格式 -
Cookie
: 浏览器存储的Cookie信息 -
Content-Type
: 请求体类型(POST/PUT) -
Content-Length
: 请求体大小(字节)
示例:
bash
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
Cookie: sessionid=abc123
3)空行
请求头和请求体之间必须有一个空行。
4)请求体
-
只有部分请求方法(如POST、PUT)有请求体
-
通常携带提交的数据,如表单、JSON、文件等
3. HTTP 响应结构
HTTP 响应由四部分组成:
bash
状态行(Status Line)
响应头(Response Headers)
空行
响应体(Response Body)
1)状态行
格式:
bash
HTTP/VERSION STATUS_CODE REASON_PHRASE
-
STATUS_CODE:三位数字,表示请求状态
-
REASON_PHRASE:简短描述状态码
示例:
bash
HTTP/1.1 200 OK
2)响应头
描述响应的元数据:
-
Content-Type
: 响应体格式和编码 -
Content-Length
: 响应体大小 -
Set-Cookie
: 设置Cookie -
Cache-Control
: 缓存策略 -
Server
: 服务器信息
示例:
bash
Content-Type: text/html; charset=UTF-8
Content-Length: 1024
Set-Cookie: sessionid=abc123; HttpOnly
Cache-Control: no-cache
3)空行
响应头和响应体之间必须有空行。
4)响应体
服务器返回的实际数据,比如HTML页面、JSON、图片等。
4. HTTP 状态码详解
状态码反映服务器对请求的处理结果,按首位数字分类:
类别 | 代码范围 | 描述 | 说明 |
---|---|---|---|
1xx | 100-199 | 信息性状态码 | 请求已接收,继续处理 |
2xx | 200-299 | 成功 | 请求成功完成 |
3xx | 300-399 | 重定向 | 需要客户端进一步操作,如跳转 |
4xx | 400-499 | 客户端错误 | 请求有错误,如参数不合法、未授权等 |
5xx | 500-599 | 服务器错误 | 服务器处理请求时发生错误 |
常见状态码示例
状态码 | 含义 |
---|---|
200 | OK --- 请求成功 |
201 | Created --- 资源成功创建 |
301 | Moved Permanently --- 永久重定向 |
302 | Found --- 临时重定向 |
304 | Not Modified --- 资源未修改,使用缓存 |
400 | Bad Request --- 请求格式错误 |
401 | Unauthorized --- 未认证 |
403 | Forbidden --- 禁止访问 |
404 | Not Found --- 资源未找到 |
500 | Internal Server Error --- 服务器错误 |
503 | Service Unavailable --- 服务不可用 |
5. HTTP工作流程
-
客户端发起 TCP 连接,通常连接到服务器的 80 端口
-
发送 HTTP 请求
-
服务器处理请求并返回 HTTP 响应
-
客户端解析响应,根据响应状态执行后续操作
-
根据 Connection 头是否为 keep-alive 决定是否关闭连接
6. HTTPS协议详解
HTTPS 是什么?
HTTPS 是在 HTTP 之上增加了 SSL/TLS 加密层的安全协议,主要解决 HTTP 明文传输导致的信息泄露和篡改问题。
HTTPS 端口
默认端口是 443。
HTTPS 工作流程(简化版)
-
客户端发起 HTTPS 连接请求
-
服务器返回数字证书(包含公钥)
-
客户端验证证书(是否由可信CA签发、是否过期、域名是否匹配)
-
客户端生成对称密钥,用服务器公钥加密后发给服务器
-
服务器用私钥解密得到对称密钥
-
双方使用对称密钥加密通信数据
HTTPS 特点
-
加密通信:保护数据不被窃听
-
身份认证:防止伪造服务器
-
数据完整性:防止数据被篡改
-
防止中间人攻击
总结
内容 | 说明 |
---|---|
HTTP 请求 | 请求行 + 请求头 + 空行 + 请求体(可选) |
HTTP 响应 | 状态行 + 响应头 + 空行 + 响应体 |
状态码 | 1xx信息,2xx成功,3xx重定向,4xx客户端错,5xx服务器错 |
HTTPS | HTTP + SSL/TLS加密 |
HTTPS 工作流程 | 证书交换、密钥协商、加密通信 |
二、Cookie 详解
Cookie 是服务器通过 HTTP 响应头 Set-Cookie
向客户端(浏览器)写入的一段小型数据,浏览器会在下一次请求时自动将它附带在请求头 Cookie
中发送给服务器,用于状态保持。
Cookie 具有以下特性:
-
每个 Cookie 大小不超过 4KB
-
同一域名下最多存储 20 个 Cookie(浏览器不同略有差异)
-
自动附带到相同域名的每次请求中
1. Cookie 的基本结构
Set-Cookie 响应头格式:
bash
Set-Cookie: name=value; Path=/; Expires=Wed, 01 Jan 2025 00:00:00 GMT; HttpOnly; Secure; SameSite=Strict
常见属性详解:
属性 | 说明 |
---|---|
name=value |
键值对数据 |
Expires |
过期时间(绝对时间) |
Max-Age |
存活时间(秒,优先于 Expires) |
Path |
限制在哪些路径下 Cookie 会被发送 |
Domain |
可跨子域访问的设置,如 .example.com |
Secure |
仅在 HTTPS 连接下才发送 |
HttpOnly |
JS 不能访问,防止 XSS 盗取 |
SameSite |
控制跨站请求时是否发送(Strict / Lax / None) |
2. Cookie 的作用
状态保持(Session 管理)
-
登录状态:如
sessionid=abc123
-
用户偏好:如
lang=zh-CN
-
购物车:记录加入商品的 ID
追踪用户行为
-
统计页面访问、点击行为
-
第三方广告 Cookie(如 Google Analytics)
3. Cookie 生命周期
会话 Cookie(Session Cookie)
-
不设置
Expires
或Max-Age
-
浏览器关闭后自动失效
持久 Cookie(Persistent Cookie)
-
设置了
Expires
或Max-Age
-
即使关闭浏览器,指定时间内依然有效
4. Cookie 的安全问题
1)XSS 攻击(跨站脚本)盗取 Cookie
攻击者通过注入恶意 JS 代码,调用 document.cookie
读取用户 Cookie 并发送给远程服务器。
防御:
-
设置
HttpOnly
,防止 JS 访问 Cookie -
对用户输入进行严格过滤或转义
2)CSRF 攻击(跨站请求伪造)
利用用户浏览器已存的 Cookie 向目标网站发起伪造请求,如提交表单、转账等。
防御:
-
设置
SameSite=Strict
或Lax
-
使用 CSRF Token 验证来源合法性
3)Cookie 劫持
如果用户在 HTTP 下传输 Cookie,攻击者可以使用中间人攻击(MITM)截获 Cookie。
防御:
-
设置
Secure
属性,只允许 HTTPS 传输 -
使用 HTTPS 加密所有通信
4)Cookie 固定攻击(Session Fixation)
攻击者提前设置用户 Cookie,诱导用户使用该 Cookie 登录,从而复用 Session。
防御:
-
登录成功后重新生成 Cookie / Session ID
-
拒绝来源不明的 Session Cookie
5. Cookie 示例(请求 + 响应)
服务端响应设置 Cookie:
bash
HTTP/1.1 200 OK
Set-Cookie: sessionid=abc123; HttpOnly; Secure; SameSite=Strict
浏览器下一次请求自动携带 Cookie:
bash
GET /user/profile HTTP/1.1
Host: example.com
Cookie: sessionid=abc123
6. Cookie 与浏览器 JS 操作
javascript
// 读取
console.log(document.cookie); // name=value; another=123
// 设置
document.cookie = "token=xyz456; path=/; max-age=3600";
// 删除(设置过期)
document.cookie = "token=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
注意:如果设置了 HttpOnly
,JavaScript 是无法访问该 Cookie 的。
7. Cookie 与跨域
Cookie 默认 不跨域,但有策略支持:
-
前提是设置了
Access-Control-Allow-Credentials: true
-
客户端请求必须使用
withCredentials: true
-
Cookie 的
Domain
设置为顶级域名(如.example.com
)
总结
属性 | 用途 | 是否可防攻击 |
---|---|---|
HttpOnly |
禁止 JS 访问 | 防止 XSS |
Secure |
只在 HTTPS 传输 | 防止 MITM |
SameSite |
跨站请求限制 | 防止 CSRF |
Expires |
控制 Cookie 失效时间 | 控制生命周期 |
Domain |
控制子域可访问 | 易被滥用,小心设置 |
三、Session详解
Session
是服务器端用于 记录客户端状态 的一种机制。它解决了 HTTP 协议无状态的问题(服务器无法记住每个用户是谁)。
客户端登录后,服务器生成一个 Session ID
,用于标识当前会话,并将它保存在服务端,同时通过 Cookie
发给客户端。客户端每次请求时携带这个 Session ID
,服务器就能识别该用户是谁。
1. Session 的工作流程
bash
[客户端] ------ 登录请求 ------> [服务端]
<------ Set-Cookie: sessionid=abc123 ------
[客户端] ------ 后续请求(带 Cookie) ------> [服务端]
查找 sessionid=abc123 对应的用户状态
示例流程:
-
用户第一次访问网站,服务端创建一个新的 Session,生成一个唯一的
sessionid
-
服务器通过
Set-Cookie
把sessionid
设置到客户端浏览器中 -
之后客户端请求中都会自动携带
Cookie: sessionid=xxx
-
服务端根据
sessionid
在内存/数据库中查找用户的会话信息(如登录状态、用户名等)
2. Session 与 Cookie 的区别
项目 | Cookie | Session |
---|---|---|
存储位置 | 客户端浏览器 | 服务端内存、数据库、Redis 等 |
安全性 | 较低,易被盗用 | 较高,不暴露用户数据,仅暴露 ID |
容量限制 | 每个 Cookie 最大约 4KB | 较大,可存储任意复杂结构 |
生命周期 | 设置 Expires/Max-Age 控制 | 通常存在内存中,浏览器关闭或过期失效 |
易用性 | 无需服务器端资源 | 需要服务器维护 Session 状态 |
3. Session 存储机制
Session 本质是一个 Key-Value
结构:
-
Key 是
sessionid
(保存在客户端 Cookie 中) -
Value 是服务端保存的用户状态信息(保存在服务器)
Session 数据的存储方式常见如下:
存储方式 | 特点 |
---|---|
内存(默认) | 简单、速度快,重启丢失,不可扩展 |
文件 | 存在磁盘,可持久,速度较慢 |
数据库 | 可持久、易管理,性能中等 |
Redis | 高性能分布式,适合高并发场景 |
4. Session 生命周期
-
默认有效期:浏览器关闭时失效,或服务端设定超时时间(如 30 分钟)
-
设置方式(以 PHP 为例):
php
ini_set('session.gc_maxlifetime', 3600); // 设置有效期 1 小时
session_start();
5. Session 安全问题与攻击方式
1)Session Fixation(固定会话攻击)
攻击者诱导用户使用事先构造的 sessionid
,然后服务器将其绑定为合法 Session。
举例:
bash
http://example.com/login?PHPSESSID=abc123
用户点击后登录,攻击者就可以使用相同 Session ID 登录。
防御:
-
登录成功后强制重新生成 Session ID
-
拒绝 URL 中传递 Session ID(禁止 SID)
-
设置
HttpOnly
,禁用 JS 操作 Cookie
2)Session Hijacking(劫持)
攻击者通过 XSS、流量嗅探、恶意扩展等手段获取用户的 sessionid
,然后伪造请求。
防御:
-
使用
Secure + HttpOnly
属性保护 Cookie -
全站强制 HTTPS,防止中间人窃取
-
Session ID 绑定用户 UA/IP,防止伪造
3)会话过期攻击
用户长时间不操作,Session 被销毁,攻击者在这个时间发起请求。
防御:
-
设置合理的 Session 过期时间
-
登录前置验证 + Session 管理机制
6. 常见 Session 实现方式
PHP
php
session_start(); // 启动 Session
$_SESSION['user'] = 'admin';
Cookie 自动设置:
bash
Set-Cookie: PHPSESSID=abc123; path=/; HttpOnly
Python Flask
python
from flask import session
session['user'] = 'admin'
默认使用 Cookie 存储(可配置为 Redis 等)
Java Servlet
java
HttpSession session = request.getSession();
session.setAttribute("user", "admin");
默认使用 JSESSIONID 来标识会话
bash
Set-Cookie: JSESSIONID=abc123; Path=/; HttpOnly
7. Session 的高级安全控制
1)Session ID 强度
-
应该使用高熵的随机值生成(如 UUID、SHA256 随机串)
-
不要使用简单自增或可预测字符串
2)Session ID 绑定策略
绑定到以下信息可防止伪造:
-
User-Agent(浏览器指纹)
-
IP 地址(不建议绑定完整 IP,可绑定前几段)
8. Session 与 Token 的区别
项目 | Session | Token(如 JWT) |
---|---|---|
存储 | 服务端 | 客户端本地 |
状态 | 有状态(服务端维护会话) | 无状态(不需要存储) |
性能 | 占用内存,扩展差 | 适合分布式,多终端场景 |
安全性 | 受控于服务端,泄漏风险低 | 需要加密签名验证,防止伪造 |
总结
核心要素 | 内容 |
---|---|
Session 本质 | 用于服务端保存用户状态,配合 Cookie 识别身份 |
Cookie 作用 | 存储 sessionid,标识用户是谁 |
安全关键点 | HttpOnly、Secure、SameSite、重新生成 ID、防 Fixation |
攻击方式 | Fixation、Hijacking、XSS、CSRF |
防御方法 | 绑定信息、使用 HTTPS、短期有效期、验证来源 |
四、Token详解
Token (令牌)是一种服务端生成的字符串,用于客户端访问受保护资源时 标识身份 的认证机制。
Token 是为了解决传统 Session 需要在服务器维护用户状态的问题(即"有状态认证"),而引入的 无状态认证方式,广泛用于:
-
Web 前后端分离项目
-
移动端、APP 登录认证
-
分布式认证(单点登录)
1. Token 的工作流程(认证机制)
bash
[客户端] ------ 登录 ------> [服务端]
<------ 返回 Token ------
[客户端] ------ 后续请求(携带 Token) ------> [服务端]
验证 Token 合法性,返回数据
常见传输方式:
请求头方式(推荐):
bash
Authorization: Bearer <token>
URL 参数:
bash
GET /api/user?token=abc123
请求体(POST JSON)中提交:
bash
{ "token": "abc123" }
2. Token 的种类
1)自定义 Token(普通随机串)
-
结构简单:如
abc123xyz456
-
存在 Redis、数据库中,和 Session 类似
-
每次请求服务器查一次数据库,验证合法性
2)JWT(JSON Web Token)
-
无需数据库查找,使用签名校验即可
-
常用于分布式认证、前后端分离系统
3. JWT 的结构
bash
xxxxx.yyyyy.zzzzz
由三部分组成,每部分使用 Base64 编码:
部分 | 内容 | 示例 |
---|---|---|
Header | 令牌类型 + 签名算法 | { "alg": "HS256", "typ": "JWT" } |
Payload | 载荷(用户信息) | { "uid": 1001, "role": "admin" } |
Signature | 签名(防篡改) | HMAC_SHA256(header + payload + 密钥) |
举例:
javascript
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. // Header
eyJ1aWQiOjEsInJvbGUiOiJhZG1pbiJ9. // Payload
Abcdefghijklmnopqrstuvwxyz123456 // Signature
4. Token 与 Session 的区别
项目 | Session | Token(JWT) |
---|---|---|
存储方式 | 服务器内存、数据库 | 客户端本地(无状态) |
标识机制 | sessionid + 服务端状态记录 | Token 自带用户信息 + 签名验证 |
性能 | 服务端需查状态,横向扩展差 | 不依赖服务端状态,易于分布式部署 |
安全性 | 不泄漏用户信息,服务端控制较强 | 用户信息直接暴露在 Payload 中 |
可控性 | 服务端可手动销毁、修改 | 一旦发出不可撤销,需设置过期时间 |
5. Token 的优点与缺点
优点:
-
无需服务端保存状态(节省资源)
-
可跨服务、跨平台共享身份(如 SSO 单点登录)
-
不依赖 Cookie,可用于移动端、App
缺点:
-
无法主动失效(Token 发出后无法收回)
-
信息容易泄漏(Payload 明文,需加密敏感字段)
-
体积大于 Session ID,占带宽
6. Token 的存储方式
存储方式 | 说明 |
---|---|
LocalStorage | 持久性强,但易被 XSS 攻击 |
SessionStorage | 浏览器关闭即清除,安全略高 |
Cookie | 可配合 HttpOnly + Secure 提升安全 |
7. Token 的安全问题与攻击方式
1)Token 泄漏(XSS、日志暴露)
-
Token 通常保存在浏览器中,若存在 XSS 漏洞,攻击者可轻松获取
-
URL 中传递 Token 可能被日志、代理服务器记录
防御:
-
Token 不出现在 URL,推荐放在 Header
-
存储 Token 时避免使用
localStorage
(推荐 HttpOnly Cookie) -
前端防 XSS:严格 CSP + DOM 过滤
2)Token 伪造
- 攻击者尝试伪造 JWT,绕过认证
防御:
-
使用强加密算法(如 HMAC-SHA256)
-
严格保管密钥,不应泄漏服务端密钥
3)Token 重放攻击(Replay)
- 攻击者截获合法请求 Token 后,在有效期内重复使用
防御:
-
Token 设置短有效期(如 5 分钟)
-
配合
一次性 Token / RefreshToken
机制
8. Token 与 Refresh Token 机制
由于 Token 不可撤销,推荐使用双 Token 机制:
类型 | 用途 |
---|---|
Access Token | 有效期短,用于请求接口 |
Refresh Token | 有效期长,用于换取新 Token |
流程:
bash
[登录] ------> [发出 access_token + refresh_token]
[请求资源] ------> 附带 access_token
|
└──[过期]------> 用 refresh_token 换新的 access_token
9. 实战示例:使用 JWT 验证身份
前端请求:
bash
POST /login
Content-Type: application/json
{
"username": "admin",
"password": "123456"
}
服务端返回:
bash
{
"token": "eyJhbGciOiJIUzI1NiIsInR5c..."
}
后续请求附带:
bash
GET /user/info
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5c...
服务端用密钥验证 Token 签名,读取其中的 Payload 信息,判断用户身份。
10. Token 示例分析(JWT 解码)
示例 JWT:
bash
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1aWQiOjEsInJvbGUiOiJhZG1pbiIsImV4cCI6MTY5ODQzMjAwMH0.
t7I8mVYuqxPhA5KXZMQzN2gUe9eWYmN2coHo5cVdE2g
解码 Payload 得到:
bash
{
"uid": 1,
"role": "admin",
"exp": 1698432000
}
说明用户 ID 为 1,角色为 admin,有效期截止时间为某个时间戳(可用 Python/JS 解码)。
总结
要素 | 内容说明 |
---|---|
核心机制 | 客户端持有 Token,服务端验证签名,无需状态存储 |
推荐方案 | 使用 JWT + RefreshToken 实现安全、可扩展的认证机制 |
安全风险 | XSS、Token 泄漏、伪造、重放攻击等 |
防御策略 | HttpOnly Cookie / Token 加密 / 过期机制 / 加签验证 |
与 Session 区别 | Token 是无状态的,适合分布式系统;Session 依赖服务端存储 |
五、JWT 的机制与攻击方式
JWT 全称 JSON Web Token ,是一种 无状态的身份验证机制,主要用于前后端分离项目、移动端接口调用、单点登录(SSO)等。
它本质上是一个自包含的令牌,通过数字签名的方式防止篡改。
1. JWT 的结构(三段式)
格式如下:
bash
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEsInJvbGUiOiJhZG1pbiJ9.WfJ9oX7O1fFLjlR_pIRpZI...
由 Header.Payload.Signature
三部分组成,每部分使用 Base64 编码。
名称 | 内容类型 | 作用 |
---|---|---|
Header | 元数据(算法类型) | 指定加密算法,如 HS256 / RS256 |
Payload | 负载(用户信息) | 包含用户身份、权限、过期时间等 |
Signature | 签名(完整性验证) | 防止篡改,验证 Token 是否有效 |
2. JWT 签名机制(核心)
签名生成公式如下(以 HMAC-SHA256 为例):
bash
Signature = HMAC-SHA256(
base64url(Header) + "." + base64url(Payload),
secret_key
)
这个签名可以保证:
-
内容被篡改 → 签名校验失败
-
客户端不能伪造 Token(不知道密钥)
3. JWT 的使用流程
bash
[用户登录] → [生成 JWT] → 返回给前端
↓
[客户端] 持有 JWT 调用接口
↓
[服务器] 验证 JWT 的签名 → 读取 Payload → 允许访问
4. Payload 示例
bash
{
"uid": 123,
"username": "admin",
"role": "super_admin",
"exp": 1710000000 // 过期时间,Unix 时间戳
}
注意:
-
Payload 不能加密,默认是明文
-
不应放敏感数据(如密码、银行卡等)
5. JWT 攻击方式(黑客视角)
WT 是无状态的,一旦签发就无法撤销,如果存在配置问题或弱密钥,攻击者可以伪造/篡改 JWT。
常见攻击方式:
1)弱密钥爆破攻击(HS256)
- 当服务端使用对称加密(如
HS256
),如果密钥过于简单,如123456
,攻击者可以使用工具暴力爆破。
工具:
-
jwt-cracker
-
jwt_tool.py
bash
jwt_tool.py <token> -C -d /path/to/weak_passwords.txt
防御:
-
使用复杂不可预测的密钥(如 UUID + 高位随机)
-
使用非对称加密(RS256)
2)算法混淆攻击(alg: none)
有些服务端对 JWT 的 alg
字段没有做校验,如果用户将其修改为 "alg": "none"
,服务端就会跳过签名验证。
攻击方式:
篡改 Header 为:
bash
{ "alg": "none", "typ": "JWT" }
删除签名部分,提交伪造 Token。
防御:
-
拒绝
"alg": "none"
,显式验证签名算法 -
使用经过验证的 JWT 库
3)算法替换攻击(HS256 → RS256)
RS256 是非对称加密(公私钥),攻击者可以利用算法替换绕过验证。
攻击原理:
-
服务端使用 RS256,但攻击者将 alg 改为 HS256,并用"公钥"代替"密钥"来签名
-
如果服务端仍用公钥验证,会被成功验证签名
防御:
-
固定签名算法,不允许前端指定
alg
-
使用严格的验证库(如
PyJWT
,jsonwebtoken
)
4)Token 重放攻击
即攻击者截获某用户的合法 Token(通过 XSS、中间人攻击、URL 泄漏等方式),然后在有效期内重复使用。
防御:
-
使用 HTTPS 加密传输
-
设置短的有效期(
exp
) -
引入 Refresh Token + 滑动过期机制
-
绑定 IP / UA 检查
5)JWT 泄漏攻击
泄漏途径:
-
Token 存在 URL 中,容易被浏览器缓存、中间件记录
-
Token 存储在 localStorage,容易被 XSS 拿到
防御:
-
推荐使用 Cookie + HttpOnly + Secure 存储 JWT
-
避免在 URL 中传递 Token
-
启用 CSP、输入校验防 XSS
6. 渗透测试视角:JWT 检测点
在渗透测试/CTF 中,遇到 JWT 可以重点检查以下点:
检测点 | 说明 |
---|---|
alg 是否为 none | 是否能跳过签名验证 |
alg 能否替换为 HS256 | 能否使用公钥伪造签名 |
密钥是否可爆破 | 使用字典工具尝试爆破 |
payload 是否可控 | 是否能提权(role=admin) |
过期时间是否有效 | 是否能修改 exp 绕过校验 |
是否绑定 IP / UA | 是否可进行重放攻击 |
7. JWT 攻击实战:模拟提权攻击
1)抓取一段正常用户的 Token:
bash
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VyIjoiZ3Vlc3QiLCJyb2xlIjoiZ3Vlc3QifQ.
ZV1HG9mU_kPvEZfukOVsfAz1-r4PHiZ93KAjtz07Gb0
2)解码 Payload 并修改角色字段为:
bash
{ "user": "guest", "role": "admin" }
3)使用弱密钥爆破签名或尝试算法替换,重新生成 JWT。
4)用篡改后的 JWT 访问管理员接口,判断是否成功提权。
8. 防御最佳实践
措施 | 描述 |
---|---|
固定签名算法 | 不允许前端通过 Header 控制 alg |
不使用 none 算法 |
拒绝无签名 JWT |
使用非对称加密(RS256) | 避免密钥泄漏 |
设置 exp/iatt/nbf 等字段 | 控制有效期、拒绝过期 Token |
配置短有效期 + Refresh机制 | Access Token + Refresh Token 组合使用 |
使用 HttpOnly Cookie | 防止 JS 获取 Token(抗 XSS) |
输入过滤 + CSP | 防 XSS 攻击 |
9. 推荐工具 & 测试框架
工具名 | 用途 |
---|---|
jwt.io | 在线 JWT 解码/编码 |
jwt_tool.py | JWT 爆破、伪造、测试脚本工具 |
HackBar / Burp Suite | 实战中修改 Token 提交重放 |
Postman | 模拟 JWT 接口调用 |
六、同源策略(SOP)
同源策略(Same-Origin Policy) 是浏览器的一种安全机制,用于隔离不同网站之间的资源,防止恶意网站窃取用户敏感数据。
它最初是为了解决:
-
网页中的 JavaScript 脚本不能访问其他域下的资源(防止 XSS、CSRF)
-
保护用户的 Cookie、本地存储、DOM 数据不被第三方网站访问
1. 什么叫"同源"?
要完全同源,必须满足三个条件完全相同:
条件 | 说明 | 示例 |
---|---|---|
协议 | http vs https | http:// ≠ https:// |
域名 | www.example.com vs api.example.com | 子域名也算不同源 |
端口 | 80 vs 8080 | http://a.com:80 ≠ http://a.com:8080 |
例如:
bash
http://a.com ≠ https://a.com
http://a.com ≠ http://b.com
http://a.com:80 ≠ http://a.com:81
2. SOP 的限制范围(默认禁止访问的内容)
浏览器会对不同源的请求或访问行为 进行限制。以下是 SOP 默认禁止的操作:
操作 | 是否允许 |
---|---|
JS 读取 iframe 中的 DOM(不同源) | 不允许 |
JS 发起跨域 Ajax 请求 | 不允许 |
JS 访问其他源的 Cookie / localStorage | 不允许 |
表单(form)提交跨域 | 允许(但无法读取响应) |
图片(img)加载跨域资源 | 允许(只加载,无法操作) |
3. SOP 的核心目标:防止跨站攻击
举例:A 网站打开 B 网站的 iframe,尝试通过 JS 读取用户信息
javascript
// 假设在 a.com 的页面中:
let content = document.getElementById('iframe').contentWindow.document;
console.log(content.cookie); // 报错:同源策略阻止了访问
如果不限制,就会产生极大的安全隐患(如 CSRF、XSS 等)。
4. 开发中遇到的常见问题(实际限制表现)
场景 | 是否被 SOP 限制 | 说明 |
---|---|---|
使用 fetch 发送跨域请求 |
被限制 | 需要服务端设置 CORS 头 |
JS 读取 <iframe src="b.com"> 的内容 |
被限制 | DOM 无法访问 |
<img src="https://b.com/1.png"> 加载图片 |
不限制 | 图片加载不受限制 |
<script src="https://cdn.com/lib.js"> |
不限制 | 可加载第三方脚本(也是 XSS 传播方式之一) |
5. SOP 的绕过方法(前端对策)
浏览器的 SOP 限制并不是绝对的,常见的绕过方案包括:
1)CORS(跨域资源共享)
服务端设置响应头:
bash
Access-Control-Allow-Origin: https://a.com
让前端合法地跨域访问后端资源。这是现代前后端分离的标准方案。
2)JSONP(只支持 GET 请求)
通过 <script>
标签的漏洞来"绕过"SOP:
html
<script src="https://api.com/data?callback=cb"></script>
<script>
function cb(data) {
console.log(data);
}
</script>
JSONP 是早期跨域的方式,但存在安全风险,不推荐新项目使用。
3)PostMessage(安全通信)
允许父页面与 iframe 跨域通信:
javascript
// 子页面(b.com):
window.parent.postMessage("data", "http://a.com");
// 父页面(a.com):
window.addEventListener("message", function(e) {
if (e.origin === "http://b.com") {
console.log(e.data);
}
});
这是现代安全通信推荐的方式。
4)document.domain(仅限同一主域)
两个子域如 a.example.com
和 b.example.com
,可以设置:
javascript
document.domain = "example.com";
使它们视为同源,但只能在主域一致时使用。
6. 渗透测试视角:绕过 SOP 的利用点
攻击点 | 说明 |
---|---|
缺少 CORS 检查 | 攻击者可构造恶意站点发起跨域请求 |
CORS 配置错误(允许 *) | Access-Control-Allow-Origin: * 与敏感数据结合极度危险 |
JSONP 接口未校验 callback | 可被攻击者构造页面获取用户数据 |
WebSocket 没有来源校验 | 攻击者可能伪造连接窃取数据 |
7. 安全建议
措施 | 说明 |
---|---|
合理配置 CORS | 明确允许来源,避免使用 * |
所有敏感操作要求认证 | 防止被跨站调用滥用接口 |
对 JSONP 接口设置签名验证 | 防止 callback 被任意构造 |
iframe 内部禁止敏感操作 | 设置 X-Frame-Options 避免嵌入 |
CSP 配置 | 限制 JS 来源,防止恶意加载脚本 |
8. 浏览器 SOP 的实现方式
-
对 DOM 对象进行隔离(沙箱)
-
设置
Origin
请求头和Referer
头 -
跨域访问报
DOMException: Blocked a frame with origin...
浏览器如 Chrome、Firefox 都严格遵守 SOP 规则。
9. 常见工具与调试技巧
工具 | 用途 |
---|---|
Chrome DevTools | 查看请求的 Origin 、CORS 响应 |
Burp Suite | 模拟跨域请求、CORS 配置测试 |
HackBar | 构造 JSONP / iframe payload |
七、CORS(跨域资源共享)
CORS(Cross-Origin Resource Sharing)是浏览器为了解决跨域访问限制,在服务器端通过设置 HTTP 响应头来告诉浏览器:"哪些源可以访问我"。
它是同源策略(SOP)限制的标准化扩展机制,允许客户端从不同源的服务器请求资源。
1. 什么是跨域?
跨域的本质是源不同(origin)。判断是否跨域,要比较:
协议 | 域名 | 端口 |
---|---|---|
http://a.com | vs | https://a.com |
http://a.com | vs | http://b.com |
http://a.com:80 | vs | http://a.com:81 |
只要三者有一个不同,就叫做"跨域请求"。
2. CORS 的基本流程(以浏览器为例)
当前端向跨域后端发请求时,浏览器会检查是否允许,如果允许则继续,否则阻止访问。
1)简单请求(simple request)
满足以下条件的请求,称为简单请求:
-
使用方法:
GET
、HEAD
、POST
-
Content-Type
限制为:-
application/x-www-form-urlencoded
-
multipart/form-data
-
text/plain
-
-
请求头没有自定义(比如没有带 token)
浏览器直接发请求,后端返回响应:
请求:
bash
GET /api/data HTTP/1.1
Origin: http://a.com
响应:
bash
Access-Control-Allow-Origin: http://a.com
如果这个头部不存在,浏览器就会拦截响应结果(虽然请求成功,但无法访问响应数据)。
2)非简单请求(Preflight 预检请求)
如果使用了:
-
方法为
PUT
、DELETE
、PATCH
等 -
请求头带有自定义字段(如
Authorization
,X-Custom-Header
) -
Content-Type 非简单类型(如
application/json
)
浏览器会先自动发送一个 预检请求(OPTIONS),确认服务端是否允许跨域。
预检请求(OPTIONS):
bash
OPTIONS /api/update HTTP/1.1
Origin: http://a.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
响应:
bash
Access-Control-Allow-Origin: http://a.com
Access-Control-Allow-Methods: PUT, POST, GET
Access-Control-Allow-Headers: Content-Type
预检通过后,浏览器才会发起真正的跨域请求。
3. 常见响应头字段详解(由服务器设置)
响应头 | 含义 |
---|---|
Access-Control-Allow-Origin |
指定允许访问资源的域名(如 http://a.com )或 * |
Access-Control-Allow-Methods |
允许的 HTTP 方法(如 GET, POST, PUT ) |
Access-Control-Allow-Headers |
允许的自定义请求头 |
Access-Control-Allow-Credentials |
是否允许携带 Cookie,必须为 true |
Access-Control-Expose-Headers |
允许前端 JS 访问的响应头(默认 JS 只能读部分 header) |
Access-Control-Max-Age |
预检请求的缓存时间,单位秒(减少重复预检) |
示例响应头(配置示例):
bash
Access-Control-Allow-Origin: https://a.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 3600
4. CORS 安全风险与攻击利用
虽然 CORS 是为了安全而设计的,但配置不当反而会成为漏洞入口,攻击者可以借此发起攻击:
1)Access-Control-Allow-Origin: *
如果服务端设置了:
bash
Access-Control-Allow-Origin: *
且接口还返回了敏感信息或用户隐私数据(如登录态、订单、银行卡),就允许任意网站跨域读取用户数据,这是严重漏洞!
尤其危险当还设置了 Access-Control-Allow-Credentials: true
!
2)反射型 Origin 校验绕过
有些服务端写法是:
javascript
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
这会导致任意 Origin 都能被服务端反射,如果没有做白名单校验,非常危险!
3)服务端配置错误导致攻击者网站可以发请求读取数据
攻击者只需伪造页面,在 victim 用户打开后即可读取其在真实网站中的数据:
javascript
fetch("https://bank.com/api/user", {
credentials: 'include'
})
.then(res => res.json())
.then(data => {
// 攻击者读取用户数据
sendToMe(data);
});
5. 渗透测试中如何检测 CORS 问题?
常用方法:
-
用 Burp Suite 修改
Origin
头,测试是否被允许 -
修改
Access-Control-Allow-Credentials
为 true,观察响应头是否放开 -
用 curl 或 Postman 构造 OPTIONS 请求,查看服务器是否响应预检
6. 安全配置建议
项目 | 建议配置 |
---|---|
Access-Control-Allow-Origin |
只允许明确的白名单域名 |
Access-Control-Allow-Credentials |
仅在确实需要时设置为 true ,并不能与 * 同时使用 |
Access-Control-Allow-Headers |
控制允许的自定义头,避免过宽 |
检查 Origin 白名单 |
不要简单反射请求头,要严格校验合法域名 |
7. 常用调试工具
工具 | 用途 |
---|---|
Chrome DevTools - Network | 查看请求是否被 CORS 拦截 |
curl | 构造跨域和预检请求 |
Postman | 模拟请求(注意 Postman 不受 SOP 限制) |
Burp Suite | 劫持 Origin 头,测试服务端配置 |
CORS Everywhere 插件 | 测试跨域调试(仅开发用) |
八、URL 编码
URL 编码,又叫 百分号编码(Percent Encoding) ,是为了将 URL 中不允许出现的特殊字符 转换为合法格式,便于安全传输。
URL 只能使用 ASCII 字符集,不能直接包含:
-
空格(
-
中文(如
你好
) -
特殊符号(如
#
、&
、?
、=
,/
等)
所以需要将这些字符进行编码,才能正确传递给服务器。
1. URL 编码的原理
格式为:
bash
% + 两位十六进制表示的 ASCII 码
示例:
字符 | ASCII | URL 编码 |
---|---|---|
空格 | 0x20 |
%20 (或 + ) |
+ |
0x2B |
%2B |
/ |
0x2F |
%2F |
? |
0x3F |
%3F |
= |
0x3D |
%3D |
& |
0x26 |
%26 |
# |
0x23 |
%23 |
中文 "你" | U+4F60 |
%E4%BD%A0 (UTF-8 编码后再转为十六进制) |
2. 哪些字符需要被编码?
类型 | 是否需要编码 |
---|---|
英文字母 A--Z、a--z | 不需要 |
数字 0--9 | 不需要 |
安全字符 - _ . ~ |
不需要 |
空格 | 需编码为 %20 或 + (在 application/x-www-form-urlencoded 中) |
其它字符如 : / ? # & = % |
必须编码 |
非 ASCII 字符(如中文) | 必须编码 |
3. URL 编码的使用位置
1)浏览器地址栏中的参数:
bash
GET /search?q=%E5%BC%A0%E4%B8%89 HTTP/1.1
2)表单提交时:
表单 Content-Type: application/x-www-form-urlencoded
时,表单字段会被 URL 编码
3)AJAX、Fetch 请求中参数拼接
4)编码敏感字符以防止参数污染、解析错误
4. Web 安全中的 URL 编码(绕过技巧)
1)参数混淆绕过防火墙(WAF):
假如 WAF 拦截 ../../etc/passwd
,你可能试试:
-
%2e%2e%2f%2e%2e%2fetc%2fpasswd
-
%252e%252e%252f
(双重编码绕过) -
%c0%ae%c0%ae%c0%af
2)XSS 利用中:
bash
<script>alert(1)</script>
编码后变为:
bash
%3Cscript%3Ealert(1)%3C%2Fscript%3E
WAF 可能没能识别所有编码形式,从而实现绕过。
3)SQL 注入混淆:
bash
?id=1%20OR%201=1
编码了空格,防止被拦截。
5. 编码/解码工具
1)Python 代码演示:
python
from urllib.parse import quote, unquote
# 编码中文
s = "你好 world!"
encoded = quote(s) # %E4%BD%A0%E5%A5%BD%20world%21
print(encoded)
# 解码
print(unquote(encoded)) # 你好 world!
2)Burp Suite 解码工具:
在 Repeater/Decoder 标签页可以快速 Base64、URL、HTML、Unicode 编解码
3)Chrome 控制台:
javascript
encodeURIComponent("你好&=123")
// 输出:"%E4%BD%A0%E5%A5%BD%26%3D123"
6. 常见编码陷阱与错误
问题 | 说明 |
---|---|
重复编码 | 如 %252e 是 %2e 的再编码(双重编码),服务器可能解码两次 |
编码位置错误 | 编码值错放在 URL path 或 query 中,可能导致路径解析错误 |
编码不一致 | 前端用 encodeURIComponent ,后端没对应解码,会导致参数丢失 |
编码绕过防御 | 防御机制只检查原始字符串,未解码处理,易被绕过 |
7. 与其他编码方式对比
编码方式 | 用途 | 是否安全 |
---|---|---|
URL 编码 | 浏览器传参、Form 表单 | 是 防止格式错乱,但非加密 |
Base64 编码 | 数据传输(如图片、JWT) | 否 仅编码,非加密 |
HTML 实体编码 | 防止 XSS 注入 | 是 如 < 编码为 < |
JavaScript 转义 | 防止 XSS,绕过 JS 解析 | 是 \x3C 是 < |
总结
项目 | 说明 |
---|---|
编码规则 | % + 两位十六进制 ASCII |
空格 | %20 或 + (表单) |
中文 | UTF-8 → hex → %XX 格式 |
安全用途 | 防止参数错乱、WAF 绕过、XSS 混淆 |
安全风险 | 双重编码绕过、解码不一致问题 |
九、Base64 编码
Base64 是一种将 任意二进制数据 编码成 可打印 ASCII 字符 的方式,常用于:
-
数据传输(如 JSON、表单、URL 中)
-
数据存储(如图片、证书)
-
避免字符在传输中出错或被解析
重点:Base64 不是加密,也不是压缩,仅是编码!
1. Base64 编码原理详解
原理概括:
将原始数据每 3 字节(3 x 8 = 24 bit) 一组,拆分为 4 个 6 位二进制数(4 x 6 = 24 bit),再映射到一个 Base64 字符表中。
Base64 字符表:
css
A-Z a-z 0-9 + /
共 64 个字符
编码值 | 字符范围 |
---|---|
0-25 | A-Z |
26-51 | a-z |
52-61 | 0-9 |
62 | + |
63 | / |
填充符 =
:
当原始数据不是 3 字节整数倍时,会用 =
进行补齐,1 个或 2 个 =
。
示例:
编码原始字符串:abc
1)将每个字符转换为 ASCII(二进制)
bash
a: 01100001
b: 01100010
c: 01100011
→ 拼接:011000010110001001100011
2)按 6 位拆分为:
bash
011000 010110 001001 100011
十进制:24 22 9 35
映射: Y W J j
结果:YWJj
Python 演示:
python
import base64
# 编码
text = "abc"
encoded = base64.b64encode(text.encode()) # b'YWJj'
print(encoded.decode())
# 解码
decoded = base64.b64decode(encoded).decode()
print(decoded)
2. Base64 的使用场景
场景 | 示例 |
---|---|
JWT | header.payload.signature 中的 header 和 payload 是 base64url 编码 |
图片 | <img src="data:image/png;base64,XXX"> |
文件上传 | 文件内容转为 base64 发送到服务器 |
HTTP Basic Auth | Authorization: Basic dXNlcjpwYXNz (user:pass 的 base64) |
URL 参数 | 数据转为 base64 再放到 URL 中传输 |
3. Base64 和 Base64URL 的区别
比较项 | Base64 | Base64URL(安全版本) |
---|---|---|
+ 替换为 |
+ |
- |
/ 替换为 |
/ |
_ |
末尾 = |
有 | 可省略 |
用于 | 常规场景 | JWT、URL、Web 安全相关传输 |
示例:
bash
Base64: abc123! → YWJjMTIzIQ==
Base64URL: YWJjMTIzIQ # 去掉了等号
4. Base64 与 Web 安全的关系
应用:
-
参数传输隐藏
把 JSON 参数 base64 编码,避免前端直接暴露结构
-
API 加密混淆
一些接口请求体、请求头中加入 base64 编码数据,提升分析门槛
-
绕过防火墙/规则匹配
有些敏感 payload 会先 base64 编码再传输,再由服务器解码(如 WAF 绕过)
-
XSS 编码绕过
把恶意脚本 base64 编码后,通过
eval(atob(...))
执行
javascript
eval(atob("YWxlcnQoJzEyMycp")) // alert('123')
-
JS逆向中常见加密流程
多层 Base64 编码、混淆和加密结合使用。
5. 安全误区与攻击风险
问题 | 说明 |
---|---|
不是加密! | Base64 编码后看起来像加密,但任何人都能解码 |
可被爆破/分析 | 许多 JS 文件、JWT payload 都是 base64 编码的,可以还原得到内容 |
可以隐藏 XSS、命令注入等 payload | 需要手动解码再检测 |
6. 实战分析案例
JWT Payload 解码(典型 Base64URL)
bash
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJ1c2VyIjoiYWRtaW4iLCJpYXQiOjE2Nzk2NTg1NTV9
.
<signature>
把中间两段解码即可得到 header 和 payload 信息。
Python 脚本解码 JWT:
python
import base64
import json
def decode_jwt_part(part):
# Base64 padding 补齐
# JWT 使用的是 Base64 URL 安全编码,它会去掉 = 号来减小长度。
# 但 Python 解码时需要标准 Base64 格式(必须是 4 的倍数长度),所以要补 =。
# -len(part) % 4 的意思是:最少补几个 =,才能使长度变成 4 的倍数
part += '=' * (-len(part) % 4) # padding
return json.loads(base64.urlsafe_b64decode(part))
print(decode_jwt_part("eyJ1c2VyIjoiYWRtaW4iLCJpYXQiOjE2Nzk2NTg1NTV9"))
7. 常用工具
工具 | 功能 |
---|---|
Python base64 模块 | 编解码 |
Burp Suite Decoder | 支持 Base64 多层解码 |
在线网站 | 如 base64decode.org |
Chrome 控制台 | btoa() 编码、atob() 解码 |
总结
项目 | 内容 |
---|---|
每 3 字节 → 4 字符 | 6bit 对应 1 个 base64 字符 |
字符集 | A-Z, a-z, 0-9, +, /(或 URL 中的 -, _) |
补齐 | 不足用 = 补齐 |
安全意义 | 避免传输错误、隐藏参数、混淆传输逻辑 |
风险点 | 可逆,不等于加密,可作为绕过媒介 |
十、加密与混淆格式
在 Web 安全中,我们经常会遇到一些传输参数像这样:
bash
X-Qwert: U2FsdGVkX1+K7NvMdq...
data: 5a53486c6358526c5a6a49...
sign: KLi8rYuM+j2kmdFrYzR2aA==
这些数据可能是:
-
加密过的数据(如 AES/RSA 加密)
-
混淆处理后的参数(如自定义编码、Base64、多层转换)
-
加密 + 编码 + 压缩的多层处理
1. 加密 vs 混淆的区别
项目 | 加密 | 混淆 |
---|---|---|
目的 | 保障机密性、避免被破解 | 增加理解、逆向难度 |
是否可逆 | 加密通常可逆(对称/非对称) | 混淆通常可逆 |
是否安全 | 安全性取决于算法和密钥 | 不安全,仅用于隐藏逻辑 |
使用场景 | 敏感数据传输、身份验证 | Web 参数、JS 函数混淆 |
2. 常见加密算法与格式
对称加密
-
算法:AES、DES、3DES、RC4
-
特点:加密和解密使用同一个密钥
-
格式特征:加密后多为 base64 编码字符串或 16 进制
示例:
javascript
// AES 加密后的数据
U2FsdGVkX19yJwDkLNEpsjd3S1qzvFq...
关键点:
- 如果数据以
U2FsdGVkX1
开头,很可能是CryptoJS
的 AES 加密(OpenSSL 格式)
非对称加密
-
算法:RSA、ECC
-
特点:公钥加密、私钥解密
-
格式特征:
-
base64 编码大段数据
-
开头可能是
"-----BEGIN PUBLIC KEY-----"
-
常见格式:
bash
MIIBIjANBgkqhkiG9w0BAQEFAA...
哈希算法(不可逆)
-
算法:MD5、SHA1、SHA256
-
特点:不可逆,常用于签名、校验
-
格式特征:固定长度 hex 字符串(32/40/64位)
示例:
bash
签名:ae2b1fca515949e5d54fb22b8ed95575 // MD5
3. 混淆格式举例
1)Base64 混淆
-
加密后用
Base64
编码,使其变得"可传输" -
多层 Base64 编码也很常见
javascript
let data = "YWJjZGVmZw=="; // 实际为 'abcdefg'
2)字符编码混淆
- 原始字符串被转为 Unicode 编码、URL 编码、十六进制等
javascript
\u0061\u0062\u0063 // 'abc'
%61%62%63 // 'abc' URL 编码
0x61 0x62 0x63 // 十六进制 ASCII
3)函数名和变量名混淆
javascript
var _0x8a21=["\x63\x6F\x6E\x73\x6F\x6C\x65"];
console[_0x8a21[0]]("hello");
-
这里的
console["log"]("hello")
被混淆了 -
用于 JS 反调试、反逆向v
4)自定义变形/加密格式
很多 APP 和 JS 代码会自己写一套编码/混淆算法,如:
-
把字符串每个字符 +3(Caesar)
-
异或加密(XOR)
-
字节倒序
-
定制压缩算法
javascript
// 简单的异或加密
function xor(str, key) {
return str.split('').map(c => String.fromCharCode(c.charCodeAt(0) ^ key)).join('');
}
4. 攻击角度:如何分析加密和混淆?
1)看数据格式
特征 | 可能是什么 |
---|---|
以 U2FsdGVkX1 开头 |
AES + OpenSSL(CryptoJS) |
字符全部为 hex | AES/RC4/raw-byte |
长度固定 | Hash,如 MD5/SHA1 |
多层 base64 | 混淆 |
2)查代码关键点
-
搜索:
CryptoJS
,AES
,RSA
,encrypt
,sign
,btoa
,atob
-
查看数据构造、参数生成逻辑
-
找混淆函数、手动还原(AST 分析、动态调试)
3)动态调试定位加密逻辑
-
使用浏览器断点调试(XHR、事件触发)
-
Hook JS 函数(如:CryptoJS.encrypt、btoa)
-
Frida 注入 APP 加密函数中间参数
5. Web 安全中加密与混淆的实战应用
场景 | 加密/混淆用法 |
---|---|
登录传参 | 密码 AES/RSA 加密,防止被抓包重放 |
参数校验 | 用 sign/signature 签名参数防篡改 |
WebSocket 通讯 | 使用 base64 + AES 封装消息 |
JS 反调试 | 所有关键变量、函数名混淆,配合动态密钥 |
JS逆向保护 | 自定义的算法混淆函数逻辑,动态解密执行 |
6. 工具推荐
工具 | 用途 |
---|---|
Burp Suite + Decoder | 拆解多层混淆 |
JSDetox、AST Explorer | 还原 JS 混淆代码 |
CyberChef | 可视化多层解码 |
Frida | Hook APP 加密逻辑 |
Python + Crypto 库 | 自定义脚本解密 |
总结
加密方式 | 特征表现 | 常见用途 |
---|---|---|
Base64 多层 | 只要 atob 多次即可还原 | 数据混淆 |
AES + base64 | CryptoJS 明文加密后再编码 | 登录、参数 |
RSA + base64 | 一般只加密部分数据(如密码) | 登录验证 |
MD5、SHA 签名 | 固定 32/64 长度,非可逆 | 防篡改 |
异或、倒序、变形 | 数据无固定长度,无库依赖 | 隐藏算法 |