过滤不严格造成的漏洞解析('or'='or'原理以及修补办法)
这次先给大家介绍个脚本漏洞.
一般一个网站系统无非都是查询数据库然后生成网页,或者实现特殊功能,这里我找到一个网站.
http://www.k**e.com/admin/admin_login.asp
这里我直接猜到他的后台.
如下图所示,帐户密码那里我打了箭头,注意我输入的都是 'or'='or' 很多玩过黑客的人都会知道这个漏洞,
这里主要讲解的这个漏洞的原理.
<!--#include file="../inc/conn.inc" -->
<!--#include file="inc/config.asp" -->
<!--#include file="inc/md5.asp" -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title><%=GetOneSet(0)%></title>
<style type="text/css">
<!--
body {
background-image: url(images/bg1.gif);
margin: 0px;
background-repeat: repeat-x;
}
table,td{
font-family:"宋体";
font-size:12px;
}
.inputtext{
border-left:1px solid balck;
border-right:1px solid balck;
border-top:1px solid balck;
border-bottom:1px solid balck;
}
.loginbg {
font-size: 12px;
width: 59px;
height: 26px;
background-image: url(images/login_bg.gif);
border: none;
padding-top: 3px;
color:white;}
-->
</style>
<%
session("admin")=false
session("pass")=false
response.Cookies("newspics")=""
Function gen_key(digits)
dim output
dim char_array(50)
char_array(0) = "0"
char_array(1) = "1"
char_array(2) = "2"
char_array(3) = "3"
char_array(4) = "4"
char_array(5) = "5"
char_array(6) = "6"
char_array(7) = "7"
char_array(8) = "8"
char_array(9) = "9"
randomize
do while len(output) < digits
output = output&char_array(Int((9 - 0 + 1) * Rnd + 0))
loop
gen_key=output
End Function
dim key
key=gen_key(4)
dim action
action=request.QueryString("action")
if action="login" then
dim sql,verifyCode,manager,password,key2,rs,power
password=request.Form("txtPassword")
manager=request.Form("txtManager")
verifyCode=request.Form("txtVerify")
key2=request.Form("key")
password=MD5(password)
if key2=verifyCode then
sql="select * from manager where managerName='"&manager&"' and managerPassword='"&password&"'"
set rs=server.CreateObject("adodb.recordset")
rs.open sql,conn,1,1
if not rs.eof then
session("pass")=true
session("manager")=rs("managerName")
session("managerId")=rs("managerId")
power=rs("power")
if power=1 then
session("admin")=true
else
session("admin")=false
end if
response.Cookies("power")("power_class")=rs("power_class")
response.Cookies("power")("power_news")=rs("power_news")
'call GetSetting()
action=3
else
session("pass")=false
session("admin")=false
action=2
end if
rs.close
set rs=nothing
else
action=1
end if
end if
conn.close
set conn=nothing
if action=3 then response.Redirect("admin_index.asp")
%>
</head>
<body>
<div align="center">
<%
if action=2 then
response.Write("用户名或密码错误,请重登陆 <br>")
elseif action=1 then
response.Write("验证码不正确,请重登陆 <br>")
end if
%>
</div>
<tr>
<td> </td>
</tr>
</table>
<table width="50%" align="center" height="34" border="0" cellspacing="0" cellpadding="0">
<tr>
<td><img src="images/admin_02.gif" width="291" height="34"></td>
</tr>
</table>
<table width="100%" height="30" border="0" cellspacing="0" cellpadding="0">
<tr>
<td> </td>
</tr>
</table>
<table width="50%" height="261" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td valign="top"><table width="457" border="0" cellspacing="0" cellpadding="0">
<tr>
<td colspan="3"><img src="images/admin_05.gif" width="457" height="40" border="0" usemap="#Map" href="../index.asp"></td>
</tr>
<tr>
<td width="142" rowspan="3" valign="bottom" background="images/lbg.gif"><img src="images/admin_07.gif" width="142" height="221"></td>
<td width="240" valign="top"><img src="images/admin_08.gif" width="240" height="42"></td>
<td width="75" rowspan="3" valign="bottom" background="images/rbg.gif"><img src="images/admin_09.gif" width="75" height="221"></td>
</tr>
<tr>
<td height="107" valign="top" background="images/admin_10.gif">
<form action="admin_login.asp?action=login" name="form1" method="post">
<table width="75%" align="center" height="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="24%" height="30">用 户:</td>
<td width="76%" height="30"><input type="text" name="txtManager" id="txtManager" size="15" maxlength="20" class="inputtext"></td>
</tr>
<tr>
<td height="25">密 码:</td>
<td height="25"><input name="txtPassword" type="password" id="txtPassword" size="15" maxlength="20" class="inputtext">
<tr>
<td height="25">验证码:</td>
<td height="25"><input name="txtVerify" type="text" id="txtVerify" size="15" maxlength="20" class="inputtext"> <%=key%></td>
</tr>
<tr>
<td height="25" colspan="2"><p align="center"><input type="submit" value="登 陆" class="loginbg"><span class="mframe-t-right">
<input name="key" type="hidden" id="key" value="<%=key%>">
</span> <input type="reset" value="取 消" class="loginbg"></td>
</tr>
</table></form></td>
</tr>
<tr>
<td valign="bottom"><img src="images/admin_11.gif" width="240" height="72"></td>
</tr>
</table></td>
</tr>
</table>
<area shape="rect" coords="349,1,437,39" href="../index.asp">
</map></body>
</html>
-------------------------------------
Function StrCheck(fString)
fString=Trim(Server.HtmlEncode(fString))
fString=Replace(fString,"&","&")'
fString=Replace(fString,"\","\")
fString=Replace(fString,"--","--")
fString=Replace(fString,CHR(9),"	")
fString=Replace(fString,CHR(10),"<br>")
fString=Replace(fString,CHR(13),"")
fString=Replace(fString,CHR(22),"")
fString=Replace(fString,CHR(32)," ")
fString=Replace(fString,CHR(39),"'")'单引号
fString=Replace(fString,";",";")
StrCheck=fString
End Function
第二种方法
在你的conn.asp 文件中加防注入代码就行了;这是form注入;下面是防注入代码;<%'Dim Fy_Post,Fy_Get,Fy_cook,Fy_In,Fy_Inf,Fy_Xh,Fy_db,Fy_dbstr,aa On Error Resume Next Fy_In = "'|exec|insert|select|delete|update|count|chr|truncate|char|declare|--|script|*|char|set|(|)" aa="heike.txt" '------------------------------------------如入侵记录保存文件 Fy_Inf = split(Fy_In,"|") '1--------POST部份------------------ If Request.Form<>"" Then For Each Fy_Post In Request.Form For Fy_Xh=0 To Ubound(Fy_Inf) If Instr(LCase(Request.Form(Fy_Post)),Fy_Inf(Fy_Xh))<>0 Then flyaway1=""&Request.ServerVariables("REMOTE_ADDR")&","&Request.ServerVariables("URL")&"+'post'+"&Fy_post&"+"&replace(Request.Form(Fy_post),"'","*")&"" set fs=server.CreateObject("Scripting.FileSystemObject") set file=fs.OpenTextFile(server.MapPath(aa),8,True) file.writeline flyaway1 file.close set file=nothing set fs=nothing call aaa() End If Next Next End If'2--------GET部份------------------- If Request.QueryString<>"" Then For Each Fy_Get In Request.QueryString For Fy_Xh=0 To Ubound(Fy_Inf) If Instr(LCase(Request.QueryString(Fy_Get)),Fy_Inf(Fy_Xh))<>0 Then flyaway2=""&Request.ServerVariables("REMOTE_ADDR")&","&Request.ServerVariables("URL")&"+'get'+"&Fy_get&"+"&replace(Request.QueryString(Fy_get),"'","*")&"" set fs=server.CreateObject("Scripting.FileSystemObject") set file=fs.OpenTextFile(server.MapPath(aa),8,True) file.writeline flyaway2 file.close set file=nothing set fs=nothing call aaa() End If Next Next End If'3--------cookies部份------------------- If Request.Cookies<>"" Then For Each Fy_cook In Request.Cookies For Fy_Xh=0 To Ubound(Fy_Inf) If Instr(LCase(Request.Cookies(Fy_cook)),Fy_Inf(Fy_Xh))<>0 Then flyaway3=""&Request.ServerVariables("REMOTE_ADDR")&","&Request.ServerVariables("URL")&"+'cook'+"&Fy_cook&"+"&replace(Request.Cookies(Fy_cook),"'","*")&"" set fs=server.CreateObject("Scripting.FileSystemObject") set file=fs.OpenTextFile(server.MapPath(aa),8,True) file.writeline flyaway3 file.close set file=nothing set fs=nothing call aaa() End If Next Next End IfSub aaa() Response.Write "请不要注入,我们已记下你的ip" Response.Write "<br><hr>" Response.End end Sub%>
第三种方法
先来了解下万能密码的产生
分析一个login.asp
(1)pwd = request.form("pwd") "获取客户端输入的密码,再把值赋给pwd"
(2)name = request.form("name") "获取客户端输入的用户名再把值赋给name"
都没有进行任何过滤
(3)Set rs = Server.CreateObject("ADODB.Connection") "利用Server对象的CreateObject方法创建ADO组件的Connection对象"
(4)sql = "select * from Manage_User where UserName='" & name & "' And PassWord='"&encrypt(pwd)&"'" "将用户名和密码放入查询语句中查询数据库"
(5)Set rs = conn.Execute(sql) "执行SQL语句"
(6)If Not rs.EOF = True Then "当前的记录位于Connection对象的最后一个记录之前"
(7)Session("Name") = rs("UserName") "将UserName的属性赋给Name的Session自定义变量"
(8)Session("pwd") = rs("PassWord") "将PassWord的属性赋给pwd的Session自定义变量"
(9)Response.Redirect("Manage.asp")了 "利用Response对象的Redirect方法重定向"Manage.asp"
(10)Else
(11)Response.Redirect "Loginsb.asp?msg=您输入了错误的帐号或口令,请再次输入!"
(12)End If
(13)end if
%>
知道原理之后 我们就可以修补了
把(1)(2)的内容修改成
pwd = replace(request.form("pwd"),"'","") //意思就是把'替换为空
name = replace(request.form("name"),"'","") //同上
为了保险后台最好设置登陆用户 登陆密码 还有验证码