前些阵子讯时系统爆出了很多洞,先看他的怎么写的,下面是从他的admin_conn.asp文件中找到的。
sss=LCase(request.servervariables(”QUERY_STRING”))
if instr(sss,”select”)<>0 or instr(sss,”inster”)<>0 or instr(sss,”delete”)<>0 or
instr(sss,”(”)<>0 or instr(sss,”‘or”)<>0 then
response.write “你的网址不合法”
response.end
end if
代码使用了 request.servervariables的方法来获得传递过来的数据,然后赋值给sss。再判断传递过来的sss变量中是否含有 select,inster等敏感的字符串,只要有就结束程序。给普通注入造成了极大的麻烦,需要有新的东西出现来突破这个防注入。
现已知的有两种方法:
1.使用URL编码我们传递的数据,比如select可以编码为selec%74(即将t转换为url编码),这样就可以实现注入了!
2.使用cookies注入。
先看看第1种怎么实现的吧。因为程序接受的参数使用的是request.servervariables,呵呵,这个方法和我们平时的 request不太一样的,因为它接受的数据都会原封不动的接受的,比如我们传递了selec%74,那么这里sss里就会是selec%74,而不是已经解码的select 字符串了。当下面的判断语句来判断时会因为select<>selec%74而绕过检测!
第2种利用了request的cookie方法来传递数据,为什么呢?看程序的代码我们知道因为他只判断了使用 request.servervariables(”QUERY_STRING”)来接受的数据,我们如果用cookie来传递的话,程序当然不会去检测了,只要在前面的代码中找到一处使用request的方法接收变量的地方。这就是cookie的注射了。比如:前面有这样代码我们就可以实现cookie 注射了.这次代码在讯时admin_news_view.asp中截的。
<% newsid=trim(request(”newsid”)) sql = “select * from news where id=”&newsid Set rs = Server.CreateObject(”ADODB.RecordSet”) rs.Open sql,conn,1,1 title=rs(”title”) dat=rs(”time”) hit=rs(”hit”)+1 content=rs(”content”) %>
使用了request接收,而它会依次的去用3种数据集合(Form,QueryString,cookie)去判断,所以我们可以使用cookie来提交我们构造的SQL语句了.这里就不在截图了,具体可以参考这篇文章《最新版讯时新闻发布系统惊爆cookie漏洞》
但是并不是所有的程序都这么另人兴奋的哦,上次入侵一个站时,就碰到了这种情况,找到了源码下来看,却没有突破这个防注入。代码如下:
sub check()
Fy_Url=Request.ServerVariables(”QUERY_STRING”)
Fy_a=split(Fy_Url,”&”)
redim Fy_Cs(ubound(Fy_a))
On Error Resume Next
for Fy_x=0 to ubound(Fy_a)
Fy_Cs(Fy_x) = left(Fy_a(Fy_x),instr(Fy_a(Fy_x),”=”)-1)
Next
For Fy_x=0 to ubound(Fy_Cs)
If Fy_Cs(Fy_x)<>”" Then
If Instr(LCase(Request(Fy_Cs(Fy_x))),”‘”)<>0 or Instr(LCase(Request(Fy_Cs
(Fy_x))),”and”)<>0 or Instr(LCase(Request(Fy_Cs(Fy_x))),”select”)<>0 or Instr(LCase
(Request(Fy_Cs(Fy_x))),”union”)<>0 or Instr(LCase(Request(Fy_Cs(Fy_x))),”from”)<>0 or
Instr(LCase(Request(Fy_Cs(Fy_x))),” “)<>0 Then
response.Write(”嘿嘿,不要你注射!屏蔽了关键字,但是这个屏蔽程序却不好——如何突破呢?”)
Response.End
End If
End If
Next
end sub
这样的代码,都是用了Request.ServerVariables(”QUERY_STRING”)来接收的数据,但是你直接将注入的字符URL编码,会看到仍不能注射!
那到底怎么去突破呢?看下面!lake2大牛曾经写过一篇突破这种防注入的大作,这个方法也就是大牛发现的! 写的很详细哦,我们就引用大牛的话来解释一下这个绕过机制。
“Request.ServerVariables(”QUERY_STRING”)是得到客户端提交的字符串,这里并不会自动转换url编码,哈哈,如果我们把name进行url编码再提交的话,呵呵,那就可以绕过检查了。”下面是我的理解,因为程序使用 Instr(LCase(Request(Fy_Cs(Fy_x))),”‘”)<>0这样的判断语句,它是判断了name的值即 value,而且使用request来接收数据的.前面我们如果在url里value我们用url编码后来提交,然后当值传递到这里,就又会被解码了,所以程序可以检测得到.注意,但它只是判断了name的值即value,但对name,可以看到没有判断,而它又是通过name这个变量名来判断SQL语句的,所以只要用url编码name就可以了,然后程序仍是去判断name的值,但是这次是i%64,会被转换为id,可是我们并没有赋值给id而是 i%64,呵呵,那么id的值它就会认为是空,就这样绕过了哦!
可以看出只要能保证前面接收的方式不能解码,后面判断的语句可以解码就可以绕过了。后来胡思乱想到了chr()函数,只是YY了一下…..也没成。
而且这里是不是也可以用cookie注射呢?我测试的时候没有成,可能找的不是用request接受的地方….