在测试绕过WAF执行远程代码之前,首先构造一个简单易受攻击的远程代码执行脚本,如图
所示第6行是一个明显的命令执行代码,第3行尝试拦截诸如系统,exec或pass-thru之类的功能(PHP中还有许多其他可以执行系统命令的功能,这三个是最常见的)。
> >此脚本在CloudFlare WAF和ModSecurity + Owasp CRS3后面部署。对于第一个测试,请尝试阅读传递的内容。
/cfwaf.php?code=system("cat /etc/passwd");
如您所见,它是由Cloudflare拦截的,我们可以尝试使用非初始化的变量来绕过它,例如
cat /etc$u/passwd
CloudFlare WAF已被绕过,但是由于脚本检查敏感功能,因此被脚本阻止,因此如何绕过脚本的函数检测?让我们看一下字符串上的PHP文档。
https://secure.php.net/manual/en/language.types.string.php
php字符串逃脱序列:
-
[0â7] {1,3}字符序列中的八分位数序列会自动溢出以适合一个字节(例如“ 400” ====“!¿½00”)
-
x [0â9a-fa-f] {1,2}十六进制字符的序列(例如“ x41”)
-
u {[[0â9a-fa-f]+} unicode代码点的顺序输出到字符串,作为该代码点的UTF-8表示(添加在PHP 7.0.0中)
并不是每个人都知道代表字符串的PHP语法,“ PHP变量函数”成为我们绕过过滤器和规则的瑞士刀。
PHP变量函数
PHP支持可变功能的概念。这意味着,如果将括号附加到变量名称上,则PHP将寻找一个与变量评估相同名称的函数,并尝试执行它。除其他外,这可用于实现回调,功能表等。
这意味着语法类似于$ var(args)和“ sting”(args等于func(args)。如果我可以使用变量或字符串调用函数,则意味着我可以使用逃生序列而不是函数名称。这是一个示例
第三种语法是十六进制符号的逃生字符序列,PHP将其转换为字符串“系统”,然后使用参数“ LS”将其转换为功能系统。让我们尝试一个脆弱的脚本
此技术不适用于所有PHP功能,变量函数不适用于echo,print,unset(),isset(),empty(),inclage和requient。将这些构造中的任何一个用作带有包装函数的Variadic函数。
改进的用户输入检测
如果我将诸如双引号和从用户输入中的单引号等字符排除到脆弱脚本会发生什么?即使不使用双引号,也可以解决它吗?让我们尝试
您在第三行上看到的是,脚本现在阻止了$ _get [code]查询字符串参数中的“和”的使用。我以前的有效载荷现在应该被阻止
幸运的是,在PHP中,我们并不总是需要报价来表示字符串。 PHP使您可以声明元素的类型,例如$ a =(string)foo,在这种情况下,$ a包含字符串“ foo”。另外,没有特定类型声明的括号内的任何东西都被认为是字符串
在这种情况下,我们有两种绕过新过滤器的方法。首先是使用(系统)(LS)之类的东西,但是我们不能在代码参数中使用“系统”,因此我们可以像(SY。(ST).EM)(LS)(LS)一样执行此操作,与串联字符串相同。第二个是使用$获取变量。如果我发送诸如?a = system&b = ls&code = $ get a的请求,结果为$ get [a]将被字符串“系统”代替,$ get [b]将被字符串“ ls”代替,我将能够绕过所有过滤器!
让我们尝试第一个有效载荷(sy。(st).em)(whoami);
和第二个有效载荷?
?a = system&b = cat+/etc&c =/passwd&code = $ _ geta;
在这种情况下没有用,但是您甚至可以在功能名称和参数中插入注释(这可能有助于绕过阻止特定PHP功能名称的WAF规则集)。以下所有语法都是有效的
get_defined_functions函数
此PHP功能返回一个多维数组,其中包含所有已定义函数的列表,包括内置(内部)和用户定义的函数。可以使用$ arr [内部]访问内部功能,并且可以使用$ arr [user [user]访问用户定义的功能。例如
这可能是访问系统功能而无需使用其名称的另一种方法。如果我为“系统”而grep,我可以发现其索引编号,并将其用作我的代码执行的字符串
显然,这应该适用于我们的Cloudflare WAF和脚本过滤器
字符阵列
PHP中的每个字符串都可以用作字符数组(几乎就像在Python中),您可以使用语法$ string [2]或$ string [-3]参考单个字符串字符。这可能是规避阻止PHP功能名称的规则的另一种方法。例如,使用此字符串$ a =“ elmsty/”,我可以编写一个语法系统(“ ls/tmp”)。
如果幸运的话,可以在脚本文件名中找到所需的所有字符。使用相同的技术,您可以选择所有想要的字符,例如
OWASP CRS3
使用OWASP CRS3,一切都更加困难。首先,使用我以前见过的技术,我只能绕过偏执狂的第一级,这真是太神奇了!由于偏执狂1只是我们在CRS3中找到的规则的一小部分,因此该级别旨在防止任何误报。对于第2级偏执狂,由于规则942430“受限制的SQL字符异常检测(ARGS),超过特殊字符的数量”,一切都变得困难。我所能做的就是执行命令,而没有参数,例如“ ls”,“ whoami”等。但是我无法像我使用CloudFlare WAF一样执行诸如System(“ CAT/ETC/passWD”)之类的命令。
。来源:-https://tutorialboy24.blogspot.com/2023/07/bypassing-php-waf-to-achieve-remote.html