Description
I accidentally left the debug script in place... Well, I think that's fine - No one could possibly access my super secure directory.
Setup
Launch the challenge instance and note the host and port.
This is the third Printer Shares challenge (see also Printer Shares 2) - the twist here is that a script on the share executes automatically every minute via cron.
sudo apt install smbclientSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1
Connect to the SMB share anonymously and list its contentsObservationI noticed the challenge description referenced an exposed SMB share from the earlier Printer Shares series, which suggested trying an anonymous null session connection first to enumerate what files were accessible without credentials.The public share accepts anonymous (null session) connections just like in the earlier Printer Shares challenges. Once connected, listing the files reveals two items: script.sh and cron.log. Download both so you can inspect them locally.bashsmbclient -L //<HOST> -p <PORT_FROM_INSTANCE> -Nbashsmbclient //<HOST>/shares -p <PORT_FROM_INSTANCE> -Nbashsmb: \> lsbashsmb: \> get script.shbashsmb: \> get cron.logbashsmb: \> exitbashcat script.shbashcat cron.logExpected output
picoCTF{5mb_pr1nter_5h4re5_r3v3r53_...}What didn't work first
Tried: Using smbclient with -U to supply a username and password instead of a null session
The server returns an authentication error because no valid credentials are configured. The share is intentionally open to anonymous connections, so passing -U guest or any explicit credentials just adds unnecessary complexity. Use -N to tell smbclient to skip the password prompt entirely and connect as a null session.
Tried: Running enum4linux or nmap SMB scripts to enumerate shares before connecting
Those tools can list share names but add extra steps when you can simply run smbclient -L to list shares directly. More importantly, enum4linux output does not show you the files inside the share, so you still need smbclient to actually download script.sh and cron.log. Skip the enumeration detour and connect directly.
Learn more
Null sessions let a client authenticate with an empty username and empty password. Unless
restrict anonymousis set in the Samba config, the server hands over a tree-connect handle and the client can enumerate and transfer files freely. This default open posture is why anonymous SMB access keeps appearing across the Printer Shares series.Once you read
script.shyou will see it is a health-check script that appends output tocron.log. Readingcron.logshows regular timestamps, confirming the script runs automatically every minute. That scheduled execution is the key to the exploit: you can overwrite the script and the cron job will run your version.Step 2
Overwrite script.sh with a payload that copies the flagObservationI noticed that script.sh on the share is executed automatically every minute by cron and the share accepts anonymous writes, which suggested replacing the script with a payload that reads the flag from the protected directory and appends it to the readable cron.log file.Because the share is both anonymous and writable, you can replace script.sh with any content you like. Write a new version of the script that reads the flag from the protected directory the cron user has access to and appends it to cron.log, which lives on the public share where you can retrieve it.bash# Create the malicious script.sh locallybashcat > script.sh << 'EOF'bash#!/bin/bashbashecho "Health Check: $(date)"bashcat /challenge/secure-shares/flag.txt >> /challenge/shares/cron.log 2>&1bashEOFbash# Upload the modified script back to the sharebashsmbclient //<HOST>/shares -p <PORT_FROM_INSTANCE> -N -c 'put script.sh'What didn't work first
Tried: Trying to open a reverse shell from the payload instead of writing the flag to cron.log
A reverse shell requires an inbound connection from the challenge server to your machine, which is blocked by NAT and the CTF network isolation. The cron job will execute your script but the connection will silently time out. Using cron.log as the output channel works because it already lives on the same writable share you can read anonymously, so no outbound connection from the server is needed.
Tried: Hardcoding /root/flag.txt or /flag.txt as the flag path in the payload
The flag is not at a standard root-level path in this challenge. The cron.log will show a 'No such file or directory' error (captured by 2>&1) when the script runs, confirming the wrong path. The correct path is /challenge/secure-shares/flag.txt, which is readable by the cron user but not by the anonymous SMB session directly.
Learn more
The attack is a classic cron job hijacking: a privileged automated process runs a script that an unprivileged user can overwrite. The cron job runs as a user that has read access to the flag in the protected directory. Because cron executes whatever is in
script.sh, replacing that file with your own payload gives you the cron user's effective permissions for one minute.The payload redirects the flag into
cron.log, a file on the same public share you can already read anonymously. The2>&1redirect captures any error messages too, which helps debug path mistakes. If the path to the flag is different on the challenge instance, check cron.log for error output and adjust accordingly.In real-world penetration testing, writable cron scripts are a high-severity finding. The attacker does not need any credentials, no shell access, and no exploit: the privilege escalation is entirely configuration-driven. Defence is straightforward: make cron scripts owned by root and non-writable by any unprivileged user or group.
Step 3
Wait for cron to run, then retrieve the flag from cron.logObservationI noticed cron.log contained timestamps spaced roughly one minute apart, confirming the cron interval, which suggested waiting at least 60 seconds after uploading the payload before downloading an updated copy of cron.log to find the appended flag.The cron job fires every minute. After about 60 seconds, download the updated cron.log from the share. The flag will be appended at the bottom of the file.bash# Wait approximately one minute, then download the updated logbashsmbclient //<HOST>/shares -p <PORT_FROM_INSTANCE> -N -c 'get cron.log'bashcat cron.logWhat didn't work first
Tried: Downloading cron.log immediately after uploading the modified script.sh
The cron job runs on a fixed schedule, once per minute, not on demand. If you fetch cron.log within seconds of the upload, you get the version that was written before your script ran, so the flag is not there. Wait at least 60 seconds, or use a polling loop with sleep 10 between fetches, to give the scheduler time to execute your payload.
Tried: Using cat on the local cron.log file you already downloaded before uploading the payload
smbclient get overwrites the local cron.log file with whatever is currently on the share at the time of the download. If you read the local copy you saved during step 1, it predates your payload execution and will not contain the flag. You must run smbclient get again after the cron interval to pull the updated file from the share.
Learn more
Timing matters here. If you download cron.log too soon, you will get the old version without the flag. Wait the full minute (or a little longer to be safe) before fetching the file. You can also loop the download until the flag pattern appears:
until grep -q 'picoCTF' cron.log; do smbclient //<HOST>/shares -p PORT -N -c 'get cron.log'; sleep 10; doneThis writable-script-plus-cron pattern appears frequently in CTF privilege escalation chains and in real penetration tests. Tools like
pspymonitor running processes without root to spot these scheduled jobs on a live system. Here the cron.log timestamps in the original file make the schedule obvious without needing any process monitoring.
Interactive tools
- Hex ViewerView text or raw hex bytes as a xxd-style hex dump with byte offset, hex columns, and ASCII sidebar. Highlights printable characters and null bytes.
- Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.
Flag
Reveal flag
picoCTF{5mb_pr1nter_5h4re5_r3v3r53_...}
The flag is retrieved from cron.log after the cron job executes the overwritten script.sh. The real vulnerability is a writable SMB share hosting a cron-executed script, not a debug script with hardcoded credentials.