讯时网站管理系统2.70漏洞分析

irrelevant:

10月1日放国庆了,该死的学校30号晚上尽然还要上晚自习,没有办法只有10月1日回家了。在寝室看完了国庆60周年的阅兵式,这次大家的普遍的反应是没有50周年好看。那个猥琐的导播的技术也确实是烂到了家。最牛逼的还是小平同志那个时候的阅兵式,打过仗的就是不一样啊。今天是十月五日,晃眼间今天就5日了,国庆就过了大半,无所谓,反正学校、家里的生活对我来说没有好大的区别,现在最想的还是找工作,实践自己的所学。

——————————————————–

今天没有事情做,友情检测了一个站点 ,思路和过程我会详细记录,此本发布之前已经修补好了所有的漏洞,请看官不要徒劳。检测的主要目的是学习安全技术,挂马死全家。

首先瞥了一下网站的基本构架,89不离10是用asp+access搭建的,安全性非常让人质疑,然后随便打开一个带有参数的地址:http://www.xxx.com/xsnews/News_View.asp?NewsID=80 。

习惯性的在网站后面的参数加上’ 成了:

http://www.xxx.com/xsnews/News_View.asp?NewsID=80′

结果网页照常正常显示,只是新闻导航有点变化:

动态信息 – [新闻标题] 变成了:$$路径$$ ,我8成估计是模板代码。我突然发现子目录的名字是xsnews,就直接打开这个子目录:

http://www.xxx.com/xsnews/

xuas

网站使用的是讯时网站管理系统,但是具体的版本还是未知,我姑且算它使用的是最新版本,就到官方网站下载了一个最新的版本本地假设好,来研究研究:http://www.xuas.com/view.asp?id=2 ,access版本是免费的,mssql是收费的。

xuas_file_list

down下来,看了看文件目录,我艹,这完全没有统一的命名规范嘛,有大写的,有小写的,有“-”连接的,有“_”连接的。还有后面加“2”的,首先一点来判断这个系统就是做得不专业(当然叫我做不一定做得出来,但至少俺至少了解一些系统开发时的一些规范)。

既然前台的sql注入没有希望了,那么我们来看看后台登录代码 login.asp,最牛逼的是这几行,用随机数来生成验证码,这种验证码用了等于没有用,写个js应该可以自动获取里面的值,然后自动填写注册码。理论是这样的,我有时间实验一下。

171
172
173
174
175
Randomize
an=""
an= int((99999-11111+1) * RND +11111)
session("xuasyzm")=an
Response.Write an

———————以下是表单的详细信息:

ID 名称 方法 操作
FrontPage_Form1 POST admin_login.asp

元素

索引 ID 名称 类型 标签 大小 最大长度 状态
0 user text 24 20
1 pass password 24 20
2 XuasYzm 9 5
3 B1 image 提交

登录到admin_login.asp进行验证,分析一下13行开始的代码

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
For each j in Request.QueryString
    sss= sss& j & Request.QueryString(j)
Next
For each j in Request.form
    sss= sss& j & Request.QueryString(j)
Next
sss=sss&LCase(request.servervariables("QUERY_STRING"))
GuoLv="select,insert,;,update,',delete,exec,admin,count,drop,from,truncate,xp_cmdshell,netlocalgroup,and,chr,master,declare,*,char,script,%"      '过滤掉get和form中的这些关键字来防止注入
GuoLvA=split(GuoLv,",")
for i=0 to ubound(GuoLvA)
  if instr(sss,GuoLvA(i))<>0 then
    Response.Redirect "res://shdoclc.dll/dnserror.htm"  '有注入关键字自动跳转到牛逼的“找不到服务器”页面。
    response.end       
  end if
next


  sql = "select * from [admin]"
  Set rs = Server.CreateObject("ADODB.RecordSet"):rs.cursorlocation=3
  rs.Open sql,conn,1,1
  if rs.recordcount=0 then
    conn.Execute "insert into [admin] ([user],[pass],[dj]) values('admin','"&md5("admin")&"','1')"
  end if  '如果admin表中没有记录,自动插入一条用户名和密码都是admin的记录。
  rs.close:set rs=nothing

看来用户名密码填写’or’='or’ 或者 ‘or”=’ 等万能密码是没有希望了,都被过滤干净了,继续看代码。。。
假设登录成功会转向到admin_index.asp , 直接打开admin_index.asp会自动跳转到login.asp,说明admin_index.asp做了cookie或者是session验证。发现后台大部分的文件都包含了admin_chk.asp , 这是验证的关键文件:

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
session("admin__user")=Request.Cookies("adminuser")
session("admin__pass")=Request.Cookies("adminpass")
session("dJ")=Request.Cookies("admindj")

adminuser=Request.Cookies("adminuser")
adminpass=Request.Cookies("adminpass")
admindj=Request.Cookies("admindj")

if adminuser="" or adminpass="" then
  Response.Redirect "login.asp?id=8"
end if
%><!--#include file = admin_conn.asp -->

<!--#include file = md5.asp -->
<%


