Not long ago, we had a friendly penetration of a host in the school. The website adopted a self-developed ASP + Access program. I didn't ask what table structure it was, so I found the injection point smoothly. The article table has five fields. The index values of the fields that can be normally displayed are (2, 3, and 5), the Administrator table is Admin, and two common fields are guessed: ID, Password, adopts the reverse push method: when union select, * from admin is returned normally, it is known that the admin table has three fields, and the user name field is unknown. Unfortunately, this User Name field can only be displayed at the 4 position (adminuser is later known), as shown in table 1:
1 2 3 4 5
1 1 ID Adminuser Password
Table 1
If you want to change 2 to ID submit (union select 1, ID, * from admin), the system reports an error:
Microsoft JET Database Engine error '80040e14'
The two data tables selected in the joint query or the columns in the query do not match.
/List_kx.asp, row 11
I thought I was wrong. I checked the number of columns. 1 + ID + * (3) = 5. Why not? Is the number of connections on the computer wrong? Since you said I was wrong, I will join you!
Submit union select ID, * from admin, Error! Union select 1, 1, ID, * from admin, normal! I am wondering: 1 + 1 + ID + * (3) = 6, you can still return normally !? 6. Why is it equal to 5? Fortunately, I learned some database theories:
An important difference between DBMS and RDBMS is that RDBMS provides a DB database language for a set of questions. For most RDBMS, this set-oriented database language is SQL. A forward set refers to a set (result set) that SQL Processes Group data at the same time. In other words, the returned result of each query is a set ). The elements in a set are not repeated. In the union of the two sets, the common elements of the two elements can only appear once. Therefore, the result set of union select, * from admin is equivalent to union select, ID, * from admin. The difference is that * (all columns) has changed:
* 1 = {ID, Adminuser, Password}, * 2 = {Adminuser, Password}
Note the important fact that we changed "*" (all columns )!
However, this change is meaningless for our guess. The username field Adminuser is still at the position where the column index is 4. Fortunately, we still have a trump card: Password field!
Submit union select 1, 1, Password, * from admin! If desired, the User Name field is successfully exposed through transformation. See table 2.
1 2 3 4 5
1 1 Password ID Adminuser
Table 2
The above is only the simplest case. Take the dynamic Article 3.0 (Access) as an example, printpage. asp has the SQL injection vulnerability. The variable ArticleID is not filtered. SQL = "select * from article where ArticleID =" & ArticleID & "" queries the ARTICLE table with 28 fields, we Union the ADMIN table, which has eight fields. The table structure is as follows:
ID | Username | Password | Purview | LastLoginIP | LastLoginTime | LastLogoutTime | LoginTimes
We can see that the index values of the fields that can be displayed are (3, 4, 5, 8, and 14). If you have not guessed enough field names, assume that we only know the ID field and use *, add the ADMIN table to perform three self-Join Operations, and add four matching fields to submit such query statements: union select, * from (admin as a inner join on admin as B on. id = B. id) inner join on admin as c on. id = c. the Password field cannot be displayed, as shown in table 3:
5 ...... 8 ...... 14
A. ID ...... A. Purview ...... B. Username
Table 3
The methods in the past are no different. Fortunately, I just turned to Yi tianjian because I can perform three self-join operations on the Admin table. I am afraid we only know the ID field, let's take a look at how I pull a pound:
Union select 1, 1, 1, a. id, * from (......), The world is so peaceful ......
Union select, a. id, B. id, * from (......), Offset!
Union select 1, 1, 1, a. id, B. id, c. id, * from (......), Offset!
See table 4.
5 ...... 8 ...... 14
A. ID ...... A. Purview ...... B. Username
A. ID ...... A. Password ...... B. Username
A. ID ...... A. Username ...... A. LoginTimes
Table 4
The user name and password are obtained successfully! When the victory is still not in the dark, there are still some details to discuss with you: why is there no offset for the first time? When and where will the offset occur? What is the offset?
Using Induction, when "*" contains one table:
Let's look back at the first example. We mentioned the Password field before, and the ID and Adminuser are all moved back, that is, as long as the field is being extracted (in this example: Password) all previous fields are moved back. The ID field is at the top of all fields in the table and cannot be moved;
When "*" contains N tables, there is more room for activity. The same field is changed to n siblings and can be proposed n times, but how many offset operations can be performed depends on fate. Table 5 shows the offset in the second example:
5-> 13
5-> 13 14-> 21
Table 5
The values 5 to 13 are offset twice, but the values 14 to 21 are offset only once. Therefore, the values 8 can be offset by Password and Username, while the values 14 can only be offset by LoginTimes.
The preceding figure shows that the number of fields is 1. If N fields are guessed, the offset can be multiplied by N times! In this case, we will write a Union-based injection machine.