SQL Injection practical overview (1/2)

David E Lares S
Nerd For Tech
Published in
6 min readFeb 13, 2021

Databases have been around forever, and almost 50 years ago a lot of projects were put together and transformed into what is today known as SQL or the Structured Query Language. A lot of things came up just to get what we know today as a database.

Before going practical we need to talk about SQL as a language.

As you may know, SQL is not a product, is a standard programming language that is used for managing and obtaining data from a database. SQL is an ISO norm today, and a lot of products are available based on that specification.

SQL suites as:

  1. A programming language for accessing a database
  2. A data definition language for handling data integrity and views
  3. A dynamic and incorporated transaction control mechanism
  4. A mechanism for exploring the flexibility and power of relational systems
  5. A way of controlling data register collections and not individual registers

SQL is a lot. I can’t imagine software solutions or products without databases and SQL in any kind of product available.

Today we have more options for data storage, but 15 years ago this was unthinkable. SQL is the most used language for databases and is still massively adopted.

SQLi

An SQL injection is an SQL code insertion made through data input from the client side of a web application most of the time. This insertion can be found in a complete or partial mode and will lead to accessing the database, gaining privileges, obtaining data or deleting records

Based on your backend code implementation and whatever privileged settings are set, you just not only a database but others as well. You literally can execute OS-based commands and take control of your system.

This kind of attack is very common to use find and is placed in the OWASP Top 10 because of the ease of detection and exploitation. The impact can be enormous if your database settings are misconfigured

Databases are the place where all the information is stored, if this particular piece is compromised, you will have a big problem. As a company is a fact that you will lose money and credibility. Hackers' motivation is money, any kind of data stealing is a later income for them.

SQLi can be used for DDoS, for data exploring and manipulation, and also compromising the infrastructure, where:

  1. DDoS can be achieved by injecting a DROP TABLE SQL command, making the whole system unavailable due to database inconsistency.
  2. By doing data exploration you get to know, how is the database structured, check any content, insert new users, or whatever thing comes to mind.
  3. Compromising an infrastructure can be done in multiple ways, you can load a Webshell tool like C99Shell (if you are using PHP), or maybe generate reverse sessions, perform remote connections, and way more.

SQLi Types

There are two types of SQLi injections available. The Classic SQLi and the Blind SQLi, both result in the same way but differ in showing the returned data.

The Classic SQLi generates an error based on a character input or boolean expressions that generates an error message that can be generic or not. The generic messages do not show any ID related to the OS or the routes, and also won’t show error details, they just prompt the name of the error itself.

On the other hand, the Blind SQLi is used when there are no error messages due to a possible injection, and no data is returned from the website code execution (internal SQL query). Here, the attacker will try to inject queries that throw a boolean True as the result and will try to infer the type of information that the query executes.

When the execution goes well, it will show the expected content and not the error message.

Sending information

If you are familiar with web development (that should do), you already know that there are two ways of sending data to the server using the HTTP protocol verb, they are the GET and the POST method.

The POST method sends the information internally, this won’t be visible from the URL and can be sent in plain-text or by any encoding method. It can be simply printed by the backend. This can be captured as well by sniffers such as Burpsuite.

The GET method sends the information as a query string directly into the URL, and as well, can also be sent as plain text or with any particular encoding technique. Here’s an example

process.php?name=David&lastname=Lares

Both name and lastname are identifiers or vulnerable parameters (next to explain)

Evaluating vulnerable parameters

The key aspect for succeeding in an SQLi is that you as an attacker must find (or identify) a piece of code that does not perform a correct input parameter validation that somehow is used to compose database queries.

By referring to the input parameters, we can assume that in a client-server architecture, we are referring to the client side of the environment. This means that we are sending whatever input set from our client side to our backend from an HTML form or by direct manipulation of the URL.

When using a GET method, and all the data is sent from the URL, you will need to use the (ASCII %27) to generate an error.

And, when using the POST method, the parameters won’t be visible, so you will need to use tools like tamperdata, or proxy tools like Burpsuite, Acunetix, or Filter to identify a vulnerable parameter.

Let’s practice!

Let’s test a known Classic SQLi now. If we recall this a bit, a boolean expression is needed

Here’s an example:

SELECT * FROM users WHERE uname='$username' AND pwd='$password';

Both $username and $password are PHP variables that are not sanitized or filtered in any way, the SQL statement is replacing a raw variable content in the uname and pwd conditions.

It seems normal at this point, but to exploit this uncertain behavior will need a boolean True statement. We are going to modify our query to this one:

$username = 1' or '1' = '1;
SELECT * FROM users WHERE uname='$username';

This can be seen as:

SELECT * FROM users WHERE uname= 1' or '1' = '1;

In a URL, the %20 is represented as a '' and this is not based on encoding but is a way to send strings. So, at this point, the ' or '1' = '1 will always resolve a True statement, where:

  1. The first and second ' marks an OR SQL statement
  2. The third and fourth ' marks a = sign
  3. In the Truth table T or 1 will resolve a True statement. So, 1 or (1 = 1 which is True) will result in a True statement

The injection succeeds for this GET example

For POST scenarios, things like change a little bit. For manual scenarios like this, we need to intercept the request, and the Burpsuite proxy is the perfect tool for it.

  1. Let’s sync the proxy server with our browser settings
  2. Set the Intercept IS ON mechanism
  3. Perform a request and see what’s happening with the HTTP body and header.
  4. Write your query modification and click FORWARD to continue to POST request execution.

This is the easiest SQLi example possible.

Here’s another one:

$username = `; DROP TABLE users; --`
$password = `OR ``=`

Resulting

SELECT user_id FROM users where user_id = `;DROP TABLE user ; -- ` and password = ``OR`` = ``

My goal here is to explain to you how things are done but you can always refer to the OTG-INPVAL-005 file for tips and working examples to follow along.

Join me in part the next part, let’s get serious about tooling

See you there.

--

--