Author：Longofo@ Knownsec 404 Team
Time: April 8, 2020
Chinese version:https://paper.seebug.org/1166/

Nexus Repository Manager 3 recently exposed two El expression parsing vulnerabilities, cve-2020-10199 and cve-2020-10204, both of which are found by GitHub security Lab team's @pwntester. I didn't track the vulnerability of nexus3 before, so diff had a headache at that time. In addition, the nexus3 bug and security fix are all mixed together, which makes it harder to guess the location of the vulnerability. Later, I reappeared cve-2020-10204 with @r00t4dm, cve-2020-10204 is a bypass of cve-2018-16621. After that, others reappeared cve-2020-10199. The root causes of these three vulnerabilities are the same. In fact, there are more than these three. The official may have fixed several such vulnerabilities. Since history is not easy to trace back, it is only a possibility. Through the following analysis, we can see it. There is also the previous CVE-2019-7238, this is a jexl expression parsing, I will analyze it together here, explain the repair problems to it. I have seen some analysis before, the article said that this vulnerability was fixed by adding a permission. Maybe it was really only a permission at that time, but the newer version I tested, adding the permission seems useless. In the high version of Nexus3, the sandbox of jexl whitelist has been used.

Test Environment

• nexus-3.14.0-04
• nexus-3.21.1-01
• nexus-3.21.2-03

nexus-3.14.0-04 is used to test jexl expression parsing, nexus-3.21.1-01 is used to test jexl expression parsing and el expression parsing and diff, nexus-3.21.2-03 is used to test el expression Analysis and diff.

Vulnerability diff

The repair limit of CVE-2020-10199 and CVE-2020-10204 vulnerabilities is 3.21.1 and 3.21.2, but the github open source code branch does not seem to correspond, so I have to download the compressed package for comparison. The official download of nexus-3.21.1-01 and nexus-3.21.2-03, but beyond comparison requires the same directory name, the same file name, and some files for different versions of the code are not the same. I first decompiled all the jar packages in the corresponding directory, and then used a script to replace all the files in nexus-3.21.1-01 directory and the file name with 3.21.1-01 to 3.21.2-03, and deleted the META folder, this folder is not useful for the vulnerability diff and affects the diff analysis, so it has been deleted. The following is the effect after processing:

If you have not debugged and familiar with the previous Nexus 3 vulnerabilities, it may be headache to look at diff. There is no target diff.

Routing and corresponding processing class

General routing

Grab the packet sent by nexus3, random, you can see that most requests are POST type, URI is /service/extdirect:

The content of the post is as follows:

{"action":"coreui_Repository","method":"getBrowseableFormats","data":null,"type":"rpc","tid":7}

We can look at other requests. In post json, there are two keys: action and method. Search for the keyword "coreui_Repository" in the code:

We can see this, expand and look at the code:

The action is injected through annotations, and the method "getBrowseableFormats" in the post above is also included, the corresponding method is injected through annotations:

So after such a request,It is very easy to locate routing and corresponding processing class.

API routing

The Nexus3 API also has a vulnerability. Let's see how to locate the API route. In the admin web page, we can see all the APIs provided by Nexus3:

look at the package, there are GET, POST, DELETE, PUT and other types of requests:

Without the previous action and method, we use URI to locate it, but direct search of /service/rest/beta/security/content-selectors cannot be located, so shorten the keyword and use /beta/security/content-selectors to locate:

Inject URI through @Path annotation, the corresponding processing method also uses the corresponding @GET, @POST to annotate.

There are may be other types of routing, but you can also use a similar search method to locate. There is also the permission problem of Nexus. You can see that some of the above requests set the permissions through @RequiresPermissions, but the actual test permissions are still prevailing. Some permissions are also verified before arrival. Some operations are on the admin page, but it may not require admin permissions, may be no need permissions or only ordinary permissions.

Several Java EL vulnerabilities caused by buildConstraintViolationWithTemplate

After debugging CVE-2018-16621 and CVE-2020-10204, I feel that the keyword buildConstraintViolationWithTemplate can be used as the root cause of this vulnerability, because the call stack shows that the function call is on the boundary between the Nexus package and the hibernate-validator package, and the pop-up of the calculator is also after it enters the processing flow of hibernate-validator, that is, buildConstraintViolationWithTemplate (xxx) .addConstraintViolation (), and finally expressed in the ElTermResolver class in the hibernate-validator package through valueExpression.getValue (context) :

So I decompile all jar packages of Nexus3, and then search for this keyword (use the repair version search, mainly to see if there are any missing areas that are not repaired; Nexue3 has some open source code, you can also search directly in the source code):

