第23天:安全开发-PHP应用&后台模块&Session&Cookie&Toke_笔记|小迪安全2023-2024|web安全|渗透测试|
一、安全开发00:00
1. Cookie技术00:29
1)Cookie流程00:33

- 完整流程:
-
-
- 客户端发送HTTP请求
- 服务器设置Cookie并通过Set-Cookie响应头返回
- 客户端保存Cookie到本地
- 后续请求自动携带Cookie
- 服务器读取Cookie值
- 服务器处理请求并返回HTTP响应
-
2)Cookie的作用01:04
- 本质:用户身份凭证
- 典型应用:
- 实现"记住密码"功能
- 保存用户登录状态(如勾选"记住我"选项后下次免登录)
- 与Session区别:
- Cookie存储在客户端浏览器
- Session存储在服务器端
- 技术实现:将用户凭证保存到浏览器本地,后续访问时自动携带
3)书写简易Cookie流程02:36

- 准备工作:
- 启动数据库服务
- 配置开发环境
- 打开项目源码体系
4)项目文件创建03:21

- 核心文件:
- admin-c.php:登录处理文件
- index-c.php:登录成功首页
- logout-c.php:退出登录处理
- 功能分工:
- 登录→验证→生成Cookie→跳转首页
- 退出→清除Cookie→返回登录页
5)应用案例04:34
- 例题:Cookie登录验证

- 验证流程:
- 接收账号密码(POST方式)
- 连接数据库查询匹配
- 正确则生成Cookie并跳转
- 错误则提示失败信息
- 代码实现:
php
user=user =user=
_POST['username'];
pass=pass =pass=
_POST['password'];
// 数据库验证
sql="SELECT∗FROMadminWHEREusername=′sql = "SELECT * FROM admin WHERE username='sql="SELECT∗FROMadminWHEREusername=′
user' AND password='
pass′";pass'"; pass′";
data = mysqli_query(
con,con,con,
sql);
if(mysqli_num_rows($data) > 0) {
header('Location: index-c.php'); // 成功跳转
} else {
echo '<script>alert("登录失败!")</script>';
}
- 例题:Cookie登录验证 837000

- 关键点 :
- 使用mysqli_num_rows()判断查询结果
- 结果>0表示账号密码正确
- 需先包含数据库配置文件
- 安全注意 :
- 实际开发中密码应加密存储
- 防止SQL注入(示例为简化演示)
- 跳转处理 :
- 成功使用header()跳转
- 失败使用alert()提示
2. Session技术 1275000
1)Session设置的关键要点 1277000
- username与cookie的设定 1279000
- 随机性设置: 用户名和cookie可以任意设置,但需保证后续认证流程的一致性
- 密码存储: 示例中password=123456采用明文存储,实际开发应加密处理
- 关联性 : cookie设置必须与后续身份验证逻辑保持关联,如
username=admin对应特定权限 - 过期时间与域名设定 1306000

- 时间计算: 存活时间采用当前时间戳+60×60×24×30(秒→分→时→天)表示30天有效期
- 作用域限制: 域名参数设置为当前目录路径,限制cookie仅在指定域下有效
- 安全建议: 敏感操作建议设置较短过期时间,如银行操作通常为15-30分钟
- 登录状态检测 1350000

- 检测流程 : 使用
if($_SERVER)判断请求来源,未登录时屏蔽错误提示 - 双重验证: 先检测POST请求存在性,再验证具体参数,避免直接暴露验证逻辑
- 错误处理 : 示例中通过
else分支处理登录失败情况,但应先验证会话有效性 - POST请求处理 1415000

- 条件判断 : 必须存在
$_POST请求才会进入验证流程,防止未提交表单就触发验证 - 参数获取 : 通过
$user=$_POST['username']获取表单数据,需注意SQL注入风险 - 流程控制: 验证失败时应清除已设置的会话信息,避免产生"半登录"状态
- Cookie验证实践 1470000

