科普第二篇:%00文件上传漏洞
在讲%00上传之前有必要提一下BS双方数据交换的四种方式
一:get方式,比如在地址栏访问:http://127.0.0.1/x.asp?&aaa=bbb后台asp用request.querystring("aaa")取得值bbb
二:post方式一般为表单提交数据,ie中method必须指定post才能提交数据没有在http头中,同时包含Content-Type: application/x-www-form-urlencoded
后台asp用request.form("aaa")取得值bbb
三:后台对http头中其它方式四:传文件后台代码
Bin=Request.BinaryRead(Request.TotalBytes)
总结:因为客户端提交数据的不同方式,造成了后台取数据方式的不同.不过都要用到request对象
对于Request.BinaryRead与其它四种方式的不同造成了文件上传漏洞的一个原因.
假设客户端是用专门程序写的,在post中的数据为用其它所有的办法在取值的时候0x00后面的.jpg都自动丢掉.等于是取字符串遇到0x00就当是结尾了.对于get方式和form表单中的%00,在querystring的时候会自动做一次解码解成0x00然后还是后面的数据被丢弃.对于servervariables取user_agent/query_string则不会转换,还是字串%00.同时直接发包在http头中不能包含0x00.而用BinaryRead方法,因为本来就是为了能读取二进制数据而设计所以0x00不可能被丢弃,然后因为用这个方式取到的数据的类型为bin,所以通常的代码是利用adodb.stream控件来读取数据,而文件上传时因为文件名也在post数据中,所以通常的代码是通过分析文件上传的格式来取得文件名的,而这时数据为bin方式是可以包含0x00的.然后会用stream对象的格式把bin转成text,而这种转换0x00也不会被转换!上述格式很多代码是先找filename="然后再找后面的"来取的文件名,这样取出来的文件名中就是有0x00的.
那么最后再把数据filename=objfile.readtext,这样给一个字符串变量时这个变量中还是有0x00,那么再调用fso建文件的时候
objFSO.OpenTextFile("c:\inetpub\wwwroot\"+filename+".txt",8,1)
后面加上的.txt就将失效!!
所以重要的地方是在取文件名的时候要判断是否有0x00等特殊字符.或者fso或adodb.stream在生成文件的函数中做检查.象上面的代码a变量中有0x00,所以生成文件的时候.txt也加不上,直接生成个无后缀的a文件.
通过上传漏洞定义的特殊字符除了0x00还可以是;号利用iis5/6的文件解析漏洞来生成asp比如a.asp;.jpg
一:get方式,比如在地址栏访问:http://127.0.0.1/x.asp?&aaa=bbb
GET /1.asp?aaa=bbb HTTP/1.1
Accept: image/gif
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0;)
Host: 127.0.0.1
Connection: Keep-Alive
Cookie: ASPSESSIONIDQSTDDATQ=NEINJIKCBCMOIHEDBJJHGKMH
二:post方式一般为表单提交数据,ie中method必须指定post才能提交
<form action=http://hi_heige.com/1.asp method=post>
<input type=text name=ccc value=ddd>
<input type=submit value="send">
</form>
POST /1.asp HTTP/1.1
Accept: image/gif
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0;)
Host: hi_heige.com
Content-Length: 7
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: ASPSESSIONIDQSTDDATQ=NEINJIKCBCMOIHEDBJJHGKMH
ccc=ddd
后台asp用request.form("aaa")取得值bbb
三:后台对http头中其它方式
request.servervariables("http_user_agent")
request.cookies
<form action=http://hi_heige.com/1.asp method=post ENCTYPE=multipart/form-data>
<input type=file name=myfile>
<input type=submit value="send">
</form>
POST /1.asp HTTP/1.1
Accept: image/gif
Accept-Language: zh-cn
Content-Type: multipart/form-data; boundary=-----7dd12019701c4
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0)
Host: hi_heige.com
Content-Length: 426
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: ASPSESSIONIDQSTDDATQ=NEINJIKCBCMOIHEDBJJHGKMH
-----7dd12019701c4
Content-Disposition: form-data; name="myfile"; filename="c:\boot.ini"
Content-Type: application/octet-stream
[boot loader]
timeout=3
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /fastdetect /NoExecute=OptIn /noguiboot
-----7dd12019701c4--
Bin=Request.BinaryRead(Request.TotalBytes)
总结:因为客户端提交数据的不同方式,造成了后台取数据方式的不同.不过都要用到request对象
对于
request.querystring("aaa") 只能取url中提交的数据
request.form("aaa") 只能取表单数据
request.cookies 只能取cookie
request.servervariables("http_user_agent") 只能取http头
request("aaa") 按上面的顺序取
Request.BinaryRead(Request.TotalBytes) 可以取post的数据,包括文件和表单
假设客户端是用专门程序写的,在post中的数据为
00000000h: 61 61 61 3D 61 2E 61 73 70 00 2E 6A 70 67 ; aaa=a.asp..jpg
Content-Disposition: form-data; name="myfile"; filename="c:\boot.ini"
那么最后再把数据filename=objfile.readtext,这样给一个字符串变量时这个变量中还是有0x00,那么再调用fso建文件的时候
objFSO.OpenTextFile("c:\inetpub\wwwroot\"+filename+".txt",8,1)
后面加上的.txt就将失效!!
所以重要的地方是在取文件名的时候要判断是否有0x00等特殊字符.或者fso或adodb.stream在生成文件的函数中做检查.
Set objFSO = CreateObject("Scripting.FileSystemObject")
a=chr(65)+chr(00)+chr(65)
msgbox len(a) '这时a的长度还是3
Set objCountFile = objFSO.OpenTextFile(a+".txt",8,1)
objcountfile.writeline "aa"
通过上传漏洞定义的特殊字符除了0x00还可以是;号利用iis5/6的文件解析漏洞来生成asp比如a.asp;.jpg
评论21次
沙发啊 第一次当沙发激动啊