F:\compare-file\nexus-3.21.2-03-win64\nexus-3.21.2-03\system\com\sonatype\nexus\plugins\nexus-healthcheck-base\3.21.2-03\nexus-healthcheck-base-3.21.2-03\com\sonatype\nexus\clm\validator\ClmAuthenticationValidator.java:
27        } else {
28:          context.buildConstraintViolationWithTemplate("unsupported annotated object " + value).addConstraintViolation();
29           return false;
30        }
..
35        case 1:
38           }
39
42           }
43
..
52           }
53
55           return false;
56        default:
57:          context.buildConstraintViolationWithTemplate("unsupported authentication type " + authenticationType).addConstraintViolation();
58           return false;
59        }

F:\compare-file\nexus-3.21.2-03-win64\nexus-3.21.2-03\system\org\hibernate\validator\hibernate-validator\6.1.0.Final\hibernate-validator-6.1.0.Final\org\hibernate\validator\internal\constraintvalidators\hv\ScriptAssertValidator.java:
34        if (!validationResult && !this.reportOn.isEmpty()) {
35           constraintValidatorContext.disableDefaultConstraintViolation();
37        }
38

F:\compare-file\nexus-3.21.2-03-win64\nexus-3.21.2-03\system\org\hibernate\validator\hibernate-validator\6.1.0.Final\hibernate-validator-6.1.0.Final\org\hibernate\validator\internal\engine\constraintvalidation\ConstraintValidatorContextImpl.java:
55     }
56
57:    public ConstraintViolationBuilder buildConstraintViolationWithTemplate(String messageTemplate) {
58        return new ConstraintValidatorContextImpl.ConstraintViolationBuilderImpl(messageTemplate, this.getCopyOfBasePath());
59     }

F:\compare-file\nexus-3.21.2-03-win64\nexus-3.21.2-03\system\org\sonatype\nexus\nexus-cleanup\3.21.0-02\nexus-cleanup-3.21.0-02\org\sonatype\nexus\cleanup\storage\config\CleanupPolicyAssetNamePatternValidator.java:
18           } catch (RegexCriteriaValidator.InvalidExpressionException var4) {
19              context.disableDefaultConstraintViolation();
21              return false;
22           }

F:\compare-file\nexus-3.21.2-03-win64\nexus-3.21.2-03\system\org\sonatype\nexus\nexus-cleanup\3.21.2-03\nexus-cleanup-3.21.2-03\org\sonatype\nexus\cleanup\storage\config\CleanupPolicyAssetNamePatternValidator.java:
18           } catch (RegexCriteriaValidator.InvalidExpressionException var4) {
19              context.disableDefaultConstraintViolation();
21              return false;
22           }

F:\compare-file\nexus-3.21.2-03-win64\nexus-3.21.2-03\system\org\sonatype\nexus\nexus-scheduling\3.21.2-03\nexus-scheduling-3.21.2-03\org\sonatype\nexus\scheduling\constraints\CronExpressionValidator.java:
29        } catch (IllegalArgumentException var4) {
30           context.disableDefaultConstraintViolation();
32           return false;
33        }

F:\compare-file\nexus-3.21.2-03-win64\nexus-3.21.2-03\system\org\sonatype\nexus\nexus-security\3.21.2-03\nexus-security-3.21.2-03\org\sonatype\nexus\security\privilege\PrivilegesExistValidator.java:

CVE-2020-10204 analysis

