本文介绍一个使用FUZZDB在Web环境下的测试方法

0x01 前言

今天工作的时候帮同事验证一些漏洞,发现客户在扫描阶段结束后将WAF(Web Application FireWall)开启了,这就比较麻烦了。

于是想到之前很久决定做的事情:使用FUZZDB来进行WAF的遗漏规则挖掘……

去年五六月份在知乎写了几篇关于WAF的上传、注入,也分享过不少方法,但是没有一个系统的测试手法,原理没有做一个很清楚的总结,今天就来讨论一下。

0x02 为什么要学习ByPass

在安全圈里,很多基本简单的项目都是直接使用扫描器上去直接干,喝杯茶回来看结果,情况好的、感兴趣的,可能会用手工来试试。在Web渗透测试工程师的眼中:越红越感兴趣,权限越大越欢喜。当我们应对存在WAF的应用服务器的时候,好多人选择联系客户,让客户将防护暂时开启,使扫描器“大展神威”……

而关于FUZZ的技术在应用软件领域相对较为成熟,而且仅仅靠”OverFlow”就能挖掘许多bug、漏洞。

在Web层面,很少有关于FUZZ成熟的方法,我也懒得造轮子。在这里举一些Web渗透中常规FUZZ相关的手段:

  • 目录扫描
  • 口令枚举
  • 爬虫
  • ….

其实都有一些相似。

为了提高自己的能力,当然要与防御正对面的较量,有WAF是常有的事,当没有其他方式去达到目的只能选择规则对抗。

如果你还不会Bypass,或者不理解Bypass的原理,你可能不是一个合格的渗透测试工程师……

0x03 ByPass的原理

在这里我们构建一个概念模型:

模型

Bypass就是寻找大于深绿区域的那块黑色内容

没有绝对安全的系统,当然防护是一样

通常情况下,我们的目的都是发送一些攻击且能够快速有效验证漏洞payload,但是这些常用的payload都被WAF加入了规则库中,如果遇到了规则库中存在的payload,WAF就要出来搞事情了,它会记录你的攻击数据,并且将到达Web服务器之前的数据给丢弃。如此一来,我们无法进行进一步的测试了,所以心情复杂、焦躁、甚至想哭唧唧。

0x04 FuzzDB

  • GIT:https://github.com/fuzzdb-project/fuzzdb
  • Github star 1800+

FuzzDB是为了通过动态应用程序安全性测试来增加引起和识别安全感兴趣条件的可能性。

这是第一个也是最全面的故障注入模式的开放字典,可预测的资源位置,以及匹配服务器响应的正则表达式。

这个项目很可观,包括了针对各种应用程序的测试payload,我经常使用它来去进行FUZZ模糊测试以及漏洞挖掘,平常收集的密码字典也会往里添加。它已经成为了我居家旅行不可或缺的字典库。

工具

以下这些工具都有采用FUZZDB这个项目,只是大家没有发现:

  • OWASP Zap Proxy fuzzdb plugin https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project
  • SecLists https://github.com/danielmiessler/SecLists
  • TrustedSec Pentesters Framework https://github.com/trustedsec/ptf
  • Rapid7 Metasploit https://github.com/rapid7/metasploit-framework
  • Portswigger Burp Suite http://portswigger.net
  • Protofuzz https://github.com/trailofbits/protofuzz
  • BlackArch Linux https://www.blackarch.org/
  • ArchStrike Linux https://archstrike.org/

0x05 实战挖掘一个WAF的缺漏规则 - 文件上传

首先我们先将一个基本的文件上传数据包贴出来分析:

POST /upload_file.php HTTP/1.1
Host: 10.211.55.12
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://10.211.55.12/upload.html
X-Forwarded-For: 10.74.183.12
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=--------302761576
Content-Length: 502

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

........

‰----------302761576
Content-Disposition: form-data; name="submit"

Submit
----------302761576--

一般WAF会选择快速匹配上传数据包中的filename,而不会首要验证文件的内容,因为消耗资源。

知道了这个我们可以搭建一个简单的上传页面进行上传测试

<?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/png")
)
&& ($_FILES["file"]["size"] < 20000))
  {
  if ($_FILES["file"]["error"] > 0)
    {
    echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
    }
  else
    {
    echo "Upload: " . $_FILES["file"]["name"] . "<br />";
    echo "Type: " . $_FILES["file"]["type"] . "<br />";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
    echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";

    if (file_exists("upload/" . $_FILES["file"]["name"]))
      {
      echo $_FILES["file"]["name"] . " already exists. ";
      }
    else
      {
	$newfileName = rand().$_FILES["file"]["name"];
      move_uploaded_file($_FILES["file"]["tmp_name"],
      "upload/" . $newfileName);
      echo "Stored in: " . "upload/" . $newfileName;
      }
    }
  }
else
  {
  echo "Invalid file";
  }
?>

然后寻找一些文件名中不经常出现的字符(从FUZZDB中寻找)。

我这里找了一部分:

%2500
%2501
%2502
%2503
%2504
%2505
%2506
%2507
%2508
%2509
%250a
%250b
%250c
%250d
%250e
%250f
%2510
%2511
%2512
%2513
!
"
#
$
%
&
'
(
)
*
+
,
-
.
/
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
_
`
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~

它们的顺序和组合方式都可以任你掌控。

我导入到Burp中,准备枚举了一轮:

Burp

可以看到我只添加了三个变量,分别对应一些编码、特殊字符、英文字母,就出来了一些意想不到的结果

Burp

然后跟进分析:

Burp

经过三四次测试,结果发现filename中若存在单引号就可以绕过WAF进行上传。

这无疑是一个好消息,证明了Fuzzing的强大。

文件

去访问文件的时候发现一个坑,这个文件本身是存在的,是不是操作系统或者Web服务器的原因导致携带单引号的文件名无法读取?

文件

经过思考结论如下:

即使将单引号进行编码也无法通过浏览器访问,因为它会将URL解码。

我们直接通过Burp访问即可:

文件

0x06 思考

WAF的出现对于没有安全防护意识的用户来说真的是一个福音,也包括国内一些小众cms都强烈建议用户在服务器上安装一些软WAF。

我个人觉得这种情况很不理想,并且不会推动安全产业的良性发展,真正的测试就该直面问题,直起腰板说:“你们的WAF防护能力不行,但是你们的应用出现了漏洞比WAF更加垃圾。”

许多站长的网站被攻击、挂马,我觉得不应该是WAF服务商背锅,真正背锅的还是安全意识,矛头应该指向整个产品线负责的相关人员。

写到这里,若有任何想法和建议,可以移步About,添加我的微信交流。