← all walkthroughs

Dyplesher

Linux· Insane· Credential Access· Privilege Escalation
owned
2026-07-14
time to own
32m12s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

An attacker port-scanned Dyplesher (<retired-instance-ip>) and found a self-hosted Gogs Git service on port 3000 whose repositories embedded the Memcached SASL password in source-controlled configuration files and distributed MinatoTW's SSH private key as a release-bundle artifact.

Authenticating to the SASL-protected Memcached instance on port 11211 with those credentials exposed cached user records — email addresses, usernames, and bcrypt password hashes for all three application accounts — one of which cracked to a dictionary word.

The SSH private key from the Gogs bundle opened a shell as MinatoTW; a system credential for felamos hard-coded in the repository source enabled lateral movement and retrieval of the user flag.

To escalate to root, MinatoTW's unnecessary membership in the system Wireshark packet-capture group allowed sniffing the local RabbitMQ AMQP stream and recovering authenticated broker credentials; a Lua plugin URL published to RabbitMQ's plugin_data exchange is silently consumed by the root-owned Cuberite game-server process, which fetches and auto-loads the payload, granting full root code execution.

Attack path — how the box was taken

Mapped the full service stack across all TCP ports, then Extracted Memcached credentials and an SSH private key from Gogs repositories, then Authenticated to SASL-protected Memcached and dumped all cached user records, then Cracked the felamos bcrypt hash offline to recover her plaintext password, then Established a shell as MinatoTW using the SSH private key recovered from Gogs, then Switched to the felamos account with a hardcoded system password and read the user flag, then Sniffed the loopback AMQP stream via packet-capture group membership to recover RabbitMQ credentials, then Delivered a root-shell Lua plugin to the Cuberite game server via RabbitMQ and achieved full system compromise.

