shell shock 执行漏洞分析
2015-02-24 16:08
120 查看
该漏洞相关报道:
http://www.freebuf.com/news/44805.html
http://www.csoonline.com/article/2687265/application-security/remote-exploit-in-bash-cve-2014-6271.html
如果输出:
表示存在漏洞。打了补丁会输出以下错误:
而根据漏洞信息得知,这个漏洞产生于Shell在处理函数定义时,执行了函数体之后的命令。但这里x的值是个字符串,它是怎么转变成函数的呢。
实际这个和Bash实现有关,在Bash中定义一个函数,格式为:
当Bash在初始化环境变量时,语法解析器发现小括号和大括号的时候,就认为它是一个函数定义:
上面代码在新的Bash进程中,
1、新的bash在初始时,扫描到环境变量
2、bash把
typeset命令可以列出当前环境中所有变量和函数定义,我们用typeset看看这个字符串怎么变成函数的。继续上面定义的
这里新启动了个Bash进程,然后执行了typeset,typeset会返回当前环境(新的环境)中所有定义,这里清楚看到say_hello被变成函数了。
通过结合补丁,我对Bash的源码简单分析了下,Bash初始化时调用了
继续看
它判断命令是否是一个定义成全局的,新的bash进程启动后,
其实Bash本身其实是想在启动时初始环境变量以及定义一些函数,而初始的方式就是去把
http://www.freebuf.com/news/44805.html
http://www.csoonline.com/article/2687265/application-security/remote-exploit-in-bash-cve-2014-6271.html
测试
在Bash Shell下执行以下代码:env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
如果输出:
vulnerable this is a test
表示存在漏洞。打了补丁会输出以下错误:
bash: 警告: x: ignoring function definition attempt bash: `x' 函数定义导入错误 this is a test
原理分析
Shell里可以定义变量,POC中定义了一个命名为x的变量,内容是一个字符串:() { :;}; echo vulnerable
而根据漏洞信息得知,这个漏洞产生于Shell在处理函数定义时,执行了函数体之后的命令。但这里x的值是个字符串,它是怎么转变成函数的呢。
实际这个和Bash实现有关,在Bash中定义一个函数,格式为:
function function_name() { body; }
当Bash在初始化环境变量时,语法解析器发现小括号和大括号的时候,就认为它是一个函数定义:
[lu4nx@lx-pc ~]$ say_hello='() { echo hello world; }' [lu4nx@lx-pc ~]$ export say_hello [lu4nx@lx-pc ~]$ bash -c 'say_hello' hello world
上面代码在新的Bash进程中,
say_hello成了新环境中的一个函数,它的演变过程如下:
1、新的bash在初始时,扫描到环境变量
say_hello出现小括号和大括号,认定它是一个函数定义
2、bash把
say_hello作为函数名,其值作为函数体
typeset命令可以列出当前环境中所有变量和函数定义,我们用typeset看看这个字符串怎么变成函数的。继续上面定义的
say_hello函数:
[lu4nx@lx-pc ~]$ bash -c 'typeset' | fgrep -A 10 say_hello say_hello () { echo hello world }
这里新启动了个Bash进程,然后执行了typeset,typeset会返回当前环境(新的环境)中所有定义,这里清楚看到say_hello被变成函数了。
漏洞产生原因
而这个漏洞在于,Bash把函数体解析完了之后,去执行了函数定义后面的语句,为啥会这样呢。通过结合补丁,我对Bash的源码简单分析了下,Bash初始化时调用了
builtins/evalstring.c里的
parse_and_execute函数。是的,就等于Bash初始化环境时调用了类似其他高级语言中的
eval函数,它负责解析字符串输入并执行。
继续看
parse_and_execute的源码,关键点在这里:
218 else if (command = global_command) 219 { 220 struct fd_bitmap *bitmap;
它判断命令是否是一个定义成全局的,新的bash进程启动后,
say_hello不仅被解析成函数了,还变成全局的了:
[lu4nx@lx-pc data]$ bash -c 'typeset -f' say_hello () { echo hello world } declare -fx say_hello
declare命令是Bash内置的,用来限定变量的属性,-f表示
say_hello是一个函数,-x参数表示
say_hello被export成一个环境变量,所以这句话的意思是让
say_hello成了全局有效的函数。
其实Bash本身其实是想在启动时初始环境变量以及定义一些函数,而初始的方式就是去把
变量名=值这样的赋值语句用eval去执行一次,如果出现了函数定义,就把它转变成函数,除此之外就不想让它干其他的了,可偏偏它在扫描到函数定义时,把它转变成函数的过程中不小心执行了后面的命令,这其实不是eval的错,这是做语法解析时没考虑严格,所以补丁加了这么一句话来判断函数体合法性:
if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def)
补充
另外,很多人疑惑POC里{ :; }这句中的冒号和分号,分号作为结束符,而冒号的意思是什么也不做,类似Python里的
pass,具体看Bash官方文档。
相关文章推荐
- Struts2/XWork < 2.2.0远程执行任意代码漏洞分析及修补
- ElasticSearch远程任意代码执行漏洞(CVE-2014-3120)分析
- Struts2远程命令执行漏洞 S2-045 源码分析
- Supervisord远程命令执行漏洞分析(CVE-2017-11610)
- Maccms8.x 命令执行漏洞分析
- Struts2/XWork < 2.2.0远程执行任意代码漏洞分析及修补[转自Neeao's Blog]
- CVE-2017-9805:Struts2 REST插件远程执行命令漏洞(S2-052) 分析报告
- PHPMailer 命令执行漏洞(CVE-2016-10033)分析
- 【漏洞分析】流行开源电子邮件程序Roundcube v1.2.2命令执行漏洞分析
- OrientDB远程代码执行漏洞利用与分析
- Struts2(s2-016)远程代码执行漏洞详细代码分析
- Bash 3.0-4.3命令执行漏洞分析
- 【漏洞分析 】齐博分类系统 代码执行
- PHPMailer 命令执行漏洞(CVE-2016-10033)分析(含通用POC)
- CVE-2012-0003 Microsoft Windows Media Player ‘winmm.dll’ MIDI文件解析远程代码执行漏洞 分析
- Samba远程崩溃或代码执行漏洞(CVE-2015-0240)简要分析
- 某远程代码执行漏洞影响超过70个不同的CCTV-DVR供应商的漏洞分析
- Struts2 S2 – 032远程代码执行漏洞分析报告
- Struts2 S2 – 032远程代码执行漏洞分析报告 .
- CVE-2017-9805:Struts2 REST插件远程执行命令漏洞(S2-052) 分析报告