This is the bypass of the previous stripJavaEL repair mentioned above, and it will not be analyzed here. The use of the \$\\x{ format will not be replaced (tested with version 3.21.1):

CVE-2020-10199 analysis

This vulnerability corresponds to ConstraintViolationFactory in the search results above:

buildConstraintViolationWith (label 1) appears in the isValid of HelperValidator class (label 2), HelperValidator is annotated on HelperAnnotation (label 3, 4), HelperAnnotation is annotated on HelperBean (label 5), on ConstraintViolationFactory.createViolation HelperBean (labels 6, 7) is used in the method. Follow this idea to find the place where ConstraintViolationFactory.createViolation is called.

Let's also go back to the manual reverse trace to see if we can trace back to where there is routing.

Search ConstraintViolationFactory:

There are several, here uses the first BowerGroupRepositoriesApiResource analysis, click to see that we can see that it is an API route:

ConstraintViolationFactory was passed to super, and other functions of ConstraintViolationFactory were not called in BowerGroupRepositoriesApiResource, but its two methods also called super corresponding methods. Its super is AbstractGroupRepositoriesApiResource class:

The super called in the BowerGroupRepositoriesApiResource constructor assigns ConstraintViolationFactory (label 1) in AbstractGroupRepositoriesApiResource, the use of ConstraintViolationFactory (label 2), and calls createViolation (we can see the memberNames parameter), which is needed to reach the vulnerability point. This call is in validateGroupMembers (label 3). The call to validateGroupMembers is called in both createRepository (label 4) and updateRepository (label 5), and these two methods can also be seen from the above annotations that they are routing methods.

The route of BowerGroupRepositoriesApiResource is /beta/repositories/bower/group, find it in the admin page APIs to make a call (use 3.21.1 test):

Several other subclasses of AbstractGroupRepositoriesApiResource are the same:

CleanupPolicyAssetNamePatternValidator does not do cleanup point analysis

Corresponding to the CleanupPolicyAssetNamePatternValidator in the search results above, we can see that there is no StripEL removal operation here:

This variable is thrown into buildConstraintViolationWithTemplate through an error report. If the error message contains the value, then it can be used here.

Search CleanupPolicyAssetNamePatternValidator:

Used in CleanupPolicyAssetNamePattern class annotation, continue to search for CleanupPolicyAssetNamePattern:

The attribute regex in CleanupPolicyCriteria is annotated by CleanupPolicyAssetNamePattern, and continue to search for CleanupPolicyCriteria:

Called in the toCleanupPolicy method in CleanupPolicyComponent, where cleanupPolicyXO.getCriteria also happens to be CleanupPolicyCriteria object. toCleanupPolicy calls toCleanupPolicy in the createup and previewCleanup methods of the CleanupPolicyComponent that can be accessed through routing.

However, it cannot be used here, and the value value will not be included in the error message. After reading RegexCriteriaValidator.validate, no matter how it is constructed, it will only throw a character in the value, so it cannot be used here.

Similar to this is the CronExpressionValidator, which also throws an exception there, it can be used, but it has been fixed, and someone may have submitted it before. There are several other places that have not been cleared,but either skipped by if or else, or cannot be used.

The way of manual backtracking search may be okay if there are not many places where the keyword is called, but if it is used a lot, it may not be so easy to deal with. However, for the above vulnerabilities, we can see that it is still feasible to search through manual backtracking.

Vulnerabilities caused by JXEL (CVE-2019-7238)

we can refer to @iswin's previous analysis https://www.anquanke.com/post/id/171116, here is no longer going Debugging screenshots. Here I want to write down the previous fix for this vulnerability, saying that it was added with permission to fix it. If only the permission is added, can it still be submitted? However, after testing version 3.21.1, even with admin permissions can not be used, I want to see if it can be bypassed. Tested in 3.14.0, it is indeed possible:

But in 3.21.1, even if the authority is added, it will not work. Later, I debug and compare separately, and pass the following test:

JexlEngine jexl = new JexlBuilder().create();

String jexlExp = "''.class.forName('java.lang.Runtime').getRuntime().exec('calc.exe')";
JexlExpression e = jexl.createExpression(jexlExp);
JexlContext jc = new MapContext();
jc.set("foo", "aaa");

e.evaluate(jc);

I learned that 3.14.0 and the above test used org.apache.commons.jexl3.internal.introspection.Uberspect processing, and its getMethod method is as follows:

In 3.21.1, Nexus is set to org.apache.commons.jexl3.internal.introspection.SandboxJexlUberspect, this SandboxJexlUberspect, its getMethod method is as follows:

It can be seen that only a limited number of methods of type String, Map, and Collection are allowed.

Conclusion

• After reading the above content, I believe that we have a general understanding of the Nexus3 loopholes, and you will no longer feel that you can't start. Try to look at other places, for example, there is an LDAP in the admin page, which can be used for jndi connect operation, but the context.getAttribute is called there. Although the class file will be requested remotely, the class will not be loaded, so there is no harm.
• The root cause of some vulnerabilities may appear in a similar place in an application, just like the keyword buildConstraintViolationWithTemplate above, good luck maybe a simple search can encounter some similar vulnerabilities (but my luck looks bad Click, we can see the repair in some places through the above search, indicating that someone has already taken a step forward, directly called buildConstraintViolationWithTemplate and the available places seem to be gone)
• Look closely at the payloads of the above vulnerabilities, it seems that the similarity is very high, so we can get a tool similar to fuzz parameters to collect the historical vulnerability payload of this application, each parameter can test the corresponding payload, good luck may be Hit some similar vulnerabilities.