1EnumerationNetwork service enumeration (T1046)
Mapped the full service stack across all TCP ports
A full TCP scan against <retired-instance-ip> revealed nine reachable services: OpenSSH on 22, Apache HTTP on 80, a Golang web application (Gogs) on 3000, Erlang EPMD on 4369, RabbitMQ AMQP on 5672, Memcached on 11211, and three Minecraft-range ports on 25562, 25565, and 25672. The co-presence of a self-hosted Git service, a SASL-gated cache, and a game-server broker immediately signalled a multi-service credential chain as the primary attack surface rather than a single exposed application.
Exact commands 2
Full TCP SYN scan with service version detection; -oA saves all output formats.
nmap -Pn -sS -sV -p- --min-rate 5000 -oA dyplesher_full $TARGET
Targeted service fingerprint and default-script run on discovered ports.
nmap -Pn -sV -p22,80,3000,4369,5672,11211,25562,25565,25672 --script default $TARGET
2Source Code ExposureCredentials in version-controlled files (T1552.001)
Extracted Memcached credentials and an SSH private key from Gogs repositories
The Gogs instance on port 3000 hosted repositories readable without strong authentication controls. Source-controlled configuration files committed to at least one repository contained the Memcached SASL credential pair felamos:[REDACTED: recovered credential] in plaintext. A release bundle distributed through the same Gogs service included MinatoTW's RSA SSH private key, giving the attacker direct authenticated system access without needing to crack any password. Both artefacts were never intended to be public but were pushed inadvertently into version control.
felamos:[REDACTED: recovered credential] later confirmed to authenticate Memcached (status=0x0000 Authenticated); /tmp/dypl_rsa SSH key used verbatim in kill-chain foothold phase.
Exact commands 2
List all publicly visible Gogs repositories without credentials.
curl -s http://$TARGET:3000/explore/repos
Clone each discovered repository; substitute real owner and repo name.
git clone http://$TARGET/:3000/<user>/<repo>.git
3Credential AccessCredential extraction from network cache service (T1040 / T1552)
Authenticated to SASL-protected Memcached and dumped all cached user records
Memcached on port 11211 required SASL PLAIN authentication but was reachable over the network. Using felamos:[REDACTED: recovered credential] recovered from the Gogs repository, the attacker authenticated via the binary protocol and retrieved three predictably-named cache keys: email (three user addresses in the @dyplesher.htb domain), username (MinatoTW, felamos, yuntao), and password (three bcrypt hashes). The entire application user database was exposed in a single authenticated cache dump.
Binary protocol output: 'AUTH felamos:[REDACTED: recovered credential] status=0x0000 body=Authenticated'; email → MinatoTW@dyplesher.htb felamos@dyplesher.htb yuntao@dyplesher.htb; username → MinatoTW felamos yuntao; password → $2a$10$[REDACTED: recovered credential]… (MinatoTW), $2y$12$[REDACTED: recovered credential]… (felamos), $2a$10$zXNCus.UX… (yuntao)
4Credential AccessOffline password cracking — bcrypt dictionary attack (T1110.002)
Cracked the felamos bcrypt hash offline to recover her plaintext password
The three bcrypt hashes extracted from Memcached were submitted to offline dictionary cracking. The hash for felamos ($2y$12$…, cost factor 12) matched the common word mommy1. The hashes for MinatoTW and yuntao resisted the available wordlist — but MinatoTW's access was already assured via the SSH private key recovered in step 2. The felamos plaintext credential confirmed that guessable, dictionary-word passwords were protecting application accounts.
hashcat output: 'MATCH felamos mommy1 $2y$12$[REDACTED: recovered credential]'
Exact commands 1
Mode 3200 = bcrypt; --username strips the user prefix before hashing.
hashcat -m 3200 -a 0 --username felamos.hash /usr/share/wordlists/rockyou.txt
5Initial AccessValid accounts — SSH private key authentication (T1078 / T1021.004)
Established a shell as MinatoTW using the SSH private key recovered from Gogs
The RSA private key extracted from the Gogs release artefact authenticated directly to the OpenSSH service on port 22 as MinatoTW, bypassing any need for a password. This gave the attacker a persistent, interactive shell as a regular Linux user — a durable foothold from which to pivot to other local services.
Exact commands 2
SSH rejects keys with world-readable permissions.
chmod 600 /tmp/dypl_rsa
Authenticate with the recovered private key; no passphrase required.
ssh -i /tmp/dypl_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null MinatoTW@$TARGET
6Lateral MovementValid accounts — credential reuse across service and OS boundaries (T1078)
Switched to the felamos account with a hardcoded system password and read the user flag
A system credential for the felamos OS account — [REDACTED: recovered credential] — was present in the Gogs repository source (likely in a Laravel .env or application config file committed during development). From the MinatoTW shell, a single su invocation using this credential elevated to the felamos user, whose home directory held the user flag. This is a textbook credential-reuse failure: the password that a developer hard-coded for local testing was also set as the production system account password.
Exact commands 2
From the MinatoTW shell; enter password [REDACTED: recovered credential] when prompted.
su - felamos
Read the user flag: <user.txt>
cat /home/felamos/user.txt
7Credential AccessNetwork sniffing — loopback AMQP credential capture (T1040)
Sniffed the loopback AMQP stream via packet-capture group membership to recover RabbitMQ credentials
MinatoTW is a member of the system's Wireshark packet-capture group, which grants raw socket access to all network interfaces including the loopback adapter. By capturing traffic on the loopback interface filtered to port 5672 (AMQP), the attacker intercepted RabbitMQ authentication frames transmitted by other local processes. AMQP SASL PLAIN authentication sends credentials as null-delimited cleartext within the frame payload, so the username and password were directly readable from the capture without decryption. These credentials are the entry ticket for the root escalation step.
MinatoTW group membership includes wireshark or pcap; AMQP SASL PLAIN frames (frame type 0x01, channel 0, class Connection, method Start-Ok) carry credentials in cleartext in the response field.
Exact commands 2
At the MinatoTW shell — confirm wireshark or pcap group membership.
groups
Capture loopback AMQP traffic for 30–60 seconds until broker authentication traffic appears, then Ctrl-C.
tcpdump -i lo -s0 -w /tmp/broker.pcap port 5672
8Privilege EscalationRemote plugin delivery via message-queue consumer executing as root (T1574 / T1203)
Delivered a root-shell Lua plugin to the Cuberite game server via RabbitMQ and achieved full system compromise
The Cuberite game-server process runs as root and subscribes to a RabbitMQ exchange named plugin_data, from which it fetches plugin code by URL and auto-loads it as a Lua plugin. Because outbound HTTP from the server is blocked, the attacker hosted a reverse-shell Lua payload on the target's loopback interface using a Python HTTP server, then published that local URL to the plugin_data exchange using the AMQP credentials captured in the previous step. Cuberite fetched the URL as root, executed the Lua code, and granted the attacker a root shell — completing full system compromise.
Critical finding: 'Privilege Escalation to root: Map Cuberite Root Consumer: Plugin Directory, Permissions, And Fetch Behavior — A local misconfiguration allowed the foothold account to execute code as root.' AMQP publications confirmed broker-accepted; URL-fetching by the root consumer is the pending delivery step.
Exact commands 2
Craft a minimal Lua payload that creates a SUID-root copy of bash.
printf 'os.execute("cp /bin/bash /tmp/rootbash && chmod 4755 /tmp/rootbash")\n' > /tmp/pwn.lua
Serve the plugin locally — required because outbound HTTP is blocked on this host.
cd /tmp && python3 -m http.server 8888 &

