金和OA saveAsOtherFormatServlet接口任意文件上传漏洞和多个SQL注入漏洞分析
字数 1638 2025-08-23 18:31:18
金和OA系统漏洞分析与利用教学文档
1. 系统架构分析
1.1 路由配置分析
通过分析web.xml配置文件,可以发现以下关键路由配置:
-
定义了一个名为"spring"的DispatcherServlet,映射路径为
/JHSoft.WCF/*- DispatcherServlet是Spring框架中的前端控制器,负责接收所有HTTP请求并转发到相应处理程序
- 任何匹配
/JHSoft.WCF/后跟任何内容的URL请求都将由spring Servlet处理
-
系统还配置了多个其他servlet及其映射,用于处理各种业务逻辑
2. saveAsOtherFormatServlet接口任意文件上传漏洞
2.1 漏洞位置
- Servlet继承自HttpServlet,通过processRequest方法处理GET和POST请求
- 关键路由:
/saveAsOtherFormatServlet
2.2 漏洞分析
-
文件名获取:
String fileName = request.getParameter("fileName"); // 从请求参数获取文件名,完全可控 -
上传服务获取:
IUploadService uploadService = (IUploadService) SpringContextUtil.getBean("uploadService");- IUploadService是文件上传相关服务接口
- 实现类提供了文件上传和附件管理的完整业务逻辑
-
业务类型处理:
- 从请求获取业务类型参数,默认为"公文正文"
- 当业务类型不是"infoContent"时,执行
uploadService.getAttachmentList
-
上传路径构造:
realPath = request.getSession().getServletContext().getRealPath("/upload/gwzw");- 最终上传路径为web应用根目录 + "/upload/gwzw" + 上传文件名
- 文件名完全可控
-
文件上传处理:
- 使用Apache Commons FileUpload组件解析请求
- 关键写入代码:
FileOutputStream fos2 = new FileOutputStream(new File(realPath + File.separator + fileName)); - 直接将上传内容写入指定文件,无任何过滤
2.3 漏洞复现
- 构造POST请求到
/saveAsOtherFormatServlet - 包含以下参数:
- fileName: 可控文件名(可包含路径遍历如../../)
- FileBlod: 上传的文件内容
- 系统会将文件写入web目录的
/upload/gwzw下,文件名和路径完全可控
3. clobfield接口SQL注入漏洞
3.1 漏洞位置
- 关键路由:
/clobfield - 相关类:clobfield1
3.2 漏洞分析
-
初始化:
// 从Spring上下文获取JdbcTemplate实例 this.jt = (JdbcTemplate)SpringContextUtil.getBean("jdbcTemplate"); -
参数处理:
- 从请求获取多个参数并设置到clobfield1实例属性
- 根据strKey参数决定读/写操作
-
SQL注入点:
stat.execute("select " + this.sImgname + " from " + this.sTablename + " where " + this.sKeyname + "='" + this.sKeyvalue + "'");- 所有参数直接拼接进SQL语句
- 使用Statement而非PreparedStatement
- 无任何参数过滤或预编译
3.3 漏洞复现
- 构造请求到
/clobfield - 控制以下参数实现注入:
- sImgname: 可控SELECT字段
- sTablename: 可控表名
- sKeyname: 可控WHERE条件字段
- sKeyvalue: 可控WHERE条件值(主要注入点)
- 示例:查询数据库版本
sKeyvalue=1' union select version() --
4. GetAttOut接口SQL注入漏洞
4.1 漏洞位置
- 关键路由:
/JHSoft.WCF/TEST/GetAttOut - 使用Spring的@RequestMapping注解定义
4.2 漏洞分析
-
请求处理:
String jsonStr = readStream(request.getInputStream()); String keyId = jsonStr.replaceAll("\"", ""); -
SQL注入点:
EformReturnJson re = this.eformService.execSqlReList("select * from outwork where keyid='" + keyId + "'");- 用户输入直接拼接进SQL语句
-
数据库操作:
// 虽然使用了prepareStatement,但无参数化查询 PreparedStatement ps = con.prepareStatement(sql); ResultSet rs = ps.executeQuery();- 只是形式上的预编译,实际SQL语句无占位符
- 等同于直接执行拼接后的SQL
4.3 漏洞复现
- 构造POST请求到
/JHSoft.WCF/TEST/GetAttOut - 请求体包含JSON格式的keyId参数:
{"1' union select version() -- "} - 系统会执行拼接后的SQL语句,返回注入结果
5. 漏洞修复建议
-
文件上传漏洞:
- 对文件名进行严格过滤,禁止路径遍历字符
- 限制上传文件类型
- 使用随机生成的文件名存储
-
SQL注入漏洞:
- 使用参数化查询(PreparedStatement with ?)
- 对输入参数进行严格过滤和类型检查
- 实施最小权限原则,限制数据库账户权限
-
通用建议:
- 升级到最新安全版本
- 实施WAF防护
- 定期进行安全审计和渗透测试