关于sql注入大家可能或多或少有所了解,这篇文章介绍得很详细,大家可以看下:
https://www.cnblogs.com/baizhanshi/p/6002898.html
总结了下最主要的原理就是利用sql语句中的注释漏洞--
sql = "select * from user_table where username='" & userName & "' and password='" & password & "'"
例如上面的拼接语句,通常我们输入账号admin密码123456,那么拼接后的sql语句是:
select * from user_table where username='admin' and password='123456'
但是,如果黑客会在前台表单的用户名那儿填写' or 1=1 --那么会发生什么神奇的结果呢?看下面拼接的结果:
select * from user_table where username='' or 1=1 --' and password=''
大家会发现,竟然通过验证了!是不是很难受?
上面的案例再调整下让你更难受,假如输入admin' or 1=1 --现在我们再来看看:
select * from user_table where username='admin' or 1=1 --' and password=''
你是不是想握了棵草?
根据上面博文介绍的还有更绝的,利用sql语句的;表示一句间隔来执行sql语句,想干嘛就干嘛,简直为所欲为!!!
输入';DROP TABLE user_table --拼接结果:
select * from user_table where username='';DROP TABLE user_table --' and password=''
这真是要命呀。
根据上面的规律,我们好像只要对sql语句整体处理下替换掉--就行了是吧。那么用admin' or '1'='1来试试:
select * from user_table where username='admin' or '1'='1' and password=''
是不是防不胜防啊?! 有人会说这样不对,后面的password他没法猜中的。其实本来两个字段验证现在变成了一个字段验证了,只要password满足即可,现在的人很多用弱口令,比如12345,那我只要密码满足就验证通过就能进入后台了,对于一个用户数量如果比较多的系统随便输入个123456、888888等简单密码总会撞上的,有了后台到时就更好进一步突破了。
总结了下无非这些情况:
'’or 1 = 1 -- and password='’
"or "a"="a
admin' or '1'='1
' or ''='
')or('a'='a
or 1=1--
'or 1=1--
a'or' 1=1--
"or 1=1--
'or'a'='a
"or"="a'='a
'or''='
'or'='or'
1 or '1'='1'=1
1 or '1'='1' or 1=1
'OR 1=1%00
那么下面我们可以想对策了。
1.根据规律,我们首先要检测是否含有--,因为正常的表达式中不可能含有注释符号的,只要包含就认为此条sql语句非法。
2.检测是否含有;因为正常的表达式中不可能含有分号的,只要包含就认为此条sql语句非法。
3.接着我们检测是否包含恒等式,例如上面的1=1或者1='1'或者'abc'='abc'以及其他各种字符,我们得想个通用的策略。处理步骤:
(1).为了避免单引号的干扰,我们将所有非数字字母等号之外的字符都替换为空格,可以用正则表达式:[^\da-zA-Z\r\n=],替换后得到:
or 1 = 1 and password=
or a = a
admin or 1 = 1
or =
or a = a
or 1=1
or 1=1
a or 1=1
or 1=1
or a = a
or = a = a
or =
or = or
1 or 1 = 1 =1
1 or 1 = 1 or 1=1
OR 1=1 00
(2).开始判断是否包含恒等式,同样用正则表达式:\s([^\s]+?)\s*=\s*(\1)\s*,我们尝试匹配到的结果:
1.1 = 1 所在行: 1
(1).1 (2).1
2.a = a 所在行: 2
(1).a (2).a
3.1 = 1 所在行: 3
(1).1 (2).1
4.or =
or 所在行: 4
(1).or (2).or
5.a = a 所在行: 5
(1).a (2).a
6.1=1 所在行: 6
(1).1 (2).1
7.1=1 所在行: 7
(1).1 (2).1
8.1=1 所在行: 8
(1).1 (2).1
9.1=1 所在行: 9
(1).1 (2).1
10.a = a 所在行: 10
(1).a (2).a
11.a = a 所在行: 11
(1).a (2).a
12.or =
or 所在行: 12
(1).or (2).or
13.1 = 1 所在行: 14
(1).1 (2).1
14.1 = 1 所在行: 15
(1).1 (2).1
15.1=1 所在行: 15
(1).1 (2).1
16.1=1 所在行: 16
(1).1 (2).1
全部匹配到了,只要能匹配的都认为这条sql语句有问题,那么选择不执行。这样就避免了sql注入。
这里有个特殊的注入代码' or ''='替换后是 or = ,我们会发现这不会被上面的匹配到,因为等号前后是空的。所以我们还要再来一步将所有空格替换掉,然后判断是否包含or=,包含就认为非法。
总结就是:
1.判断是否包含--
2.判断是否包含;
3.判断是否包含恒等式
4.其他特殊的,例如不能含有or=
包含就认定sql语句非法,拒不执行。网上通常的办法的对每个字段的值进行过滤一大堆关键字特殊字符,个人觉得比较繁琐,经过我这4步后就将注入的问题拒之门外了。
asp中实现的办法:
'检测整个sql语句是否非法,如果非法将整个sql设置为空
function checkSql(byval strSql)
dim s,strMsg
s=strSql
if instr(s,"--")=0 and instr(s,";")=0 then '不能包含--和;有就函数返回空
s=replaceReg(s,"[^\da-zA-Z\r\n=]"," ")
if not regTest(s,"\s([^\s]+?)\s*=\s*(\1)\s*") then '不能存在恒等式
s=replace(s," ","")
if instr(lcase(s),"or=")=0 then'不能含有or=,这里主要都转小写进行比较
checkSql=strSql
exit function
end if
else
strMsg="存在恒等式 " & s & "<br>" & getMatch1(s,"\b([^\s]+?)\b\s*=\s*\b(\1)\b")
end if
else
strMsg="含有--或;"
end if
checkSql=strMsg
end function
function replaceReg(str1,strPattern,strNewString)
Set reg = CreateObject("vbscript.regExp")
reg.Global = True
reg.IgnoreCase = True
reg.MultiLine = True
reg.Pattern = strPattern
replaceReg= reg.Replace(str1, strNewString)
set reg=nothing
End function
function regTest(str1,strPattern)
Set reg = CreateObject("vbscript.regExp")
reg.Global = True
reg.IgnoreCase = True
reg.MultiLine = True
reg.Pattern = strPattern
regTest= reg.test(str1)
set reg=nothing
End function
function getMatch1Sub1(strData,strPattern)
Set reg = CreateObject("vbscript.regExp")
reg.Global = True
reg.IgnoreCase = True
reg.MultiLine = True
reg.Pattern = strPattern'"====\r\n([^\r\n]*)\r\n[\s\S]*?2431682927627455"
Set matchs = reg.Execute(strData)
if matchs.Count>0 then getMatch1Sub1=matchs(0).SubMatches(0)
End function