今日爆出一个Bash的RCE漏洞,威力巨大。看了看老外的分析,觉得有必要写一写自己对这个漏洞的理解。
首先,问题起因于一个命令ENV。
原型:
env [OPTION]... [NAME=VALUE]... [COMMAND [ARGS]...]
Man是这么说的:
Display, set, or remove environment variables,Run a command in a modified environment.
我的理解是使用env命令的key=value,首先会改变环境变量key,如果没有会临时创建,注意,这里是临时的改变环境变量。然后就把value后面的内容当做命令执行,类似于PHP中的eval。
测试如下:
可以看到,这个命令可以达到的作用是:在临时修改环境变量的同时,也可以执行命令。
网上流传的EXP通常会带有一个User-Agent字段然后后面跟一个字符串。严格意义上来说,这里的User-Agent完全可以使用其他的HTTP字段进行替换。
注意到,ENV本身不是漏洞的成因,漏洞的本质是代码注入。
在bash源码中的处理参数的代码段中:
这段代码是解析匿名函数的时候使用的,使用匿名函数我们才能达到执行的目的:parse_and_execute。这里的string是环境变量的value,name是环境变量的键值。由于没有进行过滤就直接传给temp_string,然后送到parse_and_execute中进行执行了。
也就是说,匿名函数执行完后面本应该结束掉,但是在bash中却又继续执行后面的参数了。
比如:TEST=() { :;}; /bin/cat /etc/passwd
在环境变量导入到bash的同时,也会执行/bin/cat /etc/passwd。
这和CGI的关系是:
对于CGI脚本来说,HTTP协议中的“key-value”都会变为shell中的“环境变量=值”。
-
Host (“www.example.com”,as REMOTE_HOST)
-
Header value (“custom-header-value”, as HTTP_CUSTOM in this example)
-
Server protocol (“HTTP/1.1”, as SERVER_PROTOCOL)
而将客户端信息导入到系统环境变量的时候就会用到ENV了。那么这样一来,我们就可以通过在客户端构造攻击向量去攻击服务器了。从CGI对HTTP参数的处理上看,使用哪个字段都是可以的。
本地测试过程如下:
构造有漏洞的CGI:
访问:http://10.10.10.132/cgi-bin/test
这里我也使用User-Agent进行测试:
结果如下,发送请求之后,服务器会爆出500出错:
但是这时候echo aaa > /tmp/test确实执行了。
验证下:
可以看到,服务器随便报错,但是我们的代码成功执行了。
EXP:
使用nc做个反弹shell就行了,威力挺大吧。
不过这个漏洞可是不好做批量,一种思路就是爬虫+扫描进行CGI链接的获取。当然,还有一种比较无脑的,就是------------------------------------直接抓搜索引擎的。
以上为个人理解,欢迎讨论与错误指正。