http协议
1. cookie
(1)什么是Cookie?
Cookie(HTTP Cookie)是网站存储在用户浏览器中的小型文本数据,用于记录用户信息或跟踪用户行为。当用户访问网站时,服务器可以发送Cookie到浏览器,浏览器会保存并在后续请求中自动携带Cookie,帮助服务器识别用户或维持会话状态。
(2)Cookie的作用
- 会话管理:保持用户登录状态(如登录Token)。
- 个性化设置:存储用户偏好(如语言、主题)。
- 跟踪与分析:记录用户行为(如广告追踪、数据分析)。
- 购物车功能:暂存未结算的商品信息。
(3) Cookie的特点
- 大小限制:通常每个Cookie不超过4KB。
- 域名绑定:仅对创建它的域名有效,遵循同源策略。
- 生命周期:可设置过期时间(会话Cookie或持久Cookie)。
- 安全性:可通过
Secure
(仅HTTPS)、HttpOnly
(防JS访问)等属性增强安全。
(4)Cookie的构成(常见属性)
Set-Cookie: id=abc123; Path=/; Domain=example.com; Max-Age=3600; Secure; HttpOnly
- Name/Value:存储的数据(如
id=abc123
)。 - Domain:生效的域名(默认为当前域名)。
- Path:生效的路径(如
/
表示全站)。 - Expires/Max-Age:过期时间(会话Cookie关闭浏览器后失效)。
- Secure:仅通过HTTPS传输。
- HttpOnly:禁止JavaScript访问(防XSS攻击)。
- SameSite:限制跨站发送(防CSRF攻击,可选
Strict/Lax/None
)。
(5) Cookie的缺点
- 隐私问题:可能被用于追踪用户行为。
- 安全性风险:可能遭遇XSS(窃取Cookie)或CSRF(伪造请求)攻击。
- 存储限制:容量小,不适合存大量数据。
(6) 替代技术
- SessionStorage:会话级存储,页面关闭后失效。
- LocalStorage:长期存储,无过期时间。
- IndexedDB:浏览器端大型结构化数据库。
(7)总结
Cookie是Web开发中维持状态的关键技术,适用于会话管理和小型数据存储,但需注意隐私与安全问题。现代开发中常结合其他存储技术(如Token、LocalStorage)使用。
(8)题目复现
题目:[seek flag]
- 题目来源:Polarctf-web-[seek flag]
- 解题:
- 查看源代码
提示爬虫协议,输入url/robots.txt
查看爬虫协议获得第三段flag
- 抓包看到cookie值为"id=0"
右键发送到重放器(Repeater),发送后切换到重放器模块
点击发送,在响应体的 "Flag2" 字段中得到第二段flag
- 在重放器中将cookie值篡改为"id=2",点击发送,在响应体中得到第一段flag
- 三段合在一起即为最终提交的flag:
flag{7ac53ca8737a70f029dc0ad71dadd11}
题目:[cookie]
- 题目来源:polarctf-web-[cookie]
- 解题:
根据题目cookie
,f12,在存储中找到cookie
将cookie值改为admin
并保存,刷新得到flag
题目:[debudao]
- 题目来源:polarctf-web-[debudao]
- 解题:
查看源码得到一个假的flag
f12查看存储中的cookie,存着一个flag,%7B、%7D
分别对应{、}
,提交通过:flag{72077a55w312584wb1aaa88888cd41af}
2. JWT
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用间安全地传输信息。它采用 JSON 格式,通常用于 身份验证(Authentication) 和 数据交换(Information Exchange)。
(1)JWT 的结构
JWT 由三部分组成,用 .
分隔:
Header.Payload.Signature
Header(头部)
说明令牌的类型(
typ: "JWT"
)和签名算法(如HS256
、RS256
)。示例:
json{ "alg": "HS256", // 签名算法(HMAC-SHA256) "typ": "JWT" // 令牌类型 }
Base64Url 编码后 →
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload(载荷)
包含实际传输的数据(称为 Claims),分为三类:
- Registered Claims(标准字段):如
iss
(签发者)、exp
(过期时间)。 - Public Claims(公开字段):自定义但需避免冲突。
- Private Claims(私有字段):双方约定的数据。
- Registered Claims(标准字段):如
示例:
json{ "sub": "1234567890", // 用户ID "name": "John Doe", // 用户名 "admin": true // 自定义字段 }
Base64Url 编码后 →
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Signature(签名)
用于验证令牌的完整性,防止篡改。
生成方式:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret_key )
最终 JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
(2) JWT 的工作原理
客户端登录:用户提交凭证(如用户名/密码)。
服务器验证:通过后生成 JWT 并返回给客户端。
客户端存储:通常保存在
localStorage
或Cookie
中。后续请求:客户端在
Authorization
头中携带 JWT:Authorization: Bearer <JWT>
服务器验证 JWT:
- 检查签名是否有效。
- 验证
exp
(过期时间)等字段。
(3) JWT 的优缺点
优点
- 无状态:服务端无需存储会话信息(适合分布式系统)。
- 跨域友好:可用于单点登录(SSO)。
- 数据透明:Payload 可直接解码查看(但需签名防篡改)。
缺点
- 无法废止:签发后到期前始终有效(需额外逻辑处理注销)。
- 安全性依赖密钥:弱密钥易被暴力破解(如
jwt-cracker
)。 - Payload 默认不加密:敏感数据需自行加密(或使用 JWE)。
(4) JWT 常见攻击方式
密钥爆破
- 工具:
jwt-cracker
、c-jwt-cracker
、jwt-tools
、hashcat
。 - 防御:使用强密钥(如
openssl rand -hex 32
)。
算法篡改(None Attack)
- 修改
alg
为none
绕过签名验证。 - 防御:服务端严格校验算法。
密钥混淆(RS256 → HS256)
- 当服务端支持多算法时,攻击者伪造 HS256 签名(将公钥作为密钥)。
- 防御:固定使用一种算法。
过期时间篡改
- 修改
exp
字段延长有效期。 - 防御:服务端校验时间戳。
(5)实战示例
加解码 JWT
在线工具
jq 工具
jq 是一个轻量级、强大的命令行 JSON 处理器,可用于解析、过滤、修改和格式化 JSON 数据。在 Kali Linux(或其他 Linux 系统)中,它常用于处理 API 响应、日志文件或任何 JSON 格式的数据。
安装 jq
在 Kali Linux 中,默认可能已安装,如果没有,可以运行:
sudo apt update && sudo apt install -y jq
验证安装:
jq --version
输出示例:
jq-1.6
基本用法
- 格式化 JSON
echo '{"name":"John","age":30}' | jq .
输出:
{
"name": "John",
"age": 30
}
jq .
:表示原样输出 JSON(美化格式)。
- 提取字段
echo '{"name":"John","age":30}' | jq '.name'
输出:
"John"
'.name'
:提取 name
字段。
- 提取嵌套字段
echo '{"user":{"name":"Alice","age":25}}' | jq '.user.name'
输出:
"Alice"
- 提取数组元素
echo '{"users":["Alice","Bob","Charlie"]}' | jq '.users[1]'
输出:
"Bob"
'.users[1]'
:提取数组 users
的第 2 个元素(索引从 0
开始)。
高级用法
- 遍历数组
echo '{"users":["Alice","Bob","Charlie"]}' | jq '.users[]'
输出:
"Alice"
"Bob"
"Charlie"
'.users[]'
:遍历数组的所有元素。
- 条件过滤
echo '[{"name":"Alice","age":25},{"name":"Bob","age":30}]' | jq '.[] | select(.age > 28)'
输出:
{
"name": "Bob",
"age": 30
}
select(.age > 28)
:筛选 age > 28
的对象。
- 修改 JSON
echo '{"name":"John","age":30}' | jq '.age = 31'
输出:
{
"name": "John",
"age": 31
}
'.age = 31'
:修改 age
字段的值。
- 合并 JSON
echo '{"name":"John"}' | jq '. + {"age":30}'
输出:
{
"name": "John",
"age": 30
}
'. + {"age":30}'
:合并新字段 age
。
- 提取多个字段
echo '{"name":"John","age":30,"city":"New York"}' | jq '{name, city}'
输出:
{
"name": "John",
"city": "New York"
}
'{name, city}'
:只提取 name
和 city
字段。
实战示例
- 解析 JWT 的 Payload
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" | cut -d '.' -f 2 | base64 -d | jq
输出:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
cut -d '.' -f 2
:以 .
为分隔符,提取 JWT 的第二部分(Payload)。
base64 -d
:解码 Base64Url 编码的 Payload(实际是 Base64 变种,但 -d
通常兼容)。
jq
:格式化 JSON将解码后的 JSON 数据自动排版(易读格式)。
- 解析 JWT 的 Header 和 Payload
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" |
jq -R 'split(".") | .[0,1] | @base64d'
jq -R
:-R
选项表示 jq 将输入作为原始字符串处理,而不是 JSON
split(".")
:用点号(.)分割 JWT 字符串,JWT 由三部分组成(Header.Payload.Signature),这会生成一个包含三个元素的数组
.[0,1]
:选择数组的第0和第1个元素(即 Header 和 Payload),跳过第2个元素(Signature)
@base64d
:jq 的内置函数,对 Base64 编码的字符串进行解码
注意:JWT 使用的是 Base64Url 编码,但 jq 的 @base64d 通常也能正确处理;这个命令只解码 Header 和 Payload,不处理 Signature;
最终输出会显示两个解码后的 JSON 对象:第一个是 Header 部分,第二个是 Payload 部分
示例输出如下:
"{\"alg\":\"HS256\",\"typ\":\"JWT\"}"
"{\"sub\":\"1234567890\",\"name\":\"John Doe\",\"iat\":1516239022}"
3.处理 API 返回的 JSON
curl -s "https://api.example.com/users" | jq '.[] | {id, name}'
输出:
{
"id": 1,
"name": "Alice"
}
{
"id": 2,
"name": "Bob"
}
curl -s
:静默请求 API。
jq '.[] | {id, name}'
:提取每个用户的 id
和 name
。
常见问题
Q1: 如何输出原始字符串(不带引号)?
echo '{"name":"John"}' | jq -r '.name'
输出:
John
-r
(--raw-output
):输出原始文本,不带 ""
。
Q2: 如何计算数组长度?
echo '["Alice","Bob","Charlie"]' | jq 'length'
输出:
3
Q3: 如何检查字段是否存在?
echo '{"name":"John"}' | jq 'has("age")'
输出:
false
总结
功能 | 命令示例 |
---|---|
格式化 JSON | jq . |
提取字段 | jq '.name' |
遍历数组 | jq '.[]' |
条件筛选 | `jq '.[] |
修改 JSON | jq '.age = 30' |
合并 JSON | jq '. + {"new_field":"value"}' |
jq 是处理 JSON 数据的瑞士军刀,适用于日志分析、API 测试、数据清洗等场景。
破解 JWT 令牌弱密钥
c-jwt-cracker(建议)
在 Kali Linux 中安装和使用 c-jwt-cracker
(C 语言版 JWT 暴力破解工具)的完整指南如下:
安装依赖
c-jwt-cracker
需要编译,先安装必要的开发工具:
sudo apt update
sudo apt install -y git build-essential libssl-dev
build-essential
:包含gcc
、make
等编译工具。libssl-dev
:提供 OpenSSL 库支持(用于 JWT 签名验证)。
下载并编译 c-jwt-cracker
git clone https://github.com/brendan-rius/c-jwt-cracker.git
cd c-jwt-cracker
make
编译成功后,生成可执行文件 jwtcrack
。
基本用法
- 破解 JWT 密钥
./jwtcrack "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
工具会自动尝试暴力破解密钥(默认字符集:a-zA-Z0-9
)。
成功输出示例
Found secret: "secret" (in 12.5s)
表示密钥是 secret
。
- 高级参数
参数 | 说明 | 示例 |
---|---|---|
-t <线程数> | 多线程加速(推荐 CPU 核心数) | ./jwtcrack -t 4 "JWT" |
-a <字符集> | 自定义字符集(如仅数字) | ./jwtcrack -a "0123456789" "JWT" |
-m <最大长度> | 限制密钥最大长度 | `./jwtcrack -m 6 "JWT" |
常见问题
Q1: 编译失败?
确保已安装 libssl-dev
:
sudo apt install libssl-dev
检查错误信息,通常因缺少依赖导致。
Q2: 破解速度慢?
使用 -t
增加线程数。
Q3: 如何破解长密钥?
优先尝试字典攻击(如 rockyou.txt
)。
纯暴力破解长密钥(如 >8 位)可能不现实。
jwt-tools
jwt-cracker(不建议,破解很慢)
在 Kali Linux 中安装 jwt-cracker
(一个用于破解 JWT 令牌的工具)可以通过以下步骤完成:
jwt-cracker
是一个 Node.js 工具,可以通过 npm
(Node.js 包管理器)安装。
安装 Node.js 和 npm(如果尚未安装):
bashsudo apt update sudo apt install -y nodejs npm
安装
jwt-cracker
:bashsudo npm install -g jwt-cracker
运行工具:
bashjwt-cracker <JWT_TOKEN> [<ALPHABET>] [<MAX_LENGTH>]
示例:
bashjwt-cracker -t "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
(6)安全建议
- 使用强算法:优先选择
RS256
(非对称)而非HS256
(对称)。 - 设置短有效期:通过
exp
控制令牌生命周期。 - 避免敏感数据:Payload 中不存储密码等机密信息。
- HTTPS 传输:防止中间人窃取令牌。
(7)总结
- JWT 是 无状态身份验证 的流行方案,但需注意安全性。
- 开发时避免常见漏洞(如弱密钥、算法混淆)。
- 渗透测试中可尝试爆破、篡改等手法。
(8)题目复现
题目:[jwt]
- 题目来源:Polarctf-web-[jwt]
- 解题:
登录时随意输入提示无此用户,故随便注册一个账户
注册成功后进行登录,根据题目名称"jwt",故进行抓包获取token(因为要登录后才会得到token反馈,故在登录后再刷新页面进行抓包)
将数据包发送至重放器(Repeater)模块,并将抓到的JWT复制下来进行JWT解码
解码后发现无秘钥,故进行秘钥爆破
得到秘钥为SYSA
,将数据包发送,在响应包中看到提示flag为admins
用户的密码
故将用户名改为admins
后进行编码,尝试多此后发现用户名为admin
才对,提示也是给了一个陷阱
将以前的token改为修改并编码后的token后发包,发现用户名成功更改为admin
将改好的包复制并替换代理模块中抓到的包,然后放行
前端成功回显用户名为admin
点击个人中心,将新抓到的包中的原始token也改为修改后的admin的token,然后放行
看到前端成功拿到flag
3. User-Agent
(1)什么是 User-Agent?
User-Agent(UA) 是 HTTP 请求头的一个字段,用于标识客户端(如浏览器、爬虫、应用程序等)的软件类型、版本、操作系统等信息。服务器可根据 UA 返回适配的内容(如 PC 端或移动端页面)。
(2) User-Agent 的作用
- 设备识别:区分 PC、手机、平板等设备类型。
- 浏览器适配:返回兼容的网页(如 Chrome、Safari、Edge)。
- 爬虫检测:识别搜索引擎爬虫(如 Googlebot、Baiduspider)。
- 统计与分析:收集用户设备分布(如 iOS/Android 比例)。
- 反爬虫机制:限制非浏览器访问(如禁止脚本爬虫)。
(3)User-Agent 的典型格式
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
- Mozilla/5.0:历史遗留标识(现代浏览器均保留)。
- Windows NT 10.0:操作系统(Windows 10)。
- Win64; x64:系统架构(64 位)。
- AppleWebKit/537.36:浏览器引擎(Chrome/Safari 使用)。
- Chrome/120.0.0.0:浏览器类型及版本。
- Safari/537.36:兼容性标识。
(4)常见 User-Agent 示例
Chrome(Windows)
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Safari(Mac)
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15
Edge(Android)
Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36 EdgA/120.0.0.0
爬虫(Googlebot)
Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
(5) 如何修改 User-Agent?
浏览器开发者工具:通过「Network Conditions」临时修改。
编程设置(如 Python requests):
pythonheaders = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"} requests.get(url, headers=headers)
浏览器扩展:如「User-Agent Switcher」插件。
(6) User-Agent 的隐私与争议
- 指纹追踪:UA 可能被用于生成用户唯一标识,引发隐私问题。
- 现代浏览器的限制:
- Chrome 逐步减少 UA 详细信息(启用 User-Agent Reduction 政策)。
- 替代方案:使用 Client Hints(如
Sec-CH-UA
头)获取必要信息。
(7) 相关技术
- Client Hints:更安全的设备信息获取方式(需服务器支持)。
- navigator.userAgent:JavaScript 中获取当前 UA。
(8)总结
User-Agent 是 Web 生态中重要的客户端标识工具,但面临隐私和滥用的挑战。开发者需合理使用,并关注新技术(如 Client Hints)的演进。
(9)题目复现
题目:[iphone]
- 题目来源:Polarctf-web-[iphone]
- 解题:
根据提示点击按钮
显示需要在iphone或ipad端进行查看,点击查看源码,注释中提示修改UA
抓包将User-Agent修改为iphone或ipad,然后放行即可获得flag
4. X-Forwarded-For
(1)什么是 X-Forwarded-For
X-Forwarded-For (XFF) 是一个 HTTP 请求头字段,用于识别通过 HTTP 代理或负载均衡器连接到 web 服务器的客户端的原始 IP 地址。
(2)工作原理
当客户端通过代理或负载均衡器访问服务器时,服务器看到的 IP 地址是代理的地址而非客户端的真实地址。X-Forwarded-For 头用于保留原始客户端的 IP 地址信息。
格式通常如下:
X-Forwarded-For: client, proxy1, proxy2
(3)主要用途
- 获取用户真实 IP:在多层代理环境中追踪原始请求来源
- 访问控制:基于真实 IP 进行访问限制
- 日志记录:记录用户真实 IP 而非代理服务器 IP
- 地理位置服务:基于真实 IP 提供地域相关内容
(4)安全注意事项
- X-Forwarded-For 可以被轻易伪造,不应单独用于安全关键操作
- 应在受信任的网络边界(如第一层代理)设置/覆盖此头
- 建议与其他验证方法结合使用
(5)相关头部
- Forwarded: 新的标准化替代方案(RFC 7239)
- X-Real-IP: 一些代理使用的非标准头部
(6)示例
X-Forwarded-For: 203.0.113.195, 70.41.3.18, 150.172.238.178
表示请求最初来自 203.0.113.195,然后经过两个代理服务器。
(7)题目复现
题目:[XFF]
- 题目来源:Polarctf-web-[XFF]
- 解题:
抓包并发送至重放器模块(Repeater)
根据提示修改X-Forwarded-For字段(此处包中无此字段,手动添加)来源ip为1.1.1.1
,修改后点击"发送",响应包中获得flag