通常,网站不会像上个实验那样,对文件上传攻击不做任何防护 。但是仅仅使用防护措施并不意味着就足够了。有时候可以利用文件上传的缺陷来获取web shell
Flawed file type validation 文件类型验证有缺陷
当提交HTML表单时,浏览器会将要提交的数据放到内容类型设置为'application/x-www-form-url-encoded
' 的POST请求中发送给服务器。这个可以很好的用来发送姓名、地址等简单的文本数据。但是用来发送大量的二进制数据的时候就不适用了,比如发送图片或PDF文档。发送这些文件的时候,内容类型就需要设置为'multipart/form-data
'。
如果一个表单用来提交图片和你的用户名,可能长这个样子
POST /images HTTP/1.1 Host: normal-website.com Content-Length: 12345 Content-Type: multipart/form-data; boundary=---------------------------012345678901234567890123456 ---------------------------012345678901234567890123456 Content-Disposition: form-data; name="image"; filename="example.jpg" Content-Type: image/jpeg [...binary content of example.jpg...] ---------------------------012345678901234567890123456 Content-Disposition: form-data; name="description" This is an interesting description of my image. ---------------------------012345678901234567890123456 Content-Disposition: form-data; name="username" wiener ---------------------------012345678901234567890123456--
可以看到,消息体中每个表单的输入被相互分成独立的部分,每部分都包含一个’Content-Disposition‘头,声明了输入内容的基本信息。每部分还可能包含自己的’Conten-Type‘头,向服务器声明这部分输入的MIME类型。
网站可能通过检查'Content-Type'头是否匹配MIME类型来进行文件上传验证。问题在于服务器默认信任’Content-Type'头,如果不进行进一步验证,检查文件的内容是否确实和MIME类型匹配的话,这种防护可以很轻松的使用Burp Repeater绕过。