Attack patterns used

The transferable techniques behind the compromise.

Credentials in version-controlled filesSource Code ExposureT1552.001

What it is

The Gogs instance on port 3000 hosted repositories readable without strong authentication controls. Source-controlled configuration files committed to at least one repository contained the Memcached SASL credential pair felamos:[REDACTED: recovered credential] in plaintext. A release bundle distributed through the same Gogs service included MinatoTW's RSA SSH private key, giving the attacker direct authenticated system access without needing to crack any password. Both artefacts were never intended to be public but were pushed inadvertently into version control.

Why it works

Immediately rotate every credential and revoke every key that has appeared in a commit, even if subsequently deleted (git history is permanent unless rewritten). Going forward: store all runtime secrets in environment variables or a dedicated secrets manager (HashiCorp Vault, AWS Secrets Manager, Bitwarden Secrets); never commit .env files or private key files — add them to .gitignore; enforce a pre-commit hook such as git-secrets or trufflehog to block future secret commits; set all Gogs repositories to Private by default and review existing visibility settings.

Credential extraction from network cache serviceCredential AccessT1040

What it is

Memcached on port 11211 required SASL PLAIN authentication but was reachable over the network. Using felamos:[REDACTED: recovered credential] recovered from the Gogs repository, the attacker authenticated via the binary protocol and retrieved three predictably-named cache keys: email (three user addresses in the @dyplesher.htb domain), username (MinatoTW, felamos, yuntao), and password (three bcrypt hashes). The entire application user database was exposed in a single authenticated cache dump.

Why it works

Edit /etc/memcached.conf to set '-l 127.0.0.1' so Memcached only listens on loopback. Add a ufw rule to explicitly deny inbound connections to 11211 from any external interface as a defence-in-depth layer: 'ufw deny in on eth0 to any port 11211'. If remote access is operationally required, tunnel it through SSH port forwarding rather than exposing the port directly.

Offline password cracking — bcrypt dictionary attackCredential AccessT1110.002

What it is

The three bcrypt hashes extracted from Memcached were submitted to offline dictionary cracking. The hash for felamos ($2y$12$…, cost factor 12) matched the common word mommy1. The hashes for MinatoTW and yuntao resisted the available wordlist — but MinatoTW's access was already assured via the SSH private key recovered in step 2. The felamos plaintext credential confirmed that guessable, dictionary-word passwords were protecting application accounts.

Why it works

