Bash

env x=’() { :;}; 是什麼意思?命令’ bash 做,為什麼它不安全?

  • March 24, 2017

bash 中顯然存在一個漏洞(CVE-2014-6271):Bash 特製環境變數程式碼注入攻擊

我試圖弄清楚發生了什麼,但我不完全確定我理解它。如何echo在單引號中執行?

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

編輯 1:修補系統如下所示:

$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
this is a test

編輯 2:有一個相關的漏洞/更新檔:CVE-2014-7169,它使用了稍微不同的測試:

$ env 'x=() { :;}; echo vulnerable' 'BASH_FUNC_x()=() { :;}; echo vulnerable' bash -c "echo test"

未打更新檔的輸出

vulnerable
bash: BASH_FUNC_x(): line 0: syntax error near unexpected token `)'
bash: BASH_FUNC_x(): line 0: `BASH_FUNC_x() () { :;}; echo vulnerable'
bash: error importing function definition for `BASH_FUNC_x'
test

部分(早期版本)修補輸出

bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
bash: error importing function definition for `BASH_FUNC_x()'
test

修補輸出直至並包括 CVE-2014-7169:

bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `BASH_FUNC_x'
test

編輯3:故事繼續:

bash 將導出的函式定義儲存為環境變數。導出的函式如下所示:

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

也就是說,環境變數foo具有文字內容:

() {  bar
}

當一個新的 bash 實例啟動時,它會查找這些特製的環境變數,並將它們解釋為函式定義。你甚至可以自己寫一個,看看它仍然有效:

$ export foo='() { echo "Inside function"; }'
$ bash -c 'foo'
Inside function

不幸的是,從字元串(環境變數)解析函式定義可能會產生比預期更廣泛的影響。在未打更新檔的版本中,它還解釋函式定義終止後出現的任意命令。這是由於在確定環境中可接受的類似函式的字元串時約束不足。例如:

$ export foo='() { echo "Inside function" ; }; echo "Executed echo"'
$ bash -c 'foo'
Executed echo
Inside function

請注意,在 bash 啟動期間,函式定義之外的 echo 已意外執行。函式定義只是進行評估和利用的一個步驟,函式定義本身和使用的環境變數是任意的。shell 查看環境變數 sees foo,它看起來符合它知道的關於函式定義的約束,它評估該行,無意中也執行了 echo(可能是任何命令,無論是否惡意)。

這被認為是不安全的,因為通常不允許或期望變數本身直接導致呼叫其中包含的任意程式碼。也許您的程序從不受信任的使用者輸入設置環境變數。非常出乎意料的是,這些環境變數可以以這樣一種方式進行操作,即使用者可以執行任意命令而您沒有明確的意圖使用該環境變數來執行程式碼中聲明的這種原因。

這是一個可行的攻擊範例。您在某處執行一個執行易受攻擊的 shell 的 Web 伺服器,作為其生命週期的一部分。此 Web 伺服器將環境變數傳遞給 bash 腳本,例如,如果您使用 CGI,則有關 HTTP 請求的資訊通常作為來自 Web 伺服器的環境變數包含在內。例如,HTTP_USER_AGENT可能設置為您的使用者代理的內容。這意味著,如果您將使用者代理欺騙為類似 ‘() { :; }; echo foo’,當該 shell 腳本執行時,echo foo將被執行。同樣,echo foo可能是任何東西,無論是否惡意。

引用自:https://unix.stackexchange.com/questions/157329