user=trim(session("admin__user"))
pass=session("admin__pass")

sql = "select * from admin where [user]='"&adminuser&"' and [pass]='"&adminpass&"'"
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql,conn,1,1
if rs.recordcount=0 then
  Response.Redirect "login.asp?id=8"
end if
rs.close
set rs=nothing
conn.close
set conn=nothing

这个文件的主要目的是先取得三个cookie变量:adminuser,adminpass,admindj, 然后分别把这3个cookie变量赋值给session变量:admin__user,admin__pass,dJ变量和同名的三个变量。如果adminuser,adminpass没有值,直接跳转到登录页面,验证失败。
然后把这些变量弄到sql语句中运行,这个时候就可以利用cookie来注入。一般情况下小黑用的是”桂林老兵的cookie browser”,可以在本地构造自己的cookie,但是我选择使用firefox的插件firebug的插件firecookie(后来证明我sb了,因为后台的ewebeditor是IE6 only的)。

cookie加入adminuser值为admin,adminpass值为’or’='or’,admindj值为1 ,如图直接地址栏输入admin_index.asp

xuas_cookie_bug

如图可以发现使用的是讯时2.7系统,就在网站抓了个2.7,然后本地假设,这样至少代码没有好大的区别。
接下来就是上传webshell了,方法很简单,修改或者是添加一个新闻,然后用ewebeditor编辑器上传一个图片格式的asp小马,然后在数据库备份那点把图片格式改为asp,asa,cer,htr等等,反正iis可以解析执行就ok….

xuas_webshell

webshell得到了,就打算收工了,但是还发现了一个漏洞,新闻里面的图片地址类似于:

http://www.xxx.com/xsnews/edit/UploadFile/2008613172630223.jpg

这及其可能是ewebeditor编辑器,直接打开http://www.xxx.com/xsnews/edit/ewebeditor.asp的确有这个文件,但是比较恼火的是讯时用的ewebeditor没有后台,所以没有办法通过以前增加样式,然后在样式里面把asp后缀添加到可执行文件中来。不过还有个/xsnews/edit/Admin_UploadFile.asp get参数dir的目录遍历漏洞,直接直接遍历整个网站目录:
admin_uploadfile.asp?id=xx&dir=../../../

这样找access数据库,下载,md5破解密码就也可以登录到后台。

Admin_UploadFile.asp权限验证的代码如下:

6
7
8
9
if Request.Cookies("admindj")<>"1" then
   Response.Write "<BR><BR><BR><BR><center>权限不足,你没有此功能的管理权限"
   Response.end
end if

确实是够雷人的,这就是为啥要把cookie里面的admindj改为1的原因所在。
另外还有一部分后台管理文件没有包含admin_chk.asp任何人可以直接浏览,简单列表如下:
admin_stat_user.asp //所有用户文章添加排行榜,通过这个可以直接查看后台管理员用户名,如果默认的管理员用户名
//admin被改了,也可以把上面讲的cookie变量adminuser改成相应的名字
admin_ly.asp
admin_news_add_dj.asp
admin_news_addd_dj3.asp
admin_news_pl_view.asp?action=save&id=
admin_news_view.asp
admin_newspl_del.asp
aspcheck.asp
检测完了,然后说说漏洞的修补,cookie注入在4.0中已经修补:

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function chkh(stra)
  stra=replace(stra,"<","&lt;")
  stra=replace(stra,">","&gt;")
  stra=replace(stra,"'","")
  stra=replace(stra,"(","(")
  stra=replace(stra,")",")")
  stra=replace(stra,";",";")
  stra=replace(stra,",",",")
  stra=replace(stra,"%","%")
  stra=replace(stra,"+","+")
  chkh=stra
end function
session("admin__user")=chkh(Request.Cookies("adminuser"))
session("admin__pass")=chkh(Request.Cookies("adminpass"))
session("dJ")=chkh(Request.Cookies("admindj"))

adminuser=chkh(Request.Cookies("adminuser"))
adminpass=chkh(Request.Cookies("adminpass"))
admindj=chkh(Request.Cookies("admindj"))

然后把admin_uploadfile.asp加入admin_chk.asp的包含,算了补住了。

通过这次检测,已经以前的一些小经验,我觉得web安全在中国还是任重而道远。当然现在这种弱智漏洞已经很少出现了,现在流行的是xss,csrf,深入研究还在进行中。

也许你对以下文章感兴趣

Tags: , , ,  

4 Comments

  1. 你凶……

    Reply

  2. 国内流传的很多系统,自己名声吹很大,但是真的做得很差。
    我一直有这个观念

    Reply

    tunpishuang Reply:

    做得专业的还是有,只是比较少而已。比如dz,动易,phpwind,动网,有些国外的论坛都用的dz.

    Reply

  3. discuz那是经典了。我前几天找平台的时候无意间找到了个“帝国”。。自己吹很多人用他们的- -结果却问,人家都说是他自己在吹的- -

    Reply

留下评论

*
To prove you're a person (not a spam script), type the security word shown in the picture.
Anti-spam image