The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何重新編譯 GNU Bash 解決 CVE-2014-7169 安全漏洞

就在幾天前 National Vulnerability Database (NVD) (美國國家弱點資料庫) 發佈編號 CVE-2014-6271 的弱點通報,該弱點指出在 Linux / Unix / MAC OS X 等作業系統中內建的 GNU Bash 在 4.3 版以前(含4.3版),皆存在一個能夠遠端執行任意程式碼的漏洞。雖然 GNU Bash 緊急在一天內提供了修補程式 (安全性更新),版本號為 4.3 bash43-025,但是問題並沒有解決,所以 NVD 又再緊急發布了一份 CVE-2014-7169 弱點,目前最新版 Bash 的修補更新已經推出,本篇文章教大家如何重新編譯 GNU Bash 套件!

基本上,這個弱點已經證實存在,資安人員透過 OpenSSH sshd 的 ForceCommand 功能、Apache 的 mod_cgi 與 mod_cgid 模組、透過 DHCP client 發動執行的指令檔,以及任何其他��以透過 Bash 跳過權限檢查執行的方法進行驗證,都可以攻破此弱點,而且攻擊的手法十分簡單,本文稍後也會提及驗證的方法,因此 NVD 將此弱點標示為最高權重的資安弱點 ( 10 分 ),各位必須立刻更新主機的 Bash 套件至最新版!

你可能會想說,沒事幹嘛重新編譯 GNU Bash 套件?直接安裝新版套件不就好了嗎?這想法當然沒錯,但有不少很舊很舊的 Linux 版本,也許還在線上運行中,這些 Linux 版本早就不受官方支援,相當然爾也下載不到更新過的 bash 套件,所以你勢必要學會如何重新編譯 GNU Bash 套件!

檢測系統是否有安全弱點的方法

直接在 Bash shell 底下輸入這串命令:

env x='() { :;}; echo XD' bash -c "echo This is a test code"

你原本只是在執行 bash 腳本前,設定一個 x 環境變數而已,這個環境變數的值,原本應該只是個字串,但卻意外的被執行 echo XD 這段,所以當你執行後,只要你看到這行命令輸出的第一行為 XD 的話 (如下),就代表你的 Bash 還存有該弱點!

XD
This is a test code
如果你的 bash 已經緊急更新過(注意: 你可能不是更新到最新版!),則會看見以下輸出:
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
This is a test code
如果你的 bash 已經到最新版,則會看見以下輸出:
This is a test code
 

修補這個弱點的方法 1 ( 將 bash 套件更新至最新版 )

  • Ubuntu
apt-get update
apt-get upgrade
  • RedHat / CentOS / Fedora
yum update

修補這個弱點的方法 2 (重新編譯 GNU Bash 套件)

重新編譯可參考以下步驟進行:
  1. 先安裝必要的建置套件 ( build tools ),我以 Ubuntu 安裝為例:
    apt-get install build-essential wget curl patch byacc
  2. 先檢查你的 Bash 版本
    root@server:~# bash --version
    GNU bash, version 4.0.33(1)-release (i486-pc-linux-gnu)
    Copyright (C) 2009 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

    This is free software; you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
  3. 假設 bash 版本為 4.0.33,你就可以去 GNU Bash 下載 4.0 版的原始碼回來,也就是 bash-4.0.tar.gz 這個檔案
    wget http://ftp.gnu.org/gnu/bash/bash-4.0.tar.gz
  4. 然後解壓縮 bash 原始碼,並進入原始碼目錄
    tar zxf bash-4.0.tar.gz
    cd bash-4.0
  5. 接著進入 bash 4.0 版本的 patch 目錄,這裡包含 bash 該版本原始碼每次的異動紀錄 (包含這次更新)
  6. 這時你會看到這裡有幾十個檔案,每個 bash 版本的更新次數不一,所以請看一下個別版本中有多少檔案,每個檔案都要套用才行。我以 bash 4.0 為例,目前共有 41 個檔案要更新,所以你必須執行 patch 命令 41 次。
  7. 我為此寫了一支簡單的 shell 腳本,你只要直接剪下貼上就可以一次 patch 完所有的原始碼,不過前提是你必須先要有 curl 與 patch 工具程式才行。
    for i in $(seq -f "%03g" 1 41); do echo "Getting ... http://ftp.gnu.org/gnu/bash/bash-4.0-patches/bash40-$i"; curl "http://ftp.gnu.org/gnu/bash/bash-4.0-patches/bash40-$i" | patch -p0 ; done
    ※ 上述指令請注意 141 是變數,要看你想 patch 的版本範圍而定,當然下載的網址也會因為不同的 bash 版而有所不同。
    如下是更新 bash 3.2 版的範例,因為 bash 3.2 版有 54 個 patch 要上:
    for i in $(seq -f "%03g" 1 54); do echo "Getting ... http://ftp.gnu.org/gnu/bash/bash-3.2-patches/bash32-$i"; curl "http://ftp.gnu.org/gnu/bash/bash-3.2-patches/bash32-$i" | patch -p0 ; done
    如下是更新 bash 4.2 版的範例,因為 bash 4.2 版有 52 個 patch 要上:
    for i in $(seq -f "%03g" 1 52); do echo; echo "Getting ... http://ftp.gnu.org/gnu/bash/bash-4.2-patches/bash42-$i"; curl "http://ftp.gnu.org/gnu/bash/bash-4.2-patches/bash42-$i" | patch -p0 ; done
    執行完畢大致畫面如下:

    ※ 請注意:你必須確保每次 patch 都是成功的。
  8. 最後就可以進行編譯了,請一步一步執行,確保每個命令執行都是正確無誤的,如下:
    ./configure
    make
    make install
  9. 最後請再驗證一次是否成功更新 bash 套件

    env x='() { :;}; echo XD' bash -c "echo This is a test code"
    如果只看到以下一行輸出,那就代表你成功更新了 bash 套件:
    This is a test code
    如下圖示:

 

相關連結