一、古老的OR注入漏洞
首先观察首页,页面设计较为简单,提供了一个登录入口,具体界面如图1所示。
500)this.width=500" title="点击这里用新窗口浏览图片" />
没有多余犹豫,直接尝试经典的 'or'='or' 注入语句,结果点击登录后,竟然成功绕过验证,直接进入了后台。让我们分析一下 login.asp 中的关键代码:
!--#include file="conn.asp"-->
FCBLOG
用户登陆
function del_space(s)
{
for(i=0;i
for(j=s.length-1;j>=0;--j)
{
if(s.charAt(j)!=" ")
break;
}
return s.substring(i, j);
}
function VerifySubmit()
{
topic = del_space(document.form1.name.value);
if (topic.length == 0)
{
alert("您忘了写用户名!");
return false;
}
if (document.form1.pwd.value == "")
{
alert("请输入密码!");
return false;
}
return true;
}
这段代码仅通过 JavaScript 在客户端检查用户名和密码是否为空,没有进行任何服务端数据校验,更没有对特殊字符进行过滤。如此薄弱的防护措施,导致 SQL 注入漏洞的出现几乎是必然的,具体效果如图2所示。
500)this.width=500" title="点击这里用新窗口浏览图片" />
二、跨站漏洞
首页还包含一个留言板块,继续深入探索。直接在几个输入框中填入 alert(/冰的原点/),操作如图3所示。
500)this.width=500" title="点击这里用新窗口浏览图片" />
提交后,意料之中,JavaScript 对话框弹出了两次,结果如图4所示。
500)this.width=500" title="点击这里用新窗口浏览图片" />
有趣的是,我们提交的文本在页面上最终呈现为什么样子?如图5所示。
500)this.width=500" title="点击这里用新窗口浏览图片" />
为什么只弹出了两次,而没有第三次?右键查看页面源文件,发现如下代码:
标题: 内容: 发表留言于2007-10-26 14:16:41
由此可见,程序对用户输入的内容只做了简单的转义处理,将 < 和 > 分别替换为 < 和 >,但这种过滤只执行了一次,导致标题和内容中的脚本被转义失效,而地址栏中的脚本却因为转义后的字符不再构成有效标签而得以保留并执行。开发者在过滤逻辑上出现了疏忽(这里没有直接查看源码,但从现象推断,过滤机制存在明显的漏洞)。
三、真假注入
首先将程序放入自动扫描工具中检测,寻找明显的注入点,结果如图6所示。
500)this.width=500" title="点击这里用新窗口浏览图片" />
显然,工具无法有效识别出漏洞。大部分页面看似是静态 HTML,有人可能会疑惑:静态页面也能存在注入吗?实际上,这里的静态页面是通过 JavaScript 动态调用的方式生成的,几乎每个页面都包含类似以下代码:
if(page=totalpage)then
'生成HTML静态首页
Set fso = Server.CreateObject("Scripting.FileSystemObject")
fso.CreateFolder(Server.MapPath(""))
Set fout = fso.CreateTextFile(Server.MapPath("msgpost.html"))
fout.WriteLine show
fout.close
response.redirect "msgpost.html"
end if%>
正是因为这种动态生成机制,参数在传递过程中基本没有经过严格过滤。例如下面这段代码:
'打开模板代码,并将其中特殊代码转变为接受值
sql1="select id,user_skin_main,user_skin_showlog from fc_moban where default=true"
set rs1=Server.CreateObject("adodb.recordset")
rs1.open sql1,conn,1,1
user_skin_main=rs1("user_skin_main")
user_skin_showlog=rs1("user_skin_showlog")
rs1.close
诸如此类的代码还有不少。因此,静态页面只是表象,真正的注入点隐藏在这些看似安全的后台逻辑中,只是自动扫描工具无法轻易发现而已。
