On January 22, 2024 Fortra posted a security advisory for their GoAnywhere MFT product. This advisory details an authentication bypass vulnerability, CVE-2024-0204, that allows an unauthenticated attacker to create an administrative user for the application. Customers were made aware of the issue by an internal security advisory post and patch made available on December 4, 2023, in which researchers malcolm0x and Islam Elrfai were originally credited with the discovery. In 2023, file transfer applications were a top target by threat actors. Our POC can be found here.
The advisory mentions that the endpoint /InitialAccountSetup.xhtml
can be deleted and the service restarted to mitigate the issue. Looking through the application directories, we find that this endpoint is mapped to the com.linoma.ga.ui.admin.users.InitialAccountSetupForm
class by inspecting the file GoAnywhere/adminroot/WEB-INF/forms-faces.xml
.
Figure 1. Endpoint to Class Mapping
Using advanced tooling, we find that the GoAnywhere/lib/gamft-7.4.0.jar
project defines that class.
Figure 2. Finding the InitialAccountSetupForm class
Comparing the jar’s for gamft between 7.4.0 and 7.4.1 reveals that several additional checks were added to the initializer for the InitialAccountSetupForm class.
When installing GoAnywhere, the application will first direct users to this endpoint to set up a new administrative user.
Figure 3. Add Administrative User During Install
After install, requesting the supposed vulnerable endpoint directly did not allow us access to the same page and instead redirects the user to the /Dashboard.xhtml
endpoint and finally to /auth/Login.xhtml
because the user is not authenticated.
Finding this behavior in the application leads us to the com.linoma.dpa.security.SecurityFilter
class. This class is called on all requests and performs the doFilter()
function, which performs checks for which endpoints are requested and based on the endpoints, user context, and application settings will allow the request to be routed to the correct endpoint.
Figure 4. SecurityFilter class
Inspecting the SecurityFilter class more closely, we find that there are a couple explicit areas that deal with requesting the /InitialAccountSetup.xhtml
endpoint mentioned in the advisory.
/wizard/InitialAccountSetup.xhtml
then it will properly route you to this setup page./wizard/InitialAccountSetup.xhtml
then redirect to /Dashboard.xhtml
.Figure 5. InitialAccountSetup logic
We considered the patches we observed and this logic, and without a way to pass the isAdminUserCreated
check we were unsure exactly how this bypass could occur. Instead of using logic, and instead using our spidey senses, we considered if possibly there was a path normalization issue. Classically for Tomcat based applications, there exist path traversal issues when the request contains /..;/
. Trying to request the supposed vulnerable endpoint now with a request that looks like https://192.168.1.1:8001/goanywhere/images/..;/wizard/InitialAccountSetup.xhtml
leads to the application now routing us to the setup page again!
Figure 6. Bypassing doFilter() with /..;/
Submitting this form again, while also being careful to re-write the form submission request to include the path traversal, we find that a new administrative user has been created.
Figure 7. Administrative User Added
Our proof-of-concept exploit that adds an administrative user can be found on our GitHub.
The easiest indicator of compromise that can be analyzed is for any new additions to the Admin Users
group in the GoAnywhere administrator portal Users -> Admin Users section. If the attacker has left this user here you may be able to observe its last logon activity here to gauge an approximate date of compromise.
Additionally, logs for the database are stored at \GoAnywhere\userdata\database\goanywhere\log\*.log
. These files contain transactional history of the database, for which adding users will create entries.
Figure 8. Indicator of User Additions in Database Logs