记一次完整的net代码审计
字数 2925 2025-09-23 19:27:46
.NET 代码审计实战教学文档
一、 环境准备与反编译
- 目标形式:审计目标并非原始项目源代码(
.cs),而是编译后生成的一堆DLL程序集。 - 必要工具:使用.NET反编译工具(如
dnSpy,ILSpy,dotPeek)对这些DLL文件进行批量反编译,将其还原为可读的C#代码,以便进行后续的代码审计分析。
二、 鉴权机制深度分析
这是本次审计的核心,发现了多处权限控制缺陷。
1. API 权限控制 (相对规范)
- 位置:继承自
ApiController的控制器(如APPController)中的大部分API方法。 - 机制:采用
请求头(Header)token 校验+Authorize属性进行服务端鉴权。 - 流程:请求必须包含有效的token,并通过
Authorize逻辑验证。鉴权通过后才执行业务逻辑;失败则直接返回错误信息,流程规范。
2. MVC Controller 权限风险 (严重缺陷)
- 位置:MVC Controller 中的大量动作(Action)。
- 缺陷:大量方法使用了
[IgnoreRightFilter]特性标签。 - 后果:此标签导致这些接口完全绕过了系统统一的权限过滤器,支持匿名访问,无需任何身份认证。
- 受影响接口举例:
- 内容管理类:如
NewsManage/UploadNewsImg(新闻图片上传)。 - 开关查询类:如
Swicth/*路径下的多数查询接口。 - 数据导出与统计类:如各种数据导出、统计报表、地图数据接口。
- 内容管理类:如
3. 会话(Session)管理不规范
- 现象:系统响应中存在
ASP.NET_SessionId会话标识符。 - 问题:会话机制未被有效利用于鉴权或授权。大多数接口不依赖Session进行权限判断,导致:
- 会话资源被浪费。
- 无法通过Session机制增强身份验证的安全性(如防止会话固定、维护登录状态等)。
4. 鉴权机制总结
- API 控制器:部分使用Header token鉴权,逻辑简单(读Header -> 调用
Authorize),但相对完整。 - MVC 控制器:因滥用
IgnoreRightFilter,导致统一权限过滤器失效,产生大量未授权访问漏洞。并且,某些接口返回的URL直接指向Web根目录,可能泄露敏感路径信息。
三、 漏洞分析
漏洞一:未授权+后缀可控文件上传 (高危 - RCE)
-
漏洞位置:
- 服务层:
JuCheap.Services.decompiled.cs文件中的EventApi类 ->uploadFileTemp方法。 - 控制器:
uploadAttachment方法位于继承ApiController的APPController中。
- 服务层:
-
漏洞描述:
- 鉴权缺失:
uploadFileTemp方法未使用前述的Header token+Authorize鉴权机制,允许匿名访问。 - 参数可控:
fileFormat参数:完全控制最终保存的文件后缀名。fileStr参数:接收Base64编码的文件内容。
- 危险操作:将Base64解码后的内容直接写入磁盘,保存路径为站点根目录下的
/UpLoad/EventPic/。 - 返回信息:上传成功后,接口会返回文件的完整访问URL。
- 鉴权缺失:
-
攻击链:
- 攻击者构造一个Base64编码的Web Shell(如ASPX木马)。
- 通过
fileFormat参数指定后缀为.aspx。 - 直接请求该接口(无需认证)上传文件。
- 根据返回的URL直接访问上传的ASPX文件,即可获得服务器命令执行权限。
-
文件名生成:由时间戳+4位随机数组成,难以预测,但返回的URL使其无需预测。
-
完整路由:由于控制器继承
ApiController,其默认路由带有/api/前缀,故完整攻击路径为:/api/APP/uploadAttachment。
漏洞二:未授权文件上传 (另一处)
- 漏洞位置:
JuCheap.Web.decompiled.cs - 漏洞描述:找到另一处文件上传逻辑,未对上传操作进行任何限制(如类型、大小、权限),导致前台用户可直接上传文件。需跟进保存代码确认最终危害。
漏洞三:未授权文件上传 (又一处)
- 漏洞位置:
- 控制层:
JuCheap.Web.decompiled.cs(定义上传请求参数)。 - 服务层:
JuCheap.Services.decompiled.cs(实现上传完整流程)。
- 控制层:
- 漏洞描述:再次发现一处文件上传实现,需分析其保存逻辑判断具体风险。
漏洞四:SQL注入漏洞 (高危)
- 漏洞定位:通过全局搜索定位到关键函数
MainMonitor。 - 漏洞原因:在服务层代码中,发现直接使用字符串拼接用户输入的数据来构造SQL查询语句。
- 漏洞描述:未使用参数化查询(如
SqlParameter)或任何有效的输入过滤与编码,导致用户输入被当作SQL代码的一部分执行,从而产生SQL注入漏洞。 - 复现:找到对应的接口,构造恶意的SQL注入参数即可利用。
四、 审计方法论总结
- 入口定位:从鉴权机制入手(
[Authorize],[IgnoreRightFilter], 自定义Filter),快速定位匿名接口和高权限接口。 - 敏感功能跟踪:重点关注文件上传、数据查询、命令执行、反序列化等高风险功能点。
- 数据流分析:跟踪用户输入参数(如
fileFormat,fileStr)的传递过程,直到其被最终使用(如写入文件、拼接SQL),判断是否存在过滤或编码。 - 工具辅助:善用反编译工具的全局搜索、分析调用、查找用法等功能,快速定位关键代码。
- 路由识别:区分
ApiController(路由常带/api/) 和普通MVC Controller的路由规则,确保测试覆盖所有端点。
五、 修复建议
- 鉴权:
- 移除不必要的
[IgnoreRightFilter]。 - 为所有需要认证的接口添加统一的鉴权机制。
- 考虑使用ASP.NET Core的 Identity 或成熟的权限管理框架。
- 移除不必要的
- 文件上传:
- 实施强认证与授权检查。
- 使用白名单严格限制允许上传的文件后缀类型。
- 对文件内容进行二次校验(如检查文件头),不能仅依赖后缀名。
- 将文件上传到Web根目录之外或配置服务器禁止直接执行上传目录下的脚本。
- 避免返回完整的物理路径或可直接访问的URL。
- SQL注入:
- 全面改用参数化查询(Parameterized Queries)。
- 使用ORM框架(如Entity Framework)替代原生SQL拼接。
- 如果必须拼接,需对输入进行严格的过滤或转义。
- 会话管理:建立并强制执行基于Session的认证和授权策略,或采用JWT等无状态令牌机制。