前些日子这个洞刚出的时候几乎通杀,有幸拿到了源码,就来分析一下

代码审计

权限绕过

首先是一个权限绕过问题,看到配置文件 cas-client.properties

发现cas.ignore.pattern,很明显存放的就是绕过权限的路径,全局查找一下
看到bic-sso-client-1.6.9.4.RELEASE.jar!/com/hikvision/sso/client/config/util/CasClientConfig.class

全局查找调用CasClientConfig.getCasClientConfig方法的类,看到bic-sso-client-1.6.9.4.RELEASE.jar!/org/jasig/cas/client/util/AbstractConfigurationFilter.class的 getPropertyFromInitParams 方法

那么就找下什么时候 propertyName 的值为 ignorePattern
bic-sso-client-1.6.9.4.RELEASE.jar!/org/jasig/cas/client/authentication/AuthenticationFilter.class
看名字就知道是身份认证的 Filter

在 initInternal 初始化的时候获取到cas.ignore.pattern的值 ,然后存储到 ignoreUrlPatternMatcherStrategyClass 中

看到它的 doFilter 方法,如果this.isRequestUrlExcluded(request)为true,直接绕过鉴权

跟进 isRequestUrlExcluded 方法

发现使用的是 getRequestUrl 方法获取的url路径,然后 matches 方法进行匹配
而这个方法与 Tomcat 的解析刚好会存在安全问题:
Tomcat URL解析差异性导致的安全问题
tomcat容器url解析特性研究

Tomcat中的URL解析是支持嵌入./../;等特殊字符的
此外,getRequestURL() 和 getRequestURI() 这两个函数解析提取的URL内容是包含我们嵌入的特殊字符的,当使用不当时会存在安全问题如绕过认证

跟进发现是使用正则表达式进行匹配的

如果满足正则匹配,就会绕过权限认证,最终得到如下payload

1
2
3
4
5
;.js
;.svg
;.ttf
/center/api/fileUpload/..;/
/center/api/task/..;/

等等方法都是可以用的,随便列举一个

任意文件上传

没有了权限限制,就有很多操作点了,先来看到爆出的任意文件上传漏洞
center/WEB-INF/classes/com/hikvision/center/module/faq/controller/KnowledgeController.class

调用 uploadFile 方法上传文件,并返回结果
center/WEB-INF/classes/com/hikvision/center/module/faq/service/impl/KnowledgeServiceImpl.class

可以看到直接使用 transferTo 方法上传文件,没有任何限制,并且对文件名进行了拼接,导致可以跨目录传文件

我们将文件放在 clusterMgr 目录下,就可以成功访问了

任意文件读取

看到center/WEB-INF/classes/com/hikvision/center/module/personmanage/controller/OrganizationController.class

这里获取GET传参fileName

然后直接进行的拼接,导致可以跨越目录读文件

1
/center/api/task/..;/orgManage/v1/orgs/download?fileName=../../../../../../../etc/passwd

后渗透利用

一般拿到shell了,就需要更进一步的利用

数据库密码解密

看到center/WEB-INF/classes/com/hikvision/center/config/jpa/GeeQueryConfig.class

发现是使用的postgresql数据库,并且看到数据库密码是先base64解密,然后使用Authentication.transDataDecrypt解密的
这里opsmgr.database.passwordconfig.properties配置文件中

跟进bic-iii-1.1.9.jar!/com/hikvision/hik/crypt/Authentication.class

1
2
3
public static byte[] transDataDecrypt(byte[] SData) throws CryptErrorException {
return IIIAESUtils.transDataDecrypt(SData);
}

那么就看到bic-iii-1.1.9.jar!/com/hikvision/hik/crypt/IIIAESUtils.class

解密核心是使用的System.load加载配置文件 Identify.dll 或者 libIdentify.so ,然后使用内部的方法进行解密
那么解密就很简单了,加载 .jar 依赖,然后调用方法即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import com.hikvision.hik.crypt.Authentication;
import sun.misc.BASE64Decoder;

public class Main {
public static String transDataDecrypt(String data) {
try {
BASE64Decoder decoder = new BASE64Decoder();
return new String(Authentication.transDataDecrypt((decoder.decodeBuffer(data))), "UTF-8");
} catch (Exception var2) {
var2.printStackTrace();
return null;
}
}

public static void main(String[] args) {
String password = transDataDecrypt("EQAQAHaQSvAuuQmMvRUpfoWt4scoTMSSkftYgn9qXVDvr28p6c0wP3LXDMFTZgJEWJS+Ug==");
System.out.println(password);
}
}

最后使用天蝎连接数据库,驱动:org.postgresql.Driver

参考工具:https://github.com/wafinfo/Hikvision