UNION-based SQL injection assaults enable the analyzer to extract data from the database effectively. Since the “UNION” operator must be utilized if the two inquiries have precisely the same structure, the attacker must craft a “SELECT” statement like the first inquiry. To do this, a substantial table name must be known, yet it is likewise vital to decide the number of columns in the first inquiry and their information type.
In this tutorial, we will be using the “User Info” page from Mutillidae to perform a Union-Based SQL injection attack. Go to “OWASP Top 10/A1 — Injection/SQLi — Extract-Data/User Info” and use a login bypass technique learned in our previous lecture to access the page.
From this point, all our attack vectors will be performed in the URL section of the page using the Union-Based technique.
There are two different ways to discover how many columns are selected by the original query. The first is to infuse an “ORDER BY” statement indicating a column number. Given the column number specified is higher than the number of columns in the “SELECT” statement, an error will be returned. Otherwise, the results will be sorted by the column mentioned.
Since we do not know the number of columns, we start at 1. To find the exact amount of columns, the number is incremented until an error related to the “ORDER BY” clause is returned. In this example, we incremented it to 6 and received an error message, so it means that the number of columns is lower than 6.
When we ordered by 5, it worked and displayed some information. It means there are five columns that we can work with.
Next, instead of using the “order by” option, let’s use the “union select” option and provide all five columns.
Ex: (union select 1,2,3,4,5).
As it is shown in the screenshot columns 2, 3, and 4 are usable, so we can substitute those numbers with any database values to see what they correspond to. Let’s change column 2 to “database(),” column 3 to “user(),” and column 4 to “version().”
Ex: (union select 1,database(),user(),version(),5).
This Union command provided us with some useful information; now, we know that the database is “owasp10,” which has a user “root@localhost,” and the version of the server is “5.0.51a-3ubuntu5”. Based on this information, we can search for some vulnerabilities or attack vectors to compromise our target further.
Before building a query to extricate sensitive data, the assailant must recognize what information he needs to remove and where it is stored in the database. First and foremost, you have to realize that you might most likely view tables that your database user has access to. In other words, you might most likely rundown tables that your session client either claims or on which the client has been allowed some authorization. Every other table will appear to be inexistent.
In MySQL, the table “information_schema.tables” contains all the metadata identified with table items. Below is listed the most useful information on this table.
“table_name”: The name of the table.
“table_schema”: The outline in which the table was made.
If you want to limit the list of tables returned to the current schema, you can add a “WHERE” clause to filter this column in combination with “DATABASE()” and “SCHEMA()” functions.
Ex: (union select 1,table_name,null,null,5 from information_schema.tables where table_schema = ‘owasp10’).
Here we want to retrieve table names from the “owasp 10” database.
As you can see, we have access to multiple tables named “accounts,” “blogs_table,” “captured_data,” “credit_cards,” “hitlog,” and “pen_test_tools.”
When the attacker knows table names, he needs to discover what the column names are to extract data. In MySQL, the table “information_schema.columns” gives data about columns in tables. One of the most useful columns to extract is called “column_name.”
Ex: (union select 1,colunm_name,null,null,5 from information_schema.columns where table_name = ‘accounts’).
Here we are trying to extract column names from the “accounts” table.
Once we discovered all available column names, we can extract information from them by just adding those column names in our query sentence.
Ex: (union select 1,username,password,is_admin,5 from accounts).
As it is shown in the screenshot, we managed to retrieve all usernames and passwords related to this database.
In this instructional exercise, I will tell you the best way to access documents on the target machine, just as how to transfer your very own files and code onto the objective computer, all without ever stepping foot into the administration panel of the target website.
We can use the “LOAD_FILE()” operator to peruse the contents of any file contained within the web-server. We will typically check for the “/etc/password” file to see if we get lucky and scoop usernames and passwords to possible use in brute force attacks later.
Ex: (union select null,load_file(‘/etc/passwd’),null,null,null).
Now we will utilize the “INTO_OUTFILE()” operator for all that they offer and attempt to root the objective server by transferring a shell-code through SQL infusion. Remember, the general purpose of this is to tell you the best way to do it without getting caught by the administrator panel. This alternative enables you to take the contents from a column and spot them in a decent text file for neatness purposes. You can also utilize it to transfer a PHP shell-code to perform a remote file inclusion or CMD execution.
Ex: (union select null,’Hello World!’,null,null,null into outfile ‘/tmp/hello.txt’).
In this example, we will write a “Hello World!” sentence and output it in the “/tmp/” directory as a “hello.txt” file. This “Hello World!” sentence can be substituted with any PHP shell-code that you want to execute in the target server.
As it’s shown in the image, we successfully added our text and saved it in the “/tmp” directory as a “hello.txt” file.