I started off as a penetration tester specializing in web application. When I started doing bug bounties my skills carried over 100%. Legit 80% of the attacks you pull off are going to be against a web application. After all, in today’s world the vast majority of a company’s public facing assets are web applications. For this reason alone, you MUST learn. Web application hacking if you want to be successful and there is no better place. To start than the OWASP top 10 if all you got out of this book was learning. How to exploit these basic web vulnerabilities, you will be able to find bugs all day.
SQL Injection (SQL) is a classic vulnerability that doesn’t seem to be going anywhere. This vulnerability can be exploited to dump the contents of an applications database. Databases typically hold sensitive information such as usernames and passwords so gaining access to this is basically game over. The most popular database is MySQL but you will run into others such as MSSQL, PostgreSQL, Oracle, and more.
The main cause of SQL injection is string concatenation as shown in the above code snippet. One line three the application is concatenating user supplied input with the sql query. If you ever see this you know you have sql injection. The reason why this is so dangerous is because we can append additional sql queries to the current query. This would allow an attacker to query anything they want from the database without restrictions.
The two most common types of sql injection are union based and error based. Union based sql injection uses the “UNION” sql operator to combine. The results of two or more “SELECT” statements into a single result. Error based sql injection utilizes the errors thrown by the sql server to extract information. Typically when I’m looking for this vulnerability. I’ll throw a bunch of double and single quotes everywhere until I see the famous error message.
As you can see in the first image appending a single. Quote to the “cat” variable value throws an sql error. Look at the two error messages and notice how they are different. Note that “%27” is the same as a single quote, it’s just url encoded. In the following sections I’ll show you how to exploit this vulnerability. We won’t be using SQL Map, you need to know how to do this by hand.
If you know how to perform sql injection on a mysql server then exploiting postgres will be very similar. Just like mysql I typically throw single and double quotes every where until I see the famous error message appear:
As you can see above there is an error message displayed. The name “psycopg2” is a python library for postgres. If you see this name you know you’re working with a postgres database server.
Union Based Sql Injection:-
Just like MySQL the first step is to determine how many columns. The SQL query is using, this can be accomplished by using the “order by” operator. As shown below we ask the server “do you have at least one column”. Then we ask “do you have two columns”, and so on until we get an error.
As you can see below once we hit 3 columns the server errors out. This tells us that there are only 2 columns being retrieved by the query.
As shown below we can use the “union all select” operator to perform the second query. Also note how the second select column is wrapped in single quotes. This is because the column types must match the original query. The first column is an integer and the second column is a string.
Note you can also use the word “null” if you don’t know the data type, so it would look like:
Union all select null
If you weren’t able to detect the database type from the error message. You could always use the “version()” function to print the database type and version as shown below:
After you have the number of columns the query returns we need to find all the tables in the database. Just like MySql we can query the “information_schema.tables” table to get a list of all tables in the databases.
● union all select 1,table_name from information_schema.tables where
table_schema != ‘pg_catalog’ and table_schema != ‘information_schema’ offset 0
For the most part this is the same as MySql but there are a few differences. For starters PostgreSQL doesn’t have a group_concat function so instead. I return one table_name at a time with the “offset” operator. Offset ‘0’ get the first table name, offset ‘1’ gets the second and so on. I also filter out the default databases “pg_catalog” and “information schema” as they tend to clog up the results.
As shown above the second table name is called “users”, this is the table we will be targeting. The next step is to extract the columns associated with the target table as shown below.
● union all select 1,column_name from information_schema.columns where
table_name = ‘users’ offset 0
As shown above there are two interesting columns called username and password. These are the columns we will be extracting data from as shown in the below query:
● union all select 1,concat(username,’:’,password) from users offset 0
Finally, the username and password of the first user is shown. An attacker could then use these credentials to log in to the application.