Dependency Confusion
Reading time: 8 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Temel Bilgiler
Dependency Confusion (diğer adıyla substitution attacks), bir paket yöneticisinin, istenen özel/iç kaynak yerine, istenmeyen, daha az güvenilir bir kayıt/ kaynak (genellikle bir kamu kaynağı) üzerinden bir bağımlılık adını çözümlemesi durumunda meydana gelir. Bu genellikle, bir saldırganın kontrolündeki bir paketin yüklenmesine yol açar.
Yaygın kök nedenler:
- Typosquatting/yazım hatası:
reqests
yerinerequests
yüklemek (kamu kaynağından çözümleme). - Mevcut olmayan/terk edilmiş iç paket: Artık içerde mevcut olmayan
company-logging
yüklemek, bu nedenle çözümleyici kamu kayıtlarında arama yapar ve bir saldırganın paketini bulur. - Birden fazla kayıt arasında sürüm tercihi: İç
company-requests
yüklemek, ancak çözümleyicinin kamu kayıtlarını da sorgulamasına izin verilmesi ve saldırgan tarafından kamuya açık olarak yayınlanan “en iyi”/daha yeni sürümü tercih etmesi.
Ana fikir: Eğer çözümleyici aynı paket adı için birden fazla kaydı görebiliyorsa ve “en iyi” adayı küresel olarak seçmesine izin veriliyorsa, çözümlemeyi kısıtlamadığınız sürece savunmasızsınız.
Sömürü
warning
Tüm durumlarda, saldırganın yalnızca kamu kaynağından bağımlılığınızın adıyla aynı adı taşıyan kötü niyetli bir paket yayınlaması gerekir. Kurulum zamanı kancaları (örneğin, npm betikleri) veya içe aktarma zamanı kod yolları genellikle kod yürütme sağlar.
Yanlış Yazılmış & Mevcut Olmayan
Projeniz, özel kayıtta mevcut olmayan bir kütüphaneye atıfta bulunuyorsa ve araçlarınız kamu kaynağına geri dönüyorsa, bir saldırgan bu isimle kamu kaynağında kötü niyetli bir paket oluşturabilir. Çalıştırıcılarınız/CI/geliştirici makineleriniz bunu alıp çalıştıracaktır.
Belirtilmemiş Sürüm / İndeksler Arasında “En iyi sürüm” seçimi
Geliştiriciler genellikle sürümleri sabitlemez veya geniş aralıklara izin verir. Bir çözümleyici hem iç hem de kamu indeksleri ile yapılandırıldığında, kaynağa bakılmaksızın en yeni sürümü seçebilir. requests-company
gibi iç adlar için, eğer iç indeks 1.0.1
içeriyorsa ancak bir saldırgan 1.0.2
'yi kamu kaynağına yayınlarsa ve çözümleyiciniz her ikisini de dikkate alıyorsa, kamu paketi kazanabilir.
AWS Düzeltmesi
Bu zafiyet AWS CodeArtifact'ta bulundu (detayları bu blog yazısında okuyun). AWS, istemcinin yukarıdan gelen kamu kayıtlarından “iç” adları almayacağı şekilde bağımlılıkları/akışları iç veya dış olarak işaretlemek için kontroller ekledi.
Zayıf Kütüphaneleri Bulma
Bağımlılık karışıklığı hakkında orijinal yazıda yazar, iç paket adlarını çıkarmak için binlerce ifşa edilmiş manifestoyu (örneğin, package.json
, requirements.txt
, kilit dosyaları) aradı ve ardından daha yüksek sürümlü paketleri kamu kayıtlarına yayınladı.
Pratik Saldırgan Oyun Kitabı (yetkili testlerde kırmızı takımlar için)
- İsimleri listele:
- Manifesto/kilit dosyaları ve iç ad alanları için reposları ve CI yapılandırmalarını Grep ile tarayın.
- Organizasyona özgü önekler arayın (örneğin,
@company/*
,company-*
, iç groupId'ler, NuGet ID desenleri, Go için özel modül yolları vb.). - Kamu kayıtlarında kullanılabilirliği kontrol edin:
- Eğer isim kamuya açık olarak kaydedilmemişse, kaydedin; eğer mevcutsa, iç geçişli adları hedef alarak alt bağımlılık kaçırma girişiminde bulunun.
- Öncelik ile yayınlayın:
- “Kazanan” bir semver seçin (örneğin, çok yüksek bir sürüm) veya çözümleyici kurallarına uyan bir sürüm seçin.
- Uygun olduğunda, minimum kurulum zamanı yürütmesini dahil edin (örneğin, npm
preinstall
/install
/postinstall
betikleri). Python için, genellikle yükleme sırasında rastgele kod yürütmeyen tekerlekler olduğundan, içe aktarma zamanı yürütme yollarını tercih edin. - Kontrolü dışarıya sızdırın:
- CI'den kontrol ettiğiniz uç noktaya çıkışın izinli olduğundan emin olun; aksi takdirde, kod yürütmesini kanıtlamak için DNS sorguları veya hata mesajlarını yan kanal olarak kullanın.
caution
Her zaman yazılı yetki alın, angajman için benzersiz paket adları/sürümleri kullanın ve test sona erdiğinde hemen yayından kaldırın veya temizlik koordinasyonu yapın.
Savunucu Oyun Kitabı (karışıklığı gerçekten önleyen)
Eko sistemler arasında çalışan yüksek düzeyde stratejiler:
- Benzersiz iç ad alanları kullanın ve bunları tek bir kayıt ile bağlayın.
- Çözümleme zamanı güven düzeylerini karıştırmaktan kaçının. Onaylı kamu paketlerini proxyleyen tek bir iç kaydı tercih edin, paket yöneticilerine hem iç hem de kamu uç noktaları vermek yerine.
- Destekleyen yöneticiler için, paketleri belirli kaynaklara eşleyin (kayıtlar arasında küresel “en iyi sürüm” yok).
- Sabitleyin ve kilitleyin:
- Çözümleme kayıt URL'lerini (npm/yarn/pnpm) kaydeden kilit dosyaları kullanın veya hash/tasdik sabitleme (pip
--require-hashes
, Gradle bağımlılık doğrulaması) kullanın. - İç adlar için kamuya açık geri dönüşü kayıt/ağ katmanında engelleyin.
- Gelecekteki squatları önlemek için mümkünse kamu kayıtlarında iç adlarınızı rezerve edin.
Eko Sistem Notları ve Güvenli Konfigürasyon Parçaları
Aşağıda bağımlılık karışıklığını azaltmak veya ortadan kaldırmak için pragmatik, minimal konfigürasyonlar bulunmaktadır. Bunları CI ve geliştirici ortamlarında uygulamayı tercih edin.
JavaScript/TypeScript (npm, Yarn, pnpm)
- Tüm iç kod için kapsamlı paketler kullanın ve kapsamı özel kaydınıza sabitleyin.
- CI'de yüklemeleri değişmez tutun (npm kilit dosyası,
yarn install --immutable
).
.npmrc (proje düzeyi)
# Bind internal scope to private registry; do not allow public fallback for @company/*
@company:registry=https://registry.corp.example/npm/
# Always authenticate to the private registry
//registry.corp.example/npm/:_authToken=${NPM_TOKEN}
strict-ssl=true
package.json (iç paket için)
{
"name": "@company/api-client",
"version": "1.2.3",
"private": false,
"publishConfig": {
"registry": "https://registry.corp.example/npm/",
"access": "restricted"
}
}
Yarn Berry (.yarnrc.yml)
npmScopes:
company:
npmRegistryServer: "https://registry.corp.example/npm/"
npmAlwaysAuth: true
# CI should fail if lockfile would change
enableImmutableInstalls: true
Operasyonel ipuçları:
- Sadece
@company
kapsamındaki dahili paketleri yayınlayın. - Üçüncü taraf paketler için, doğrudan istemcilerden değil, özel proxy/mirror aracılığıyla genel kayıt defterine izin verin.
- Yayınladığınız genel paketler için izlenebilirliği artırmak amacıyla npm paket kökenini etkinleştirmeyi düşünün (bu, karışıklığı önlemez).
Python (pip / Poetry)
Temel kural: Güven düzeylerini karıştırmak için --extra-index-url
kullanmayın. Ya:
- Onaylı PyPI paketlerini proxy ve önbellekleyen tek bir dahili indeks açığa çıkarın, ya da
- Açık indeks seçimi ve hash sabitleme kullanın.
pip.conf
[global]
index-url = https://pypi.corp.example/simple
# Disallow source distributions when possible
only-binary = :all:
# Lock with hashes generated via pip-tools
require-hashes = true
pip-tools ile hashlenmiş gereksinimler oluşturun:
# From pyproject.toml or requirements.in
pip-compile --generate-hashes -o requirements.txt
pip install --require-hashes -r requirements.txt
Eğer kamu PyPI'ye ulaşmanız gerekiyorsa, bunu iç proxy'niz aracılığıyla yapın ve orada açık bir izin listesi tutun. CI'de --extra-index-url
kullanmaktan kaçının.
.NET (NuGet)
Paket ID desenlerini açık kaynaklara bağlamak ve beklenmeyen kaynaklardan çözümlemeyi önlemek için Paket Kaynağı Haritalama kullanın.
nuget.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="corp" value="https://nuget.corp.example/v3/index.json" />
</packageSources>
<packageSourceMapping>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="corp">
<package pattern="Company.*" />
<package pattern="Internal.Utilities" />
</packageSource>
</packageSourceMapping>
</configuration>
Java (Maven/Gradle)
Maven settings.xml (tümünü dahiliye yansıt; POM'larda ad-hoc reposuna Enforcer ile izin verme):
<settings>
<mirrors>
<mirror>
<id>internal-mirror</id>
<mirrorOf>*</mirrorOf>
<url>https://maven.corp.example/repository/group</url>
</mirror>
</mirrors>
</settings>
Enforcer'ı POM'larda belirtilen depoları yasaklamak ve kendi ayna kullanımını zorlamak için ekleyin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<id>enforce-no-repositories</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules>
<requireNoRepositories />
</rules>
</configuration>
</execution>
</executions>
</plugin>
Gradle: Bağımlılıkları merkezileştir ve kilitle.
- Sadece
settings.gradle(.kts)
dosyasında depoları zorunlu kıl:
dependencyResolutionManagement {
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
repositories {
maven { url = uri("https://maven.corp.example/repository/group") }
}
}
- Bağımlılık doğrulamasını (kontrol toplamları/imzalar) etkinleştir ve
gradle/verification-metadata.xml
dosyasını taahhüt et.
Go Modülleri
Özel modülleri, kamu proxy'si ve kontrol toplamı veritabanının kullanılmadığı şekilde yapılandır.
# Use corporate proxy first, then public proxy as fallback
export GOPROXY=https://goproxy.corp.example,https://proxy.golang.org
# Mark private paths to skip proxy and checksum db
export GOPRIVATE=*.corp.example.com,github.com/your-org/*
export GONOSUMDB=*.corp.example.com,github.com/your-org/*
Rust (Cargo)
crates.io'yu onaylı bir iç ayna veya satıcı dizini ile değiştirin; rastgele kamu geri dönüşüne izin vermeyin.
.cargo/config.toml
[source.crates-io]
replace-with = "corp-mirror"
[source.corp-mirror]
registry = "https://crates-mirror.corp.example/index"
Yayınlama için --registry
ile açık olun ve kimlik bilgilerini hedef kayıt defteri ile sınırlı tutun.
Ruby (Bundler)
Kaynak blokları kullanın ve çoklu kaynak Gemfile'ları devre dışı bırakın, böylece gem'ler yalnızca hedeflenen depodan gelir.
Gemfile
source "https://gems.corp.example"
source "https://rubygems.org" do
gem "rails"
gem "pg"
end
source "https://gems.corp.example" do
gem "company-logging"
end
Yapılandırma seviyesinde zorla:
bundle config set disable_multisource true
CI/CD ve Kayıt Kontrolleri
- Özel kayıt tek bir giriş noktası olarak:
- Geliştiricilerin/CI'nın erişebileceği tek uç nokta olarak Artifactory/Nexus/CodeArtifact/GitHub Packages/Azure Artifacts kullanın.
- Dahili ad alanlarının asla yukarıdan gelen kamu kaynaklarından çözülmemesi için engelleme/izin verme kuralları uygulayın.
- Lockfile'lar CI'de değiştirilemez:
- npm:
package-lock.json
dosyasını taahhüt edin,npm ci
kullanın. - Yarn:
yarn.lock
dosyasını taahhüt edin,yarn install --immutable
kullanın. - Python: hashlenmiş
requirements.txt
dosyasını taahhüt edin,--require-hashes
zorlayın. - Gradle:
verification-metadata.xml
dosyasını taahhüt edin ve bilinmeyen nesnelerde başarısız olun. - Dışa çıkış kontrolü: onaylı proxy dışında CI'den kamu kayıtlarına doğrudan erişimi engelleyin.
- İsim rezervasyonu: desteklenen kamu kayıtlarında dahili isimlerinizi/ad alanlarınızı önceden kaydedin.
- Paket kökeni / onaylar: kamu paketleri yayınlarken, aşağı akışta müdahaleyi daha belirgin hale getirmek için köken/onayları etkinleştirin.
Referanslar
- https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610
- https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d
- https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping
- https://yarnpkg.com/configuration/yarnrc/
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.