Default jwt information leaks to RCE

dobbo- admin Default jwt information leaks to RCE

​ 年前挖的,apache没给cve,就出了个公告。没意思

0x01 analysis

org/apache/dubbo/admin/utils/JwtTokenUtil.java#generateToken()

1
2
3
4
5
6
7
8
9
10
public String generateToken(String rootUserName) {
Map<String, Object> claims = new HashMap<>(1);
claims.put("sub", rootUserName);
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.setIssuedAt(new Date(System.currentTimeMillis()))
.signWith(defaultAlgorithm, secret)
.compact();
}

Here is how jwttoken handles it, including authentication time, expiration time, username.

org/apache/dubbo/admin/utils/JwtTokenUtil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
* Jwt signingKey configurable
*/
@Value("${admin.check.signSecret:}")
public String secret;

/**
* token timeout configurable
* default to be an hour: 1000 * 60 * 60
*/
@Value("${admin.check.tokenTimeoutMilli:}")
public long expiration;

/**
* default SignatureAlgorithm
*/
public static final SignatureAlgorithm defaultAlgorithm = SignatureAlgorithm.HS512;

This class defines fixed secret, expiration, default algorithms. Now that we know the encryption method, we can use fake jwt to log in and bypass it.

​ @Value(“${admin.check.signSecret:}”).

The default key in the configuration.

image-20240128002238330

org/apache/dubbo/admin/authentication/impl/DefaultPreHandle.java#authentication()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 public boolean authentication(HttpServletRequest request, HttpServletResponse response, Object handler) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
Authority authority = method.getDeclaredAnnotation(Authority.class);
if (null == authority) {
authority = method.getDeclaringClass().getDeclaredAnnotation(Authority.class);
}

String token = request.getHeader("Authorization");

if (null != authority && authority.needLogin()) {
//check if 'authorization' is empty to prevent NullPointException
if (StringUtils.isEmpty(token)) {
//While authentication is required and 'Authorization' string is missing in the request headers,
//reject this request(http403).
AuthInterceptor.authRejectedResponse(response);
return false;
}
if (jwtTokenUtil.canTokenBeExpiration(token)) {
return true;
}
//while user not found, or token timeout, reject this request(http401).
AuthInterceptor.loginFailResponse(response);
return false;
} else {
return true;
}
}
}

Here you can analyze it, get jwt from Authorization, and then determine the expiration time. Now we have a way to encrypt it, which is for a long-term jwt.

The jwt of the 99999999999 timestamp finally constructed.

1
eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjk5OTk5OTk5OTksInN1YiI6InJvb3QiLCJpYXQiOjE2OTkwODM2Mzd9.wKRqJkWxr_nVDcVVF5rniqhnACtqaDnYUUu55g-atkIwRIt1A-SMpKqBN5zrGZl4kFVcrjzMvXsYqfqf0N9Gbg

0x03 exploits

There is already a jwt that does not expire, that can be tried using

In org.apache.dobo.admin.controller

image-20240128004005909

You can view all services.

image-20240128004030376

image-20240128004100330

Then according to the name of the service, you can query the details of the corresponding service

image-20240128004538744

You can get the address of the service, dubbo version, hessian protocol, method, and type of value passed.

Think about whether you can find dubbo versions of vulnerabilities that cause exploits.

0x04 exploit

This service is dobbo-admin’s own service. We register one ourselves.

Here we directly use the dubbo official website example to register.

image-20240128010015233

org.apache.dubbo.samples.api.HelloService

image-20240128012244192

Query service details.

image-20240128010234284

The method parameter. The most important is the version, 3.0.13.

Then we know Apache Dubbo CVE-2023-23638. Check for Serializable interfaces. This option is enabled by default in>= 3.1.6, which prevents the serialization and deserialization of non-Serializable interface implementation classes. Apache mailist content can be found to be vulnerable to ‘Generic Invoke’, that is, generalized calls. In simple terms, generalized invocation allows us to invoke a method of the corresponding Service without relying on a specific interface API.

For more information on generalization calls, please see: https://cn.dubbo.apache.org/zh-cn/overview/tasks/develop/generic/

Generic Invoke This example has ready-made code and is ready to use.

Some need to configure the qos.Port, read out the specific information.

Configure the information, start attacking and exploiting

image-20240916194023601 Duboob generalization is attackable.

0x05 summary

     Use jwt to view services in the background, and use interfaces to view service details.  If the dubbo used by the microservice is a vulnerable version, an attack using GenericService can be attempted.  Examples of websites are available.  However, microservices are generally placed on the intranet and are suitable for intranet penetration.  Attack difficulty is high.  In essence, too much information was leaked. 

Default jwt information leaks to RCE
https://unam4.github.io/2024/09/16/dubbo-admin-JWT2RCE/
作者
unam4
发布于
2024年9月16日
许可协议