科普第二篇:%00文件上传漏洞

2013-06-24 10:47:44 21 5647 1
在讲%00上传之前有必要提一下BS双方数据交换的四种方式
一: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
后台asp用request.querystring("aaa")取得值bbb


二: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
数据没有在http头中,同时包含Content-Type: application/x-www-form-urlencoded
后台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的数据,包括文件和表单
Request.BinaryRead与其它四种方式的不同造成了文件上传漏洞的一个原因.

假设客户端是用专门程序写的,在post中的数据为
00000000h: 61 61 61 3D 61 2E 61 73 70 00 2E 6A 70 67       ; aaa=a.asp..jpg
用其它所有的办法在取值的时候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也不会被转换!
Content-Disposition: form-data; name="myfile"; filename="c:\boot.ini"
上述格式很多代码是先找filename="然后再找后面的"来取的文件名,这样取出来的文件名中就是有0x00的.
那么最后再把数据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"
象上面的代码a变量中有0x00,所以生成文件的时候.txt也加不上,直接生成个无后缀的a文件.

通过上传漏洞定义的特殊字符除了0x00还可以是;号利用iis5/6的文件解析漏洞来生成asp比如a.asp;.jpg

关于作者

末日55篇文章1271篇回复

评论21次

要评论?请先  登录  或  注册