- 浏览器验证: 在开发者工具Application→Cookies中可查看具体存储内容
- 数据匹配 : 示例中
username=admin与password=123456需与服务器存储一致 - 生命周期: 设置的30天有效期可通过浏览器时间戳进行验证
- 安全警告 : 示例中密码明文存储仅为演示,实际必须使用
password_hash()等加密方式
2)应用案例 1487000
-
例题:Cookie登录验证
-

-
验证机制:通过判断用户提交的Cookie值是否匹配预设值(如username=admin且password=123456)来验证登录状态
-
流程特点 :
- 登录成功后才设置Cookie,失败时不记录
- 通过header()函数实现页面跳转控制
- 退出登录时通过setcookie()清空值或设置过期时间

-
安全隐患 :
- Cookie存储在客户端浏览器,有效期长达一个月
- 攻击者获取Cookie后可直接伪造登录(演示中通过手动添加Cookie实现越权访问)
- 典型攻击方式:XSS漏洞窃取Cookie
-
防御措施 :
- 设置合理过期时间(演示中为1个月)
- 关键操作需重新验证密码
- 建议结合Session使用
-
Session与Cookie对比
-

-
存储位置 :
- Cookie:客户端浏览器
- Session:服务端
-
安全性 :
- Cookie易被窃取(攻击目标为用户)
- Session更安全(攻击需针对服务器)
-
生命周期 :
- Cookie可设置长期有效(演示中为1个月)
- Session默认浏览器关闭即失效
-
使用场景 :
- Cookie:小型网站
- Session:中大型安全要求高的系统
-
Session工作流程 :
- 服务端生成唯一Session ID
- 通过Cookie将Session ID发送给客户端
- 客户端后续请求携带该Session ID
- 服务端验证Session ID有效性
-
登录验证代码实现
-

-
关键代码逻辑 :
php// 检查Cookie是否合法 if($_COOKIE['username']!='admin' ||$_COOKIE['password']!='123456'){ header('Location: admin-c.php'); // 跳转登录页 } -
退出登录实现 :
phpsetcookie('username', ''); // 清空Cookie值 setcookie('password', ''); header('Location: admin-c.php'); // 跳转登录页 -
注意事项 :
- 实际应用应从数据库查询验证信息(演示中为简化直接写死)
- 重要系统建议使用Session替代纯Cookie验证
- 设置HttpOnly和Secure属性增强Cookie安全性
3. Token技术 2554000
1)项目文件创建 2869000
- Session 相关重要函数 2930000

- 工作机制 :
- 服务器为客户端生成唯一的session ID,存储在服务器端存储器(如文件、数据库)
- 服务器将session ID通过cos(xie)\cos(xie)cos(xie)发送给客户端
- 客户端将session ID保存为cosαkie\cos\alpha kiecosαkie(浏览器本地存储)
- 下次请求时客户端在请求头附加该cosdkie\cos dkiecosdkie信息
- 服务器通过session ID检索对应session数据实现数据共享
- 核心函数 :
- session_start():启动或恢复已有会话
- $_SESSION:存储和访问当前会话变量的全局数组
- session_destroy():销毁当前会话所有数据
- session_unset():释放当前会话所有变量
- 登录验证流程与数据库查询 2941000

- 验证流程 :
- 先接收提交数据(与Cookie登录流程类似)
- 引入数据库配置文件进行查询验证
- 判断逻辑与Cookie验证相同,但使用不同函数
- 登录成功后进入Session操作阶段
- 数据库交互 :
- 需先检查数据是否提交
- 进行数据库查询验证用户凭证
- 验证通过后设置Session值
- Session 操作与全局变量设置 2986000
- Session设置方法 :
- 使用session_start()开启会话
- 通过SESSION全局变量设置值(区别于_SESSION全局变量设置值(区别于SESSION全局变量设置值(区别于_COOKIE)
- 典型设置:
$_SESSION['username'] =$username; - 密码设置:
$_SESSION['password'] =$password;
- Session存储路径与配置 3028000

- 存储位置 :
- 由php.ini中的session.save_path参数定义
- 默认路径格式:"N;/path"(N为整数表示子目录层级)
- 示例路径:D:\phpstudy_pro\Extensions\tmp\tmp
- 配置说明 :
- PHP不会自动创建目录结构,需手动创建
- 文件存储模式默认为600(可通过修改MODE值变更)
- 严格会话模式(use_strict_mode)可增强安全性
- 配置文件与路径设置 3093000

- 配置文件 :
- 位于PHP安装目录下的php.ini文件
- 搜索"session.save_path"参数定位存储路径设置
- 开发环境中通常设置为临时目录(如D:\tmp)
- 开发注意 :
- 本地环境同时扮演服务器和客户端角色
- 路径设置直接影响Session文件的存储位置
- 修改配置后需重启服务生效
- 登录成功后的Session启动与设置 3142000

- 操作流程 :
- 用户登录验证通过后
- 调用session_start()启动会话
- 设置$_SESSION['username']等会话变量
- 服务器端生成对应session文件
- 客户端获得session ID进行后续验证
- 安全特性 :
- Token机制可增强安全性
- 生成Token存储在Session中
- 将Token绑定到Cookie触发验证
- 在登录表单中加入Token验证逻辑
2)应用案例 3152000
-
Session与Cookie验证机制
-

-
Session验证流程 :
- 登录成功后服务器生成Session文件存储用户凭证
- 客户端通过Session ID(存储在Cookie)与服务端Session文件匹配
- 代码示例中通过
$_SESSION['username']和$_SESSION['password']进行验证 
-
Session文件特性 :
- 存储在服务器端(如
/tmp/sess_14q6v947qom4uv3ft) - 包含键值对数据(如
username|s:5:"admin";password|s:6:"123456") - 文件命名规则:
sess_+随机ID(如14q6v947qom4uv3ft)
- 存储在服务器端(如
-
安全机制 :
- 必须调用
session_start()才能启用Session功能 - 浏览器关闭后Session可能失效(取决于服务器配置)
- 通过
session_unset()和session_destroy()可主动销毁Session
- 必须调用
-
登录验证流程对比
-

-
Cookie验证的缺陷 :
- 凭证直接存储在客户端Cookie中(如
username=admin; password=123456) - 容易被篡改或窃取,存在安全风险
- 示例中演示了通过修改Cookie值实现越权访问
- 凭证直接存储在客户端Cookie中(如
-
Session验证优势 :
- 敏感信息存储在服务端,客户端只保存Session ID
- 即使获取Session ID也有时效性限制(如浏览器关闭失效)
- 可通过服务端配置增强安全性(如Session过期时间)
-
防御措施实现
-

-
安全登出实现 :
phpsession_start(); session_unset(); // 清除所有Session变量 session_destroy(); // 销毁Session header('Location: login.php'); // 跳转回登录页 -
关键防护点 :
- 必须设置Session过期机制(自动/手动)
- 重要操作需重新验证身份
- 使用HTTPS防止Session ID被截获
-
攻击场景分析
-

-
Session劫持条件 :
- 获取有效的Session ID(如在网络传输中截获)
- 该Session尚未过期(用户未登出/浏览器未关闭)
- 示例演示了通过修改PHPSESSID实现身份冒用
-
防护建议 :
- 绑定Session与客户端特征(如IP、User-Agent)
- 设置
HttpOnly和Secure属性防止XSS窃取 - 重要操作使用二次验证(如短信验证码)
4. Cookie与Session的区别 3982000

- 存储位置:
- Cookie存储在客户端浏览器上,存在被黑客窃取的风险
- Session存储在服务器端,安全性更高
- 存储容量:
- Cookie限制为4KB大小
- Session理论上无限制,取决于服务器配置
- 生命周期:
- Cookie可设置过期时间,关闭浏览器后仍存在
- Session默认在浏览器关闭后失效
- 访问方式:
- Cookie可通过JavaScript访问
- Session只能在服务器端访问
- 使用场景:
- Cookie适合存储小型数据如用户名密码
- Session适合存储购物车、登录状态等大型数据
1)判断Cookie和Session的技巧 3985000

- 时间测试法:
- 登录后保持页面不动30分钟
- 刷新后需要重新登录→Session验证
- 仍保持登录状态→Cookie验证
- 浏览器关闭测试:
- 关闭后重新打开仍登录→Cookie
- 需要重新登录→Session
- 数据包分析法:
- 检查请求数据包中是否有Session ID标识
- 但注意某些Cookie也可能包含类似标识
2)Token的唯一性 4151000

- 核心特性:
- 每次请求生成唯一标识值
- 防止数据包重放攻击
- 生成方式:
- 使用随机字符串生成算法
- 示例代码:
$token = bin2hex(random_bytes(16)) - 验证流程:
- 服务器生成Token并存入Session
- 通过隐藏表单域发送给客户端
- 客户端提交时携带Token
- 服务器比对Session中的Token值
- 安全影响:
- 有效防御暴力破解攻击
- 每次请求需要新的有效Token
- 影响CSRF等漏洞利用

- 典型实现:
- 登录表单添加隐藏Token字段
- 服务器端进行三重验证:
- 用户名密码正确性
- Token值是否匹配
- Token是否存在于Session
- 调试技巧:
- 通过浏览器开发者工具查看Token变化
- 每次刷新页面Token值都会改变
- 错误的Token会导致"登录失败"提示
二、抓包登录 5217000

- Token生成 :使用PHP的
random_bytes()函数生成16字节随机数,并通过bin2hex()转换为十六进制字符串 - Session存储 :通过
$_SESSION['token'] =$token将Token存入服务器端Session - Cookie设置 :使用
setcookie()函数将Token存入客户端Cookie,设置1小时有效期(3600秒)
1. 访问控制流程

- C型匹配检查:
- 不匹配处理:直接禁止访问,作为第一道安全防线
- 匹配处理:通过后才会进入登录判断流程
- 安全检测工具:使用Burp Suite进行被动爬取和实时审计,检测HTTPS响应缓存、传输安全策略等问题
2. 登录测试过程
- 测试步骤:
- 进行登录尝试
- 观察系统响应
- 重复测试验证稳定性
- 调试方法:通过检查网页代码和网络请求详情定位问题
3. 请求包分析

- 抓包操作:
- 成功捕获登录请求包
- 验证管理员身份响应
- 爆破实验准备:
- 将有效请求包发送到Intruder模块
- 遇到请求重复问题需重新调试
4. 调试问题处理
- 常见问题:
- 请求重复("灯重"现象)
- 代码缺失导致功能异常
- 解决方法:
- 完整复制功能代码段
- 回退到已知正常版本
- 检查Token验证逻辑完整性
- 经验总结:实验前应确保基础功能正常,避免在调试环节消耗过多时间
三、登录爆破 5363000
1. 登录爆破演示 5365000

- 爆破现象:直接访问提示"登录失败",使用爆破模块将密码作为支点进行测试时,所有返回结果均为"登录失败"
- 典型错误:爆破时未正确处理token机制,导致所有尝试都被服务器拒绝
2. 登录爆破token问题排查 5451000

- 核心机制 :系统通过比较COOKIE[′token′]和_COOKIE['token']和COOKIE[′token′]和_SESSION['token']进行验证
- 验证流程:
- 不匹配时返回403禁止访问状态码
- 匹配时才进行用户名密码校验(admin/123456)
- 常见错误:第二次提交数据包时token失效,导致验证失败
3. 登录爆破token问题解决 5583000

- 解决方法:
- 清除所有cookie
- 重启服务器
- 刷新token值
- 关键点:确保每次请求都携带有效的token值
4. 登录爆破token值判断 5671000

- 验证逻辑:
- 从cookie获取token值:
$token =$_COOKIE['token'] ?? '' - 与session中的token比较:
if ($token !=$_SESSION['token']) - 防御效果:有效防止重放攻击,使爆破工具无法重复使用同一token
5. 登录爆破token值判断代码编写 5713000

- **代码结构
- 注意事项:必须确保session_start()在所有输出之前调用
6. 登录爆破token值判断代码编写问题01:36:00

- 问题发现:仅验证cookie token而忽略表单提交的csrf_token
- 风险:可能导致CSRF攻击,表单提交缺少二次验证
7. 登录爆破token值判断代码编写问题解决01:36:18

- 解决方案:增加表单token验证
- 验证逻辑:要求cookie和表单中的token必须同时匹配session中的值
8. 登录爆破token值判断代码编写问题再解决01:37:27

- 调试技巧:
- 打印
SESSION和_SESSION和SESSION和
_COOKIE值进行比对 - 检查token生成和存储的时序问题
- 打印
- 常见错误:token生成时间晚于验证时间导致空值比较
9. 登录爆破token值判断代码编写问题确认01:39:00

- 最终方案:采用POST提交的csrf_token进行主要验证
- 优点:更符合CSRF防护的最佳实践,减少对cookie的依赖
10. 登录爆破token值判断代码编写问题确认解决01:40:20

- 防护效果:
- 错误的csrf_token直接返回403
- 即使密码正确也无法绕过token验证
- 测试结果:成功阻止所有未携带正确token的爆破尝试
11. 登录爆破token值判断代码编写问题确认解决再验证01:41:03

- 完整验证链:
- 检查csrf_token是否匹配session
- 验证用户名密码
- 双重验证通过才返回成功
- 关键结论:必须同时满足POST[′csrftoken′]==_POST['csrf_token'] ==POST[′csrftoken′]==_SESSION['token']和正确的用户名密码才能登录成功
四、数据包唯一性01:42:00
1. 示例分析

- Token生成原理:
- 使用PHP的random_bytes()函数生成16字节随机数
- 通过bin2hex()转换为32位十六进制字符串
- 同时存储在SESSION和_SESSION和SESSION和_COOKIE中(有效期3600秒)
- 验证流程:
- 表单提交时携带隐藏字段
- 服务器比对表单token与session中存储的是否一致
- 防御效果:
- 阻止暴力破解:攻击者无法预知下一次请求的token值
- 防御CSRF攻击:第三方网站无法获取有效token
- 阻止重放攻击:每个token仅单次有效

- 典型场景:
- 脚本攻击时固定token值会导致所有请求被拒绝
- 即使账号密码正确,缺少有效token也无法通过验证
- 技术本质:
- 服务端为每个会话生成唯一标识符
- 客户端必须在每次请求时携带当前有效token
- 实现"一次一密"的安全机制
五、结束01:50:25

- 渗透测试注意:
- 检查请求参数中是否存在token、csrf_token等字段
- 观察响应头中是否设置Set-Cookie更新token
- 验证token是否具有时效性和唯一性
- 绕过限制:
- 需要先获取有效会话获取初始token
- 保持会话活性以持续获取新token
- 无法进行完全自动化的批量攻击
六、知识小结
| 知识点 | 核心内容 | 技术要点 | 安全关联性 |
| Cookie技术 | 用户身份验证技术,存储在客户端浏览器 | 设置/读取Cookie流程、过期时间设置 | 易被窃取,XSS攻击主要目标 |
| Session技术 | 服务器端会话管理,关闭浏览器失效 | session_start()、$_SESSION变量 | 相对安全,但服务器负担大 |
| Token技术 | 请求唯一性验证机制 | 随机字符串生成、表单隐藏域传递 | 防CSRF/暴力破解,需服务端校验 |
| Cookie与Session对比 | 存储位置(客户端/服务端)、生命周期(长期/临时) | 实现方式( COOKIE/_COOKIE/COOKIE/ _SESSION) | 安全测试方法不同(客户端/服务端) |
| Token验证流程 | 1. 生成随机Token 2. 绑定表单/会话 3. 双重校验 | mt_rand()生成、哈希算法加密 | 阻断自动化攻击,要求请求上下文一致 |
| 开发安全实践 | 1. 登录状态验证 2. 敏感操作二次验证 3. 防重复提交 | 包含文件安全、SQL预处理 | OWASP TOP10防护基础实现 |
| 典型漏洞场景 | 1. Cookie劫持 2. Session固定 3. Token预测 | 不安全的直接对象引用 | 身份验证缺陷导致垂直越权 |