邪恶八进制 作者:Bink (http://www.guardiangenius.com)
目前整个国内互联网都在使用的都是“宁可错杀,不可放过”式的“SQL通用防注入”程序,就是检测POST GET 提交中是否包含指定的危险字符,如:select update delete 之类的字符,一旦发现,立刻封杀!比如 Neeao 的 “SQL通用防注入系统3.1 最终纪念版”也在处理误报方面毫无办法,这里是我搜索到的一篇比较详尽的关于SQL防注入的文章:http://www.dklkt.cn/article.asp?id=81 (360+NOD32 无报警),在此文中也提及以下片段: 引用:
不过,用这个防注入代码是会带来一个使用上的问题的,大家注意看这几句:
If Request.Form<>"" Then StopInjection(Request.Form)
If Request.QueryString<>"" Then StopInjection(Request.QueryString)
If Request.Cookies<>"" Then StopInjection(Request.Cookies)
特别是Request.Form那个,也就是说,假如管理员发表一篇文章中含有"and",";"等被过滤的关键字的话,那么也会被k掉。这么说,一篇英文文章根本就无法发表了。这个严重影响了网站的正常使用。所以我将这条语句If Request.Form<>"" Then StopInjection(Request.Form)删掉了。这样就会缓解这个问题。也就是说,对表单都不过滤了。而最后文章的作者补充此文提到采用正则,我眼睛一亮,难道真的有人先于我考虑到用正则来拦截? 看完代码,我发现我错了,作者仅仅是把麻烦的数组切割、instr工作交给正则完成而已,在处理结果方面完全雷同。
Neeao 的这个代码可能还复杂了点,针对拦截进行了数据库记录,而网络上更多的类似程序仅仅是匹配+拦截而已。
我们再把范围扩大,即便是Softbug老兄的 IISUSER 和一些其他我都叫不出名字的IIS防护软件也同样是采用类似的拦截手段。
好了,啰嗦了一堆,我们可以切入正题了,多年没来邪八,不知道还有几位仍记得我? 这两年徘徊于程序员与黑客的边缘,因此对于解决上面的问题,也发现了更新的解决办法,就好比认真的雪提出的那个问题一样“玩编程的搞渗透会爆发出怎样的能量”,那么我就把自己比喻为“玩脚本编程的搞脚本入侵/防御会爆发出怎样的能量”,呵呵,开个玩笑。
我这次编写出来代替SQL通用防注入的程序拦截准确率高达98%以上,误报几率控制在2%以内,执行速度在常规页面控制在100ms-500ms左右。程序采用两层关卡拦截,常规的危险字符寻找+正则语法匹配,针对POST GET COOKIE AGENT 4种可由客户端提交数据的途径进行检测和拦截。
秉承开源共享精神,公布下代码吧:(无论是转载,还是借用代码,请保留版权,谢谢,目前国内此类型代码独我一份首次发布,一旦盗用立刻能发现)
注:代码是从我的软件中分离出来的,需要稍微修改函数 doCreateLog 中变量 tmpPath 的值为一个实际存在的路径用于存放XML日志即可使用。 复制内容到剪贴板
代码:
<%
Dim KOSDefense:Set KOSDefense = New KOSDefenseClass
Call KOSDefense.doParse()
Class KOSDefenseClass
private Chr_Danger_Code,Chr_Timer_Begin
public sub class_initialize()
Chr_Timer_Begin = timer()
Chr_Danger_Code = "|;|and|or|exec|select|update|delete|declare"
end sub
public sub class_terminate()
response.write "<!-- GuardianGenius Runtime: " & FormatNumber((timer()-Chr_Timer_Begin)*1000,4) &"ms. -->"
end sub
########################################
########################################
public sub doParse()
Call doSense("post")
Call doSense("get")
Call doSense("cookie")
Call doSense("agent")
end sub
private sub debug(byval strer)
response.write strer
end sub
private sub doSense(byval strType)
dim ObjRequest,tmpArray,tmpI,tmpParameter,tmpSubParameter,tmpString
if strType = "post" then
if instr(Request.ServerVariables("CONTENT_TYPE"),"multipart/form-data")>0 then
exit sub
end if
end if
select case strType
case "post" : set ObjRequest = Request.Form
case "get" : set ObjRequest = Request.QueryString
case "cookie" : set ObjRequest = Request.cookies
end select
tmpArray = split(Chr_Danger_Code,"|")
select case strType
case "agent"
dim tmpAgentString
tmpAgentString = getUserAgent()
debug tmpAgentString&"<br /