个人WafBypass之道(upload篇)

0x00 前言

玩waf固然也要讲究按部就班,姊妹篇就写文件上传好了,感受也就SQLi和Xss的WafBypass最体现发散性思惟的,而文件上传、免杀、权限提高这几点的Bypass更须要的是实战的经验。本文内容为沉淀下来的总结以及一些经典案例。想到哪写到哪,因此可能不是很全。创造姿式不易,且行且珍惜。(案例图很差上,毕竟是upload的Bypass,就直接上姿式)php

阅读此文你会发现新老姿式都有,由于我是想系统的写一写,文件上无非就是结合各类特性或waf缺陷。辍写时想过一个问题,如何归拢哪些属于文件上传Bypass的范畴?打个比方:html

  1. 上传正常.jpg的图片 #成功
  2. 上传正常.php #拦截
  3. 绕过.php文件的filename后进行上传 #成功
  4. 使用绕过了filename的姿式上传恶意.php #拦截

以上这么个逻辑一般来说是waf检测到了正文的恶意内容。再继续写的话就属于免杀的范畴了,过于模糊而且跑题了,并非真正意义上的文件上传Bypass,那是写不完的。web

0x01 搞起

上传文件(歪脖骚)时waf会检查哪里?shell

  1. 请求的url
  2. Boundary边界
  3. MIME类型
  4. 文件扩展名
  5. 文件内容

常见扩展名黑名单:后端

  1. asp|asa|cer|cdx|aspx|ashx|ascx|asax
  2. php|php2|php3|php4|php5|asis|htaccess
  3. htm|html|shtml|pwml|phtml|phtm|js|jsp
  4. vbs|asis|sh|reg|cgi|exe|dll|com|bat|pl|cfc|cfm|ini

我的写的“稍微”全一点,实际上waf的黑名单就不必定这么全了。
测试时的准备工做:安全

  • 什么语言?什么容器?什么系统?都什么版本?
  • 上传文件均可以上传什么格式的文件?仍是容许上传任意类型?
  • 上传的文件会不会被重命名或者二次渲染?

 

0x02 容器特性

有些很老的特性其实也是最开始绕waf的基础,这里就一笔带过了。app

  • Apache1.X 2.X解析漏洞:

Apache在以上版本中,解析文件名的方式是从后向前识别扩展名,直到碰见Apache可识别的扩展名为止。
Win2k3 + APACHE2.0.59 + PHPjsp

1
IIS6.0两个解析缺陷:测试

目录名包含.asp、.asa、.cer的话,则该目录下的全部文件都将按照asp解析。例如:url

2


文件名中若是包含.asp;、.asa;、.cer;则优先使用asp解析。例如:

3


有一点须要注意,若是程序会将上传的图片进行重命名的话就gg了。
Nginx解析漏洞:

  • Nginx 0.5.*
  • Nginx 0.6.*
  • Nginx 0.7 <= 0.7.65
  • Nginx 0.8 <= 0.8.37

以上Nginx容器的版本下,上传一个在waf白名单以内扩展名的文件shell.jpg,而后以shell.jpg.php进行请求。

  • Nginx 0.8.41 – 1.5.6:

以上Nginx容器的版本下,上传一个在waf白名单以内扩展名的文件shell.jpg,而后以shell.jpg%20.php进行请求。

PHP CGI解析漏洞

  1. IIS 7.0/7.5
  2. Nginx < 0.8.3

以上的容器版本中默认php配置文件cgi.fix_pathinfo=1时,上传一个存在于白名单的扩展名文件shell.jpg,在请求时以shell.jpg/shell.php请求,会将shell.jpg以php来解析。
多个Content-Disposition:

在IIS的环境下,上传文件时若是存在多个Content-Disposition的话,IIS会取第一个Content-Disposition中的值做为接收参数,而若是waf只是取最后一个的话便会被绕过。
Win2k8 + IIS7.0 + PHP

4

请求正文格式问题:

  1. Content-Disposition: form-data; name="file1"; filename="shell.asp"
  2. Content-Type: application/octet-stream

正常的upload请求都是以上这样,然而这个格式也并不是强制性的,在IIS6.0下若是咱们换一种书写方式,把filename放在其余地方:
Win2k3 + IIS6.0 + ASP

5

结合.htaccess指定某些文件使用php来解析:

这个方法一般用于绕过waf黑名单的,配置该目录下全部文件都将其使用php来解析:
6

0x03 系统特性

Windows特殊字符:
当咱们上传一个文件的filename为shell.php{%80-%99}时:

7

waf可能识别为.php{%80-%99},就会致使被绕过。
Win2k8 + IIS7.0 + PHP

8

exee扩展名:
上传.exe文件一般会被waf拦截,若是使用各类特性无用的话,那么能够把扩展名改成.exee再进行上传。

NTFS ADS特性:
ADS是NTFS磁盘格式的一个特性,用于NTFS交换数据流。在上传文件时,若是waf对请求正文的filename匹配不当的话可能会致使绕过。

9

Windows在建立文件时,在文件名末尾无论加多少点都会自动去除,那么上传时filename能够这么写shell.php......也能够这么写shell.php::$DATA.......。
Win2k8 + IIS7.0 + PHP

10

0x04 waf缺陷

匹配过于严谨:

一个空格致使安全狗被绕过:

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

尝试在boundary后面加个空格或者其余可被正常处理的字符:

boundary =---------------------------4714631421141173021852555099

Win2k3 + IIS6.0 + ASP

11

以上也能说明一个问题,安全狗在上传文件时匹配各个参数都十分严谨,不过IIS6.0以上也变的严谨了,再看看其余的地方:

每次文件上传时的Boundary边界都是一致的

 

Content-Type: multipart/form-data; boundary=---------------------------4714631421141173021852555099
Content-Length: 253

-----------------------------4714631421141173021852555099
Content-Disposition: form-data; name="file1"; filename="shell.asp"
Content-Type: application/octet-stream

<%eval request("a")%>
-----------------------------4714631421141173021852555099--

但若是容器在处理的过程当中并无严格要求一致的话可能会致使一个问题,两段Boundary不一导致得waf认为这段数据是无心义的,但是容器并无那么严谨:
Win2k3 + IIS6.0 + ASP

12

修改Content-Type的MIME类型:
Win2k3 + IIS6.0 + ASP

13

ASCII > 127的字符:

14

数据过长致使的绕过:

waf若是对Content-Disposition长度处理的不够好的话可能会致使绕过,例如:

Win2k3 + IIS6.0 + ASP

15

基于文件名:基于构造长文件名

16
若是web程序会将filename除了扩展名的那段重命名的话,那么还能够构造更多的点、符号等等。

17

特殊的长文件名:
文件名使用非字母数字,好比中文等最大程度的拉长,不行的话再结合一下其余的特性进行测试:

shell.asp;王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王.jpg

0x05 End

文件上传Bypass可写的点很少,现有的姿式也不能拿出来说(笑)重点在于上传文件时遇到waf可以准确判断所拦截的点,目光不能只盯在waf,更多的时注意后端的状况。每每是须要结合哪些语言/容器/系统*版本“能够怎样”、“不能够怎样”。

相关文章
相关标签/搜索