Penetration Testing To Prevent API Attack
Utilizing what was uncovered at both stages of the penetration test assessment, we were able to piece together how the application worked on both the front and back end and used this information to formulate a successful attack. By chaining together various techniques and tools, code execution was achieved on one of the most vital hosts on our customer’s application infrastructure. Read along on how we went from 0 to 100, despite the website’s overall good security!
Let us enumerate API attack a bit
Web Application Testing
Overall, the web application was well built. No critical or high-risk vulnerabilities were discovered while assessing the application. Although, it was identified that the web application performed a variety of actions that related to the transferring of money from: Bank to User, User to User, and User to Application. The transferring and exchanging of money was performed by an API; however, the type of API and information pertaining to this API was tough to uncover solely through the usage of the web application. Fuzzing was performed against the API to attempt to break the application logic, but this did not yield any results. This required us to go deeper!
Let us enumerate API attack a bit
Moving to the back-end infrastructure, we began by enumerating the hosts that were in scope. As an internal connection was used, through VPN, this enumeration uncovered some standard services you would expect from a web application’s internal infrastructure: SSH, RPC, MySQL, HTTP, Load Balancers, and last but absolutely not least; Java RMI. We will come back to that one shortly, let us first talk about what piqued our interest in the Java RMI service.
Testing against the more common services yielded some general findings, nothing too special. However, the HTTP applications within the internal environment disclosed some valuable information that would ultimately function as the steppingstone that would point us towards the service we needed to attack. Navigating to the few HTTP services within the internal infrastructure in scope, we were presented with information relating to the Spring Boot Actuator API (Figure 1).
Each href would bring you to a subsequent accessible landing page. While crawling through the various applications we were presented with links and descriptions of the data that could be retrieved on the internal HTTP applications. Clicking on these links within the application would eventually lead to the disclosure of information relating to the payment API that was discussed earlier, as seen in Figure 2.
It should be noted that the HTTP applications running within the internal infrastructure were running on the same hosts that were running the Java RMI connectors. Using the information gathered from assessing the web application, performing information gathering within the internal network, and from enumerating the HTTP applications on these two individual hosts, we were able to determine that these hosts were responsible for the payment API functions and calls. This was identified by analyzing the information disclosed to us while crawling the HTTP services. We were able to uncover that the payment application was Pay Card Deposit Pay360, which can be seen in Figure 3. Pay360 is an integrated payment solution that web applications can use to send and receive funds. Now, the issue presented in front of us, how do we break the service to allow us to control said host; or, at the minimum, corrupt the application flow to perform malicious actions for us?
The Juicy Part
As mentioned, a Java RMI connector was running on the two hosts that was assumed to be responsible for payments made on the web application. Java Remote Method Invocation (RMI) is a mechanism that allows a service residing in one host to access/invoke an object running on another host. RMI is used to build distributed applications as it provides remote communication between Java programs. It was discovered that neither host required any means of authentication for interacting with their Java RMI services, this allowed enumeration to be performed against the connectors for information pertaining to the JMX console. As defined by Oracle: “Java Management Extensions (JMX) API is a standard for managing and monitoring applications and services. It defines a management architecture, design patterns, APIs, and services for building web-based, distributed, dynamic, and modular solutions to manage Java-enabled resources.” In the figure below you see a high-level overview of the Java RMI architecture.
Managed Beans (MBeans) are managed Java objects that follow the design patterns set forth in the JMX API specification. MBeans expose a management interface that, according to the JMX specification, consists of named and typed attributes that are readable and writable, as well as the named and typed operations that can be invoked by the applications that are managed by the MBean. Once a resource has been instrumented by MBeans, the management of that resource is performed by a JMX agent. MBeans are stored in the JMX registry, which is the core component of the MBeanServer; the JMX registry provides an interface to access the MBeans.
After gaining a better understanding of the architecture of Java-RMI and how it utilizes Managed Beans, further research pointed us to a tool called Beanshooter. According to the Beanshooter readme “beanshooter is a JMX enumeration and attacking tool, which helps to identify common vulnerabilities on JMX endpoints. The different beanshooter operations can be divided into two groups: basic operations and MBean operations. Whereas basic operations are used to perform general operations on a JMX endpoint, MBean operations target a specific MBean to interact with.” From this point forward, qtc-de's Beanshooter toolset was used to enumerate and attack the Java RMI connectors as it aids in identifying common vulnerabilities and staging further attacks.
Using Beanshooter’s basic operations, we were able to first confirm that the Java-RMI endpoints lacked authentication, which allowed us to enumerate the MBeans within the JMX registry. Upon further enumeration, we were able to identify the non-default MBeans on the Java-RMI connector were pertaining to the Spring Boot Actuator API for the hosted web application. Spring Boot is an open-source micro framework for Java developers; the actuator API is used to monitor the application, gather metrics, and understand application traffic. These MBeans were a bit different than what was observed on the HTTP services (Figures 1-3) of these hosts, as they allowed for more information to be queried and provided the ability to invoke different operations on the host, as can be seen in Figure 4.
Further research pointed us to deserialization attacks against these Java-RMI connectors. A common utility for exploiting deserialization attacks is frohoff’s Ysoserial toolset. Ysoserial is a collection of utilities discovered in common java libraries that can exploit Java applications performing unsafe deserialization of objects. Using a set of ysoserial payloads in conjunction with the beanshooter toolset, different deserialization attacks were performed against these connectors to identify potential attack vectors of exploitation. The first successful attack vector against the Java-RMI connectors utilized the URLDNS deserialization payload from ysoserial. This payload attempts to send DNS queries from the vulnerable machines to an attacker-controlled server during the deserialization process of our serialized payload.
The first payload successfully sent a DNS query from the vulnerable machines to our server within the internal environment (Figure 5); the second payload successfully sent a DNS query from the vulnerable machine out of the internal network to our server that was positioned on the internet (Figure 6). The latter was performed to test the security defenses in place pertaining to DNS, as DNS can be used as a means of data exfiltration. By controlling DNS queries from a trusted server within an internal network, DNS exfiltration can be accomplished by an attacker making DNS queries to an attacker-controlled domain and prepending encoded data as the subdomain.
Continuing with various deserialization attacks, other ysoserial payloads were attempted, with some resulting in stack trace errors, and others resulting in ClassNotFound exceptions being thrown by the Java-RMI service. From what was deduced from the stack trace error messages, certain privileges were needed to perform the actions the payload was attempting to perform.
The final attack vector that was attempted was to load a malicious .jar file into the MBean registry. This would allow us to perform malicious functions on the server by utilizing the malicious MBean. Initially, we attempted to directly upload and enable the malicious MBean through the Java-RMI connector; however, this proved to not be possible. Instead, we hosted the malicious MBean on a staging HTTP server within the internal network (Figure 7) and used the misconfigurations of no authentication to have the JMX API call the staging server and load the malicious .jar file into the MBean registry, otherwise known as remote loading. Once this was done, we deployed the malicious MBean on the vulnerable host (Figure 8). This effectively allowed us to run malicious commands through the newly deployed MBean on the compromised host.
The first Proof-of-Concept we attempted was sending a command for the malicious MBean to execute on the server. The first command sent was the ID command (Figure 9), as this is a safe command and would provide us enough information as to whether our MBean was running as expected. The response from the server confirmed our malicious MBean was functioning as expected, as well as confirmed our suspicion that the host handled the payment API requests from the web application. The second Proof-of-Concept involved getting a working reverse shell to our attacking machine. Once our attacking machine established a shell, we now had unfettered access on the compromised machines with the user privileges of the user running the payment API service (Figure 10).
At this point of the assessment, we had achieved working Remote Code Execution Proof-of-Concepts against both Payment API servers. Due to the time constraint of the assessment, we did not proceed further with any privilege escalation or lateral movement across the internal network that we were positioned in. Overall, we had proved that an application that has millions of users contained a flaw within its internal infrastructure that allowed for remote code execution against both servers that handled the payment API functions for the application. These types of slight misconfigurations are common within Java RMI connectors; however, their impact can be extremely detrimental. To be clear, it will require internal network access which obviously lowers the likelihood of this being exploited. Nonetheless a very interesting attack vector, a good puzzle for us to solve, and a great finding for the customer.
API Attack Remediation
As part of every pen test assessment, we of course offer our input for effective remediation based on knowledge obtained during the assessment. Proper configuration is crucial for ensuring the security of API endpoints. The following is advised as a part of best security practices for securing Java-RMI services:
- Run RMI services over SSL/TLS to prevent Man-in-the-Middle attacks.
- Require authentication for both server and client.
- Run a security manager when using RMI.
- Ensure that the value of the java.rmi.server.useCodebaseOnly property is true. Setting this property to false enables remote code loading, which increases the level of security risk to the system.
Had either host required authentication or disabled remote loading, code execution would not have been achieved within the environment. Minor configurational changes can make a significant difference in ensuring the overall security of diverse systems. As such, it is pivotal to properly implement and setup systems once they are deployed; and, even if that is done, a periodic penetration test can help in identifying something you might have missed.
About Ghost Labs
Ghost Labs is the specialist security unit within Outpost24 working in partnership with our clients to meet their penetration testing needs and objectives. Our experienced Offensive Security team offers enhanced and bespoke penetration testing security services such as advanced network penetration testing, (web)application testing, Red Teaming assessments and complex web application exploitation to help organizations have a true picture of their cyber risk. In addition, the Ghost Labs team is an active contributor to the security community with vulnerability research and coordinated responsible disclosure program.
Ghost Labs performs hundreds of successful penetration tests for its customers ranging from global enterprises to SMEs. Our team consists of highly skilled ethical hackers, covering a wide range of advanced testing services to help companies keep up with evolving threats and new technologies. To help businesses drive security maturity and mitigate risks posed by the evolving threat and techniques of the modern day hacker.