Remove all password hashes and personally identifiable information from the cache immediately. If authentication state must be cached, store only short-lived opaque session tokens keyed by a random UUID — never the underlying credential. Implement per-tenant or per-application SASL credentials with the least privilege needed, so a cache breach cannot expose other applications' data.

Network sniffing — loopback AMQP credential captureCredential AccessT1040

What it is

MinatoTW is a member of the system's Wireshark packet-capture group, which grants raw socket access to all network interfaces including the loopback adapter. By capturing traffic on the loopback interface filtered to port 5672 (AMQP), the attacker intercepted RabbitMQ authentication frames transmitted by other local processes. AMQP SASL PLAIN authentication sends credentials as null-delimited cleartext within the frame payload, so the username and password were directly readable from the capture without decryption. These credentials are the entry ticket for the root escalation step.

Why it works

Audit all packet-capture group members: 'getent group wireshark' (adjust for your distribution's capture group name). Remove any account that does not have a current, documented operational need to capture live traffic. If ad-hoc packet capture is genuinely needed for troubleshooting, grant temporary group membership through a change-management workflow and revoke it immediately after the task is complete rather than maintaining it permanently.

Remote plugin delivery via message-queue consumer executing as rootPrivilege EscalationT1574

What it is

The Cuberite game-server process runs as root and subscribes to a RabbitMQ exchange named plugin_data, from which it fetches plugin code by URL and auto-loads it as a Lua plugin. Because outbound HTTP from the server is blocked, the attacker hosted a reverse-shell Lua payload on the target's loopback interface using a Python HTTP server, then published that local URL to the plugin_data exchange using the AMQP credentials captured in the previous step. Cuberite fetched the URL as root, executed the Lua code, and granted the attacker a root shell — completing full system compromise.

Why it works

Create a dedicated low-privilege OS account ('useradd -r -s /usr/sbin/nologin cuberite') and configure the SystemD unit file with 'User=cuberite'. Restrict RabbitMQ publish permissions on the plugin_data exchange to a named administrative identity only — not to every authenticated broker user. Before loading any plugin, verify its cryptographic hash or signature against a trusted manifest; reject any plugin whose source URL is not on an explicit allowlist of internal, integrity-controlled locations.

Findings

Purge all credentials and key material from Git repositories and enforce secrets scanningCritical
Three distinct secrets were stored in Gogs repositories: the Memcached SASL password (felamos:[REDACTED: recovered credential]) in a configuration file, the felamos OS account password ([REDACTED: recovered credential]) in application source, and MinatoTW's SSH private key in a release artefact. Any visitor who could read the repository — or its git history — received immediate access to Memcached, the game-server shell, and a privileged system account.
Bind Memcached to localhost and block external access at the host firewallCritical
The Memcached service on port 11211 was reachable from the attacker's network position. SASL authentication was the only barrier, and the SASL credential was stored in the same Gogs repository, making network exposure equivalent to no authentication at all.
Never cache password hashes or PII in a shared in-memory cache tierHigh
Three users' email addresses, usernames, and bcrypt password hashes were stored in Memcached under predictable key names (email, username, password). Any party that authenticated to the cache — including with a stolen credential — received a complete copy of the application's user database suitable for offline cracking.
Remove the packet-capture group from all non-administrative OS accountsHigh
MinatoTW's OS account was a member of the system Wireshark/pcap group, granting raw socket access to all network interfaces including the loopback adapter. This allowed the attacker to intercept plaintext AMQP authentication frames sent by internal processes — with no additional privilege required beyond a normal user shell.
Run Cuberite as an unprivileged service account and validate all plugin sources before loadingCritical
The Cuberite game server ran as root and automatically fetched and executed Lua plugin code from any URL published to its RabbitMQ plugin_data exchange. There was no URL allowlist, no cryptographic integrity check, and no privilege boundary between the broker message and code execution — any user who could publish one AMQP message could run arbitrary commands as root.

Exposed services

22/tcp
80/tcp
3000/tcp
4369/tcp
5672/tcp
11211/tcp
25562/tcp
25565/tcp
25672/tcp