由于代码绕过WAF上传的tips
前言
最近审到一个通用的文件上传漏洞,但是在做测试的过程中遇到多种不同的WAF产品,一开始怎么都绕不过去,后面发现代码上的问题,然后基本上全绕过了
分析
看到很多系统文件上传获取文件名的代码都是类似这样
String fileExt=filename.substring(filename.lastIndexOf(".") + 1);
String newfileName = (new StringBuilder()).append("ico").append(System.currentTimeMillis()).append("_on.").append(fileExt).toString();
这段代码通过 lastIndexOf(".")
获取原始文件名 filename
中最后一个点 .
后的位置,然后用substring()
截取作为文件的扩展名,然后直接拼接在新生成的文件名上。
这就有个问题了,如果上传的文件名没有.
那么lastIndexOf()
会直接返回-1
就会造成文件扩展名=文件名
String fileExt=filename.substring(0)=>String fileExt=filename
而实战中大多数WAF都是在文件后缀做检测,很少有对整个文件名检测,当文件名中不带.
,直接就上传没有进行拦截
某狗没有参考价值,这里使用某亭雷池WAF测试,文件上传检测设置最高
进行正常上传jsp文件被拦截
但是可以看到直接文件名为jsp
则不会拦截,而且成功上传
像使用这种方式获取文件扩展名进行拼接的系统不是个例
浙江某华智慧园区综合管理
某矩信息校友平台
修复方式
修复方式上代码上可以是先判断是否存在文件扩展名再去进行处理,这样WAF才能有效拦截
//if(filename.contains("."))
if (filename.lastIndexOf(".")>-1) {
String fileExt = filename.substring(filename.lastIndexOf(".") + 1);
String newfileName = (new StringBuilder()).append("ico").append(System.currentTimeMillis()).append("_on.").append(fileExt).toString();
又或者代码截取的文件扩展名进行白名单校检再去进行文件名的拼接处理
String[] allowedFileExtensions = new String[] { "txt", "pdf", "png", "jpg", "gif", "html" };
String fileExtension = filename.substring(filename.lastIndexOf(".") + 1);
if (java.util.Arrays.asList(allowedFileExtensions).contains(fileExtension)) {
String newfileName = (new StringBuilder()).append("ico").append(System.currentTimeMillis()).append("_on.").append(fileExtension).toString();
System.out.println(newfileName);
} else {
System.out.println("false");
}
WAF如果能添加规则可以添加像匹配整个文件名是否等于黑名单