记一次代码审计过程
字数 1546 2025-08-09 19:58:05
代码审计实战教学:从XSS到文件上传漏洞挖掘
前言声明
- 本教学文档仅供技术研究学习使用
- 严禁用于任何非法操作
- 欢迎指出任何技术错误或不足之处
审计环境搭建
- 本地搭建目标CMS系统
- 准备代码审计工具(如静态代码分析工具)
- 获取目标系统源码(提取码:rbd0)
漏洞一:存储型XSS漏洞挖掘
漏洞发现过程
- 目标定位:发现系统中存在公司名称输入点
- 初步判断:该输入点可能存在XSS漏洞
- 审计工具辅助:使用工具辅助分析可疑代码段
代码分析
// 发现可疑代码段
$lang->install // 这是一个实例化的类
-
变量追踪:
- 查找
$lang->install的定义和使用位置 - 发现该变量直接输出到页面,未经过滤
- 查找
-
关键代码:
// 直接输出变量,存在XSS风险 echo $someVariable;
漏洞验证
- 构造XSS payload(如
<script>alert(1)</script>) - 提交到公司名称输入点
- 验证payload是否被存储并执行
漏洞特点
- 存储型XSS:恶意脚本被存入数据库
- 持久性攻击:每次访问相关页面都会触发
- 危害等级:高危,可窃取用户会话等
漏洞二:文件上传绕过漏洞
漏洞发现过程
- 常规思路:寻找系统中的文件上传功能
- 定位源码:
- 通过前端代码查找调用的函数
- 分析上传处理逻辑
代码分析流程
-
关键函数调用链:
uploadFile() -> loadModel() -> getupload() -> getExtension() -
上传过滤机制:
// 文件后缀名处理函数 function getExtension() { // 黑名单过滤 // 白名单过滤 // 强制后缀名判断 } -
黑白名单分析:
- 黑名单:包含常见危险扩展名(如.php)
- 白名单:只允许特定安全扩展名
漏洞原理
原因一:逻辑缺陷绕过
- 第一个if判断后缀名为空时,后续检查被跳过
- 利用"与逻辑"特性(一个为假则全假)
- 导致黑白名单和强制后缀名检查被绕过
原因二:服务器配置问题
- 存在
.htaccess文件强制解析无后缀文件为PHP - 典型配置内容:
<FilesMatch "^[^\.]+$"> SetHandler application/x-httpd-php </FilesMatch>
漏洞验证方法
- 上传无后缀文件或添加额外点(如"test.php.")
- 访问上传文件验证是否以PHP执行
- 检查服务器返回的文件类型
完整审计流程总结
-
信息收集:
- 了解系统架构
- 识别关键功能模块
-
输入点定位:
- 用户可控输入
- 文件上传点
- API接口等
-
代码追踪:
- 变量传递路径
- 函数调用链
- 数据处理流程
-
过滤机制分析:
- 输入过滤
- 输出编码
- 安全函数使用
-
漏洞验证:
- 构造测试payload
- 验证漏洞存在性
- 评估危害程度
防御建议
针对XSS
- 所有输出进行HTML实体编码
- 实施Content Security Policy (CSP)
- 使用安全的模板引擎
针对文件上传
- 修复逻辑缺陷:确保所有检查都执行
- 文件类型检查:
- 使用MIME类型检测
- 结合文件头校验
- 服务器配置:
- 禁用危险解析规则
- 上传目录禁止脚本执行
- 文件重命名:
- 使用随机文件名
- 强制添加安全后缀
经验总结
-
审计技巧:
- 善用代码搜索功能快速定位关键代码
- 结合前后端代码分析完整流程
- 注意框架和自定义函数的安全影响
-
常见问题:
- 逻辑顺序错误导致安全检查绕过
- 服务器配置不当引入额外风险
- 过滤不彻底(如只过滤单种攻击向量)
-
提升方向:
- 深入理解编程语言特性
- 学习常见框架的安全机制
- 掌握更多代码静态分析方法
附录
常见危险函数列表
| 函数类型 | 示例函数 | 风险 |
|---|---|---|
| 文件操作 | fopen(), include() | 文件包含/读取 |
| 命令执行 | system(), exec() | RCE |
| 数据库操作 | mysql_query() | SQL注入 |
| 序列化 | unserialize() | 反序列化漏洞 |
推荐审计工具
- 静态分析工具:SonarQube, Fortify
- 动态分析工具:Burp Suite, OWASP ZAP
- 代码搜索工具:ripgrep, ack
学习资源
- OWASP Top 10
- PHP安全编程指南
- 常见CMS漏洞分析报告