SQL Injections and how to protect against them
Page 1 of 1

Author:  KimChoJapFan [ Mon Sep 11, 2017 9:42 am ]
Post subject:  SQL Injections and how to protect against them

Introduction : I mostly come from greyhat forums such as Leakforums (UID: 9197) and so I'm all too familiar with the exploits found in most sites including:
  • SQL Injections
  • Persistent XSS
  • CSRF
  • Session Hijacking
  • Remote Code Execution
  • Cookie Injections

But this thread will be focusing mainly on SQL Injections. All of those previous items will have a thread of their own someday.

What is an SQL Injection? : An SQL Injection is an attack where a remote user escapes a user input (typically using a single quotation (tick) mark) and is able to run SQL code into a database.

These vulnerabilities occur because SQL doesn't know what is user input and what isn't user input. This coincides with a universal rule of website design: Never trust user input because a remote user can and will run any slew of attacks against your website to see what they can get away with. You don't want to find your database making its rounds around the internet and through greyhat forums; I've seen it happen myself and luckily I haven't had an incident that I'm aware of, but I do know of database leaks where my information shows up and I still get tons of spam mail because of those database leaks.

Vulnerable SQL Example : Let's show what an average data select query looks like:
SELECT * FROM accounts WHERE username='username' AND password='password';

I've seen private server code and older website code use a query like this to authenticate users when logging in since entering the correct username and password will return something while incorrect username and/or password inputs will return nothing.

This hosts a couple of interesting injections that accomplish the same thing; gaining access to an account without knowing the password.

SQL Injection method #1: Comment-based Injection : This injection type relies on us commenting out the password bit of the query and so we only need to know the username of the account that we want to access.

To do this we will put the following username in:

The single quote (tick) mark after the username will escape the user input and allow us to start running SQL code. The two dashes with a space at the end (-- ) in SQL is known as a single-line comment. In the query, this is what will be ran:
SELECT * FROM accounts WHERE username='username'-- AND password='';

So this will return the username of the user to the website and if the authentication method is only checking for the number of returned values from the query (if nothing returns then assume wrong username and/or password, else assume correct username and password).

This will give us access to this user's account without knowing the password. We could put anything into the password field if the form checks for the existence of data in that field (in this case you can simply mash buttons on your keyboard for the password and it'll still give you access to the account).

SQL Injection method #2: Binary-based Injection : This injection type relies on us giving the SQL server a simple true-or-false question in order to gain access to the account. This works well if the website is filtering the username input.

In this case we will have to know the username of the account we want to breech and we will put in the following values for each field:
username = username
password = ' or '1=1

So this will turn the query into:
SELECT * FROM accounts WHERE username='username' AND password='' or '1=1';

What happens here is that the SQL server gets requests that can be represented like this:
Form wrote:
Okay SQL server, I want to select everything from the accounts table where the username "username" is found and where the password "" is found.

SQL Server wrote:
I do not have any results where the username "username" and password "" exists.

Form wrote:
Okay SQL server, I want to select everything from the accounts table where the username "username" is found and does one equal one?

SQL Server wrote:
I do have results where the username "username" exists and yes one does equal one.

Since we have a query result that has returned all positive, we gain access to the account.

What about filtering? : That'll do fine against some attackers, but any attacker can still form a POST header (directly sending form inputs to your site) and thus can bypass most methods of filtering that you can put on your form.

Plus if you have a big site, you may tend to forget a couple of form inputs and it's those unfiltered form inputs that can be used against you:

You solve this problem by implementing prepared statements.

Prepared Statements : Prepared statements are used to tell the SQL server what parts of the query is user input and what parts aren't user input. This means that there's no way to escape the input and thus there's no way to run SQL code as a remote user.

Let's look into prepared statements using PDO:

= "mysql:host=localhost;dbname=webdb;port=3306;charset=utf8";
$pdo = new PDO($dsn, "root", "root");

$query = "SELECT * FROM accounts WHERE username=? AND password=?;";
$stmt = $pdo->prepare($query);

$user = filter_input(INPUT_POST, "username");
$pass = filter_input(INPUT_POST, "password");

$stmt->execute([$user, $pass]);
$data = $stmt->fetchAll();

count($data) > 0) {
    // Correct username and password
} else {
   // Incorrect username and/or password

This case is secure against SQL injections, but I strongly advise from using this method of storing account information in your database because it appears that there are passwords being stored in the clear in this database (so if a breech were to occur, then the attacker will be able to see raw passwords and they're pretty much ready to package the database up and leak it to other forums and websites).

Implications : So you may be wondering what could the hacker do with the information gathered from your database?

Well if you're storing emails and passwords in the database, then there's a chance that one of your members may be re-using the same password on another website (possibly their email account, their facebook account, their youtube account, etc...) and that can be used to hijack their accounts and even scrape more personal information about the user.

The information you store in the database could lead an attacker to more data about the users and possibly contribute to what is known as a "dox" or a document pertaining personal information (essentially leaking a bunch of personal and private information out on the internet for the whole world to see). This dox information has been used in the past for "swatting" or the act of calling an emergency number with a falsified claim that the target person has or is in the act of committing a violent crime at the address specified in the dox. The other things that can be done with this information could potentially lead to physical confrontations towards the person now that potentially dangerous people have the means to reach the target person and now know where to head to get to them.

You should treat all breeches as if you allowed the "bad guys" to hurt your members by relieving sensitive information about your members from ignorance alone. This information is not hard to come by and it's not difficult to switch to prepared statements while maintaining the integrity of your code (in case you don't feel like rewriting your code to meet with modern security standards).
TBD : I plan on adding more to this thread and I also plan on making a series of similar threads regarding well known vulnerabilities.

Here's the planner for this thread:
  • GET-based Injections
  • Blind SQL Injections
  • Tools used to dump databases

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group