记一次对某oa的代码审计
字数 2576 2025-10-01 14:05:44
某OA系统代码审计与安全漏洞分析教学文档
1. 系统架构分析
1.1 技术框架
- WebForms架构:采用渐进式迁移策略,关键业务页面逐步迁移至.NET MVC或.NET Core Razor Pages
- WebService架构:统一接口风格,逐步将ASMX和WCF服务迁移至ASP.NET Web API
- 混合框架:保留现有基础架构,通过Web API构建新功能,实现前后端分离
1.2 鉴权机制分析
ExtensionlessUrlHandler
- 功能:ASP.NET HTTP处理程序,处理无扩展名的URL
- URL路由支持:配合.NET路由系统实现RESTful风格URL
<!-- IIS 7.0+ 集成模式配置 -->
<system.webServer>
<handlers>
<add name="ExtensionlessUrlHandler-Integrated-4.0"
path="*."
verb="*"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
JHSoft.Log.HttpModule
- 功能:第三方/自定义HTTP模块,处理日志记录
- 主要功能:
- HTTP请求日志记录(URL、方法、参数、响应时间、状态码)
- 错误日志记录(未处理异常、错误堆栈信息、错误通知)
2. 安全漏洞分析
2.1 SQL注入漏洞
漏洞位置1:直接参数拼接
- 位置:多处DAL层代码
- 漏洞描述:页面直接读取查询参数IncentiveID和TVersion并传入BLL/DAL
- 根本原因:DAL层拼接SQL语句,未做参数化或类型校验
- 危险操作:直接将TPlanID、TVersion等参数拼接到SQL语句中
漏洞位置2:GetHomeInfo方法
- 位置:jhsoft.mobileapp/AndroidSevices/HomeService.asmx → GetHomeInfo → GetQuickUserInfo
- 漏洞类型:时间盲注可利用的SQL注入
- 根本原因:GetUserSex函数直接拼接userId参数到SQL查询字符串
// 漏洞代码示例
string userSex = GetUserSex(userID); // userId直接拼接进SQL
漏洞复现步骤:
- 构造恶意UNION/WAITFOR载荷
- 观察响应时间或返回结果
- 确认注入点有效性
2.2 文件读取漏洞
漏洞位置1:JHSoft.Web.AddMenu接口
- 漏洞描述:直接传递用户可控的path参数给DownLoad方法
- 危险代码:
// 直接使用用户输入,无过滤
string filePath = Server.MapPath(path);
if(File.Exists(filePath)) {
File.OpenRead(filePath); // 直接读取文件
Response.BinaryWrite(fileContent); // 输出文件内容
}
漏洞位置2:JHSoft.Web.CustomQuery/UploadFileDownLoadnew.aspx
- 触发条件:QueryString第一项fcform触发分支
- 漏洞机制:
- 用户传入FilePath参数拼接至../JHSoft.Web.Module/
- 未做白名单/根目录约束与穿越过滤
- 通过
\..组合进行目录穿越
路径穿越处理流程:
- 将路径中的
\\替换为/ ../替换为/的操作(但变形形式如/..../保持原样)- 最终形成
\\..\\危险路径
2.3 后台文件写入漏洞
漏洞位置:JHSoft.Web.Portal/EditMain.aspx
- 核心风险:外部输入未严格验证,可控制文件写入路径及内容
- 具体漏洞点:
1. add参数处理不当
- 仅简单将"|"替换为"\"
- 未进行路径规范化校验及权限边界检查
- 允许传入绝对路径或跨目录的相对路径
2. id参数验证缺失
- 直接拼接至"...Portal\Default"路径后作为文件路径
- 未实施白名单验证,未限制文件后缀名
- 可构造如"id=1.aspx"的恶意值创建ASPX文件
保存机制风险:
- 使用StreamWriter(FilePath, append: false)模式
- 目标文件已存在时先执行File.Delete再覆盖写入
- 可直接替换现有系统文件
2.4 XXE漏洞
漏洞位置:XML处理模块
- 根本原因:未对XmlDocument禁用DTD/外部实体解析
- 攻击向量:
- 外带请求(SSRF/DNSLOG)
- 本地文件泄露(file://协议)
- 实体扩展拒绝服务(Billion Laughs攻击)
漏洞代码流程:
- 初始化text和text2变量
- StreamReader读取请求输入流全部内容
- XmlDocument加载解析XML数据(未禁用外部实体)
- 遍历根节点子节点,拼接节点名和文本内容
- 直接拼接字段名和值构建INSERT语句(存在SQL注入)
3. 安全加固建议
3.1 SQL注入防护
- 参数化查询:全面采用参数化查询替代字符串拼接
- 输入验证:实施严格的白名单输入验证机制
- ORM框架:引入Entity Framework或Dapper等ORM框架
- 权限最小化:数据库账户遵循最小权限原则
3.2 文件操作安全
- 路径规范化:实施严格的路径规范化处理
- 白名单验证:文件操作基于白名单机制
- 目录限制:限制文件操作到特定安全目录
- 后缀名过滤:严格限制可操作的文件类型
3.3 XXE防护
- 禁用外部实体:明确禁用XML外部实体解析
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null; // 禁用解析器
- 安全配置:确保XML处理器安全配置
- 输入过滤:对XML输入内容进行严格过滤
3.4 架构优化建议
数据访问层优化:
- 引入仓储模式(Repository Pattern)隔离业务逻辑与数据访问
- 实现Unit of Work模式优化事务管理
- 建立数据访问性能监控机制
权限系统重构:
- 基于RBAC(角色基础访问控制)重构权限模型
- 将Fn_* SQL函数的权限计算逻辑迁移至应用层
- 实现细粒度权限控制,支持数据行级权限
文件上传服务:
- 构建统一的文件上传服务
- 实现完整的安全校验机制:
- 文件类型验证
- 大小限制
- 病毒扫描
- 引入分布式文件存储支持
4. 漏洞复现与测试
4.1 测试环境搭建
- 部署目标OA系统
- 配置调试环境
- 准备测试用例
4.2 测试用例设计
SQL注入测试:
- 正常参数输入测试
- 特殊字符注入测试
- 联合查询注入测试
- 时间盲注测试
文件操作测试:
- 路径穿越测试(../、..\、编码绕过)
- 绝对路径测试
- 文件类型绕过测试
XXE测试:
- 外部实体引用测试
- 文件读取测试
- 内网探测测试
5. 总结
本次代码审计发现了某OA系统存在的多重安全漏洞,包括SQL注入、文件读取、文件写入和XXE漏洞等。这些漏洞的根本原因在于输入验证不充分、直接拼接用户输入、缺乏安全配置等方面。
关键安全原则:
- 永远不要信任用户输入
- 实施深度防御策略
- 遵循最小权限原则
- 定期进行安全审计和代码复查
通过系统性的架构优化和安全加固,可以显著提升系统的安全防护能力,防止类似安全漏洞的发生。