What is RPC?
Remote Procedure Calls (RPC) are a powerful technique for building distributed applications. It is based on extending the usual local procedure invocation so that the called procedure does not need to exist in the same address space as the calling procedure. The two processes can be on the same system or they can be on different systems with the network connecting them.
- The calling environment is paused, procedure parameters are passed over the network to the environment where the procedure is executed and the procedure is executed there.
- When the procedure finishes and produces its result, its result is passed back to the calling environment, where execution continues as if returning from a regular procedure call.
RPC can be seen as a normal request-respone protocol, however it is used for server-server communication rather than client-server. This is very important because in a distributed system, the application code is on more than one server server. The most common example is the Microservices architecture.
This means: a request on the client side may need many services running on these servers to synthesize information before responding to the client. The communication between servers will now be a problem that before all services running on one server are fine, because the local call should not be concerned. Exactly then, when a server wants to “talk” to another server, it will need to encode data (JSON, XML), the receiver also has to do the opposite job of decode data to understand what the other guy said to me. must re-encode. This consumes a lot of processing resources (CPU) that should only be done at the beginning and end (the receiver and the last return).
Introducing apache dubbo
Dubbo is an open source Alibaba RPC and microservice framework.
It enhances service administration and makes traditional monolithic applications smoothly refactored into a scalable distributed architecture.
In this article, I’ll take a look at Dubbo and its most important features.
Dubbo includes several ingredients:
- Provider – Provider – the provider will create its service for registration
- Container – Container – where the service is created, loaded, and run
- Consumer – the person requesting the remote services; the consumer will subscribe to the required service in the registry
- Registry – The Registry – where the service will be registered
- Monitor – records statistics for services, for example, the frequency of service calls over a given period of time
The connection between
Registry is continuous, so whenever a
Provider has problems, the
Registry can detect the error and notify
Monitor are optional.
Consumer can connect directly with
Provider , but the stability of the whole system will be affected.
The activities of dubbo are described as follows:
Containeris responsible for initializing, loading and running
Providerregisters its services to the
Registerduring the initialization.
Consumerregisters the services they need from
Registerwhen it starts.
Consumerand when a change occurs,
Registerwill push the changed data to
Consumerselects one of the
Providerbased on the soft load balancing algorithm, then makes the call, automatically chooses another
Providerwhen an error occurs.
Providercount service calls and usage time in memory and send statistics to
Dubbo has the following features: Connectivity, Powerful, Scalable and Scalable.
List of java deserialization vulnerabilities related to apache dubbo:
CVE 2019-17564 Analysis
Apache Dubbo supports many protocols like
http ….. All are listed on https://dubbo.apache.org/en/docs/v2.7/user/references/protocol/ . By default, the Dubbo RPC Framework uses the
CVE-2019-17564 is a deserialization vulnerability that occurs when the Apache Dubbo HTTP protocol is used, An attacker can send a POST request with a malicious object to a URL of the Apache Dubbo HTTP service, which will lead to remote code execution.
- 2.7.0 <= Apache Dubbo <= 2.7.4
- 2.6.0 <= Apache Dubbo <= 2.6.7
- Apache Dubbo = 2.5.x
For the convenience of setting up the environment, visit the dubbo-Sample github project homepage and download dubbo-sample (https://github.com/apache/dubbo-samples)
After downloading the source code, select dubbo-sample-http and open it as a project in Intelij
After the project has finished loading. We will fix dubbo version 2.7.3 so that it can be exploited. Note that adding
<version>2.7.3</version> on line 81 will make your changes successful
Next we will need a zookeeper for the dubbo to connect to. Zookeeper is a centralized service (a server) for maintaining configuration information, naming, providing distributed synchronization, providing group services. In other words, Zookeeper is a distributed coordination service for distributed applications. The client connects to a ZooKeeper server (a single node). The client maintains a TCP connection through sending and receiving requests, responses, and listening for events … If the server dies, the client will be connected to another server. You can download the zookeeper here: https://zookeeper.apache.org/releases.html .
After downloading the zookeeper you launch it to
zkServer.bat . Note that before running, you create a zoo.cfg file in the conf directory with the content copied from the zoo_sample.cfg file:
If the display like this is successful already.
Analysis and debugging.
Do not run the HttpProvider class. Realizing the provider registered a service with zookeeper
Since this is an Http service, we can completely catch requests with burpsuite to modify. Create a request to the above service, and capture it with burpsuite for easy modification
This request will go through the method
org.apache.dubbo.remoting.http.servlet.DispatcherServlet.service because the
DispatcherServlet class inherits the
javax.servlet.http.HttpServlet class, which handles all http requests sent to the server. Set breakpoint at line 43.
An easy way to see the flow of the program is to look at the stack trace on the left corner of the Intelij screen. With the top of the satck is where we are standing.
Press F7 to jump to the next method which is:
Keep an eye on line 211. This code will check what kind of method the request we send up. If it is different from
POST , 500 will always be returned without processing. So to be able to go to line 216, we need to edit the request to a
POST request and try again. After repeating the above steps, we set the breakpoint at line 216 and press F7 to jump to the next handler method,
The job of this method is to read a remote invocation from the request, execute it, and write the result of the remote call into the response. Notice the
readRemoteInvocation method is responsible for reading our request. Jump to that method to see more
We see after jumping into the above method it continues to call a method of the same name to read the InputStream in the request. Pay attention to param
request.getInputStream() . Here, for some people who have studied java deserialization here will immediately realize the problem lies in this place already. It is reading any stream that the user enters in the
POST request. Notice on line 119 the program recreated the ObjectInputStream from the stream we sent it and passed the
doReadRemoteInvocation method. Jump into this method to continue reading.
So far, the program executes readObject (). From here, we have endpoind to trigger the java deserialization vulnerability. Next is just a matter of finding a chain to be able to continue mining. This issue depends on the jar packages in the project and on the actual situation. Here for simplicity I will add
commons-collectons:3.2 to demo this vulnerability.
After reloading the program. I use a nice burp suite extension called
Deserialization Scanne . It can generate payloads and send them directly to the server. Here I use gadget chain CommonsCollection 5 offline.
And here is my result.
https://www.geeksforgeeks.org/remote-procedure-call-rpc-in-operating-system/ https://www.baeldung.com/dubbo https://dubbo.apache.org/en/docs/v2 .7 / user / preface / architecture / https://y4er.com/post/apache-dubbo-cve-2019-17564/