Bash

shellshock (CVE-2014-6271/7169) 錯誤是何時引入的,完全修復它的更新檔是什麼?

  • January 15, 2019

有關該錯誤的一些上下文:CVE-2014-6271

Bash 不僅支持將 shell 變數導出,還支持將 shell 函式導出到其他 bash 實例,通過程序環境到(間接)子程序。目前的 bash 版本使用以函式名稱命名的環境變數,以及變數值中以“() {”開頭的函式定義,以在環境中傳播函式定義。漏洞發生是因為bash在處理完函式定義後沒有停止;它繼續在函式定義之後解析和執行 shell 命令。例如,環境變數設置

  VAR=() { ignored; }; /bin/id

將環境導入 bash 程序時將執行 /bin/id。

資料來源:http ://seclists.org/oss-sec/2014/q3/650

該錯誤是何時引入的,完全修復它的更新檔是什麼?(參見CVE-2014-7169

除了 CVE(最初)(3.{0..2} 和 4.{0..3})中提到的易受攻擊的版本之外,還有哪些易受攻擊的版本?

錯誤的原始碼是否已在其他項目中重複使用?

需要額外的資訊。


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

TL; 博士

shellshock漏洞已完全修復

  • 在 bash-2.05b 分支上:2.05b.10 及更高版本(包括更新檔 10)
  • 在 bash-3.0 分支上:3.0.19 及更高版本(包括更新檔 19)
  • 在 bash-3.1 分支上:3.1.20 及更高版本(包括更新檔 20)
  • 在 bash-3.2 分支上:3.2.54 及更高版本(包括更新檔 54)
  • 在 bash-4.0 分支上:4.0.41 及更高版本(包括更新檔 41)
  • 在 bash-4.1 分支上:4.1.14 及更高版本(包括更新檔 14)
  • 在 bash-4.2 分支上:4.2.50 及更高版本(包括更新檔 50)
  • 在 bash-4.3 分支上:4.3.27 及更高版本(包括更新檔 27)

如果您的 bash 顯示舊版本,您的作業系統供應商可能仍然自己修補它,所以最好檢查一下。

如果:

env xx='() { echo vulnerable; }' bash -c xx

顯示“脆弱”,你仍然脆弱。這是唯一相關的測試(bash 解析器是否仍然暴露於任何環境變數中的程式碼)。

細節。

該錯誤出現在 Brian Fox 於 1989 年 8 月 5日引入的函式導出/導入的初始實現中,大約一個月後在 bash-1.03 中首次發布,當時 bash 在安全之前沒有得到如此廣泛的使用有那麼大的問題,甚至 HTTP 和 Web 或 Linux 都存在。

1.05中的變更日誌:

Fri Sep  1 18:52:08 1989  Brian Fox  (bfox at aurel)

       * readline.c: rl_insert ().  Optimized for large amounts
         of typeahead.  Insert all insertable characters at once.

       * I update this too irregularly.
         Released 1.03.
[...]
Sat Aug  5 08:32:05 1989  Brian Fox  (bfox at aurel)

       * variables.c: make_var_array (), initialize_shell_variables ()
         Added exporting of functions.

當時在gnu.bash.bugcomp.unix.questions中的一些討論也提到了這個特性。

很容易理解它是如何到達那裡的。

bash 導出環境變數中的函式,例如

foo=() {
 code
}

在導入時,它所要做的就是=用空格替換它來解釋它……除了它不應該盲目地解釋它。

它也被打破了bash(與 Bourne shell 相反),標量變數和函式具有不同的名稱空間。其實如果你有

foo() { echo bar; }; export -f foo
export foo=bar

bash很樂意將兩者都放在環境中(是的具有相同變數名的條目),但許多工具(包括許多 shell)不會傳播它們。

有人還會爭辯說 bash 應該為此使用BASH_命名空間前綴,因為 env vars 僅與 bash 到 bash 相關。對類似功能rc使用前綴。fn_

實現它的更好方法是將所有導出變數的定義放在一個變數中,例如:

BASH_FUNCDEFS='f1() { echo foo;}
 f2() { echo bar;}...'

這仍然需要清理,但至少不能比$BASH_ENV$SHELLOPTS……

有一個更新檔可以防止bash解釋除函式定義之外的任何其他內容(https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html),這就是已應用於各種 Linux 發行版的所有安全更新。

然而,bash 仍然解釋那裡的程式碼,並且解釋器中的任何錯誤都可能被利用。已經發現了一個這樣的錯誤(CVE-2014-7169),儘管它的影響要小得多。所以很快就會有另一個更新檔。

在阻止 bash 解釋任何變數中的程式碼(如使用上述BASH_FUNCDEFS方法)的強化修復之前,我們無法確定我們是否不會受到 bash 解析器中的錯誤的影響。而且我相信遲早會發布這樣的強化修復程序。

編輯 2014-09-28

已發現解析器中的兩個額外錯誤 (CVE-2014-718{6,7}) ‘沒有暴露於不受信任的數據)。

雖然所有 3 個錯誤 7169、7186 和 7187 已在後續更新檔中得到修復,但 Red Hat 推動了強化修復。在他們的更新檔中,他們改變了行為,以便在變數中導出函式,這些變數BASH_FUNC_myfunc()或多或少地搶占了 Chet 的設計決策。

Chet 後來將該修復程序發佈為官方上游 bash 更新檔

該加固更新檔或其變體現在可用於大多數主要的 Linux 發行版,並最終應用於 Apple OS/X。

現在,這消除了對任何通過該向量利用解析器的任意 env var 的擔憂,包括解析器中的其他兩個漏洞 (CVE-2014-627{7,8}),這些漏洞後來由 Michał Zalewski 披露(CVE-2014-6278 幾乎和 CVE-2014-6271 一樣糟糕),謝天謝地,在大多數人有時間安裝加固更新檔之後

解析器中的錯誤也將得到修復,但由於解析器不再那麼容易暴露於不受信任的輸入,因此它們不再是一個大問題。

請注意,雖然安全漏洞已得到修復,但我們可能會在該領域看到一些變化。CVE-2014-6271 的初始修復破壞了向後兼容性,因為它停止導入帶有.:/名稱的函式。這些仍然可以由 bash 聲明,但這會導致不一致的行為。因為通常使用帶有.:名稱的函式,所以更新檔很可能會恢復至少接受來自環境的函式。

為什麼沒有早點發現?

這也是我想知道的。我可以提供一些解釋。

首先,我認為如果安全研究人員(而且我不是專業的安全研究人員)專門尋找 bash 中的漏洞,他們很可能會找到它。

例如,如果我是一名安全研究員,我的方法可能是:

  1. 看看從哪裡bash獲得輸入以及它如何處理它。環境是顯而易見的。
  2. 查看bash呼叫解釋器的位置和數據。再次,它會脫穎而出。
  3. 導出函式的導入是 setuid/setgid時禁用的功能之一bash,這使得它看起來更加明顯。

現在,我懷疑沒有人認為bash(口譯員)是一種威脅,或者威脅可能是這樣來的。

解釋器bash並不意味著處理不受信任的輸入。

Shell腳本(而不是解釋器)通常從安全的角度仔細觀察。shell 語法太笨拙了,編寫可靠的腳本有很多警告(我或其他人提到過 split+glob 運算符,或者為什麼你應該引用變數?),在處理腳本中發現安全漏洞是很常見的不受信任的數據。

這就是為什麼您經常聽到您不應該編寫 CGI shell 腳本,或者在大多數 Unices 上禁用 setuid 腳本的原因。或者在處理全域可寫目錄中的文件時應該格外小心(例如,參見CVE-2011-0441)。

重點在於 shell 腳本,而不是解釋器。

eval您可以通過或在使用者提供的文件上呼叫它來將 shell 解釋器暴露給不受信任的數據(將外部數據作為 shell 程式碼提供來解釋).,但是您不需要漏洞bash來利用它。很明顯,如果您將未經處理的數據傳遞給 shell 來解釋,它會解釋它。

因此,shell 在受信任的上下文中被呼叫。它有固定的腳本來解釋,而且通常(因為很難編寫可靠的腳本)固定的數據來處理。

例如,在 Web 上下文中,shell 可能會以如下方式呼叫:

popen("sendmail -oi -t", "w");

那有什麼問題呢?如果設想出了問題,那是關於饋送到該 sendmail 的數據,而不是如何解析該 shell 命令行本身或向該 shell 饋送哪些額外數據。您沒有理由要考慮傳遞給該 shell 的環境變數。如果你這樣做了,你就會意識到所有的環境變數都是以“HTTP_”開頭的,或者是眾所周知的 CGI 環境變數,SERVER_PROTOCOL或者QUERYSTRING與 shell 或 sendmail 沒有任何關係。

在特權提升上下文中,例如執行 setuid/setgid 或通過 sudo 時,通常會考慮環境並且過去存在大量漏洞,同樣不是針對 shell 本身,而是針對提升特權的事物sudo(例如,參見CVE -2011-3628)。

例如,bash當 setuid 或由 setuid 命令呼叫時不信任環境(mount例如呼叫助手)。特別是,它忽略了導出的函式。

sudo確實清理了環境:預設情況下除了白名單之外的所有內容,如果配置不這樣做,至少將一些已知會影響 shell 或其他的(如PS4, BASH_ENV, SHELLOPTS…)列入黑名單。它還將內容以開頭的環境變數列入黑名單()(這就是 CVE-2014-6271 不允許通過 提權的原因sudo)。

但同樣,這是針對環境不可信的情況:惡意使用者可以在該上下文中設置具有任何名稱和值的任何變數。這不適用於 Web 伺服器/ssh 或所有利用 CVE-2014-6271 控制環境的向量(至少控制環境變數的名稱……)

阻止像echo="() { evil; }", 但不是的變數很重要HTTP_FOO="() { evil; }",因為HTTP_FOO它不會被任何 shell 腳本或命令行作為命令呼叫。並且 apache2 永遠不會設置echoorBASH_ENV變數。

很明顯,一些環境變數應該在某些上下文中根據它們的名稱被列入黑名單,但是沒有人認為它們應該根據它們的內容被列入黑名單(除了sudo)。或者換句話說,沒有人認為任意環境變數可能是程式碼注入的載體。

至於添加該功能時的廣泛測試是否可以捕捉到它,我認為這不太可能。

當您測試功能時,您測試功能。該功能工作正常。如果您在一次呼叫中導出該函式bash,那麼它在另一次呼叫中也可以正常導入。當導出具有相同名稱的變數和函式時,或者當函式在與其導出所在的語言環境不同的語言環境中導入時,一個非常徹底的測試可能會發現問題。

但是為了能夠發現漏洞,這不是您必須進行的功能測試。安全方面必須是主要關注點,您不會測試功能,而是測試機制以及如何濫用它。

這不是開發人員(尤其是在 1989 年)經常想到的事情,並且 shell 開發人員可以原諒認為他的軟體不太可能是網路可利用的。

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