前些阵子讯时系统爆出了很多洞,先看他的怎么写的,下面是从他的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中截的。



  &lt;%   newsid=trim(request(”newsid”))   sql = “select * from news where id=”&amp;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”)   %&gt;



使用了request接收,而它会依次的去用3种数据集合(Form,QueryString,cookie)去判断,所以我们可以使用cookie来提交我们构造的SQL语句了.这里就不在截图了,具体可以参考这篇文章《最新版讯时新闻发布系统惊爆cookie漏洞》



但是并不是所有的程序都这么另人兴奋的哦,上次***一个站时,就碰到了这种情况,找到了源码下来看,却没有突破这个防注入。代码如下:



  sub check()


  Fy_Url=Request.ServerVariables(”QUERY_STRING”)


  Fy_a=split(Fy_Url,”&amp;”)


  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)&lt;&gt;”" Then


  If Instr(LCase(Request(Fy_Cs(Fy_x))),”‘”)&lt;&gt;0 or Instr(LCase(Request(Fy_Cs


  (Fy_x))),”and”)&lt;&gt;0 or Instr(LCase(Request(Fy_Cs(Fy_x))),”select”)&lt;&gt;0 or Instr(LCase


  (Request(Fy_Cs(Fy_x))),”union”)&lt;&gt;0 or Instr(LCase(Request(Fy_Cs(Fy_x))),”from”)&lt;&gt;0 or


  Instr(LCase(Request(Fy_Cs(Fy_x))),” “)&lt;&gt;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接受的地方….