Translated ['src/macos-hardening/macos-red-teaming/macos-mdm/README.md',

This commit is contained in:
Translator 2025-08-21 02:48:02 +00:00
parent 79095baba4
commit d1f2a73cb7
2 changed files with 315 additions and 37 deletions

File diff suppressed because one or more lines are too long

View File

@ -4,40 +4,262 @@
## Basic Information
संक्षेप में, एक dependency confusion vulnerability तब होती है जब एक प्रोजेक्ट एक लाइब्रेरी का उपयोग कर रहा होता है जिसका **गलत स्पेलिंग** है, **अस्तित्वहीन** है या जिसका **निर्धारित संस्करण** नहीं है और उपयोग की गई dependency repository **सार्वजनिक** repositories से **अपडेटेड संस्करणों को इकट्ठा करने** की अनुमति देती है।
Dependency Confusion (जिसे प्रतिस्थापन हमले भी कहा जाता है) तब होता है जब एक पैकेज प्रबंधक एक निर्भरता नाम को एक अनपेक्षित, कम-विश्वसनीय रजिस्ट्रि/स्रोत (आमतौर पर एक सार्वजनिक रजिस्ट्रि) से हल करता है, बजाय इसके कि इसे इच्छित निजी/आंतरिक रजिस्ट्रि से हल किया जाए। इससे आमतौर पर एक हमलावर-नियंत्रित पैकेज की स्थापना होती है।
- **गलत स्पेलिंग**: **`reqests`** को आयात करें बजाय `requests`
- **अस्तित्वहीन**: `company-logging` को आयात करें, एक आंतरिक लाइब्रेरी जो **अब अस्तित्व में नहीं है**
- **निर्धारित संस्करण नहीं**: एक **आंतरिक** **अस्तित्व में** `company-requests` लाइब्रेरी को आयात करें, लेकिन repo **सार्वजनिक repos** की जांच करता है यह देखने के लिए कि क्या **बड़े संस्करण** हैं।
सामान्य मूल कारण:
- टाइपोसक्वाटिंग/गलत स्पेलिंग: `reqests` को `requests` के बजाय आयात करना (सार्वजनिक रजिस्ट्रि से हल होता है)।
- गैर-मौजूद/परित्यक्त आंतरिक पैकेज: `company-logging` को आयात करना जो अब आंतरिक रूप से मौजूद नहीं है, इसलिए हल करने वाला सार्वजनिक रजिस्ट्रियों में देखता है और एक हमलावर का पैकेज पाता है।
- कई रजिस्ट्रियों में संस्करण प्राथमिकता: एक आंतरिक `company-requests` को आयात करना जबकि हल करने वाले को सार्वजनिक रजिस्ट्रियों को भी क्वेरी करने की अनुमति है और एक हमलावर द्वारा सार्वजनिक रूप से प्रकाशित "सर्वश्रेष्ठ"/नया संस्करण पसंद करता है।
मुख्य विचार: यदि हल करने वाला एक ही पैकेज नाम के लिए कई रजिस्ट्रियों को देख सकता है और "सर्वश्रेष्ठ" उम्मीदवार को वैश्विक रूप से चुनने की अनुमति है, तो आप कमजोर हैं जब तक कि आप समाधान को सीमित नहीं करते।
## Exploitation
> [!WARNING]
> सभी मामलों में हमलावर को केवल एक **दुष्ट पैकेज का नाम** प्रकाशित करने की आवश्यकता है जो पीड़ित कंपनी द्वारा उपयोग की जाने वाली लाइब्रेरी का नाम है
> सभी मामलों में, हमलावर को केवल एक दुर्भावनापूर्ण पैकेज प्रकाशित करने की आवश्यकता होती है जिसका नाम उस निर्भरता के समान है जिसे आपका निर्माण सार्वजनिक रजिस्ट्रि से हल करता है। स्थापना-समय हुक (जैसे, npm स्क्रिप्ट) या आयात-समय कोड पथ अक्सर कोड निष्पादन देते हैं
### गलत स्पेलिंग और अस्तित्वहीन
### Misspelled & Inexistent
यदि आपकी कंपनी एक **लाइब्रेरी आयात करने की कोशिश कर रही है जो आंतरिक नहीं है**, तो बहुत संभावना है कि लाइब्रेरी का repo इसे **सार्वजनिक repositories** में खोजने जा रहा है। यदि एक हमलावर ने इसे बनाया है, तो आपका कोड और चलने वाली मशीनें बहुत संभावना है कि समझौता की जाएंगी।
यदि आपका प्रोजेक्ट एक लाइब्रेरी का संदर्भ देता है जो निजी रजिस्ट्रि में उपलब्ध नहीं है, और आपका उपकरण सार्वजनिक रजिस्ट्रि पर वापस जाता है, तो एक हमलावर उस नाम के साथ एक दुर्भावनापूर्ण पैकेज सार्वजनिक रजिस्ट्रि में डाल सकता है। आपके रनर/CI/dev मशीनें इसे लाएंगी और निष्पादित करेंगी।
### निर्दिष्ट संस्करण नहीं
### Unspecified Version / “Best-version” selection across indexes
डेवलपर्स के लिए यह बहुत सामान्य है कि वे उपयोग की जाने वाली लाइब्रेरी का **कोई संस्करण निर्दिष्ट नहीं करते** हैं, या केवल एक **मुख्य संस्करण** निर्दिष्ट करते हैं। फिर, इंटरप्रेटर उन आवश्यकताओं के अनुसार **नवीनतम संस्करण** डाउनलोड करने की कोशिश करेगा।\
यदि लाइब्रेरी एक **ज्ञात बाहरी लाइब्रेरी** है (जैसे python `requests`), तो एक **हमलावर ज्यादा कुछ नहीं कर सकता**, क्योंकि वह `requests` नाम की लाइब्रेरी नहीं बना सकेगा (जब तक कि वह मूल लेखक न हो)।\
हालांकि, यदि लाइब्रेरी **आंतरिक** है, जैसे इस उदाहरण में `requests-company`, यदि **लाइब्रेरी repo** बाहरी रूप से **नए संस्करणों की जांच करने** की अनुमति देता है, तो यह सार्वजनिक रूप से उपलब्ध एक नए संस्करण की खोज करेगा।\
तो यदि एक **हमलावर जानता है** कि कंपनी `requests-company` लाइब्रेरी **संस्करण 1.0.1** का उपयोग कर रही है (छोटे अपडेट की अनुमति देता है)। वह लाइब्रेरी `requests-company` **संस्करण 1.0.2** को **प्रकाशित** कर सकता है और कंपनी उस लाइब्रेरी का **उपयोग करेगी** बजाय आंतरिक वाले के।
डेवलपर्स अक्सर संस्करणों को अनपिन करते हैं या व्यापक रेंज की अनुमति देते हैं। जब एक हल करने वाला आंतरिक और सार्वजनिक सूचियों के साथ कॉन्फ़िगर किया जाता है, तो यह स्रोत की परवाह किए बिना नवीनतम संस्करण का चयन कर सकता है। आंतरिक नामों जैसे `requests-company` के लिए, यदि आंतरिक सूची में `1.0.1` है लेकिन एक हमलावर सार्वजनिक रजिस्ट्रि में `1.0.2` प्रकाशित करता है और आपका हल करने वाला दोनों पर विचार करता है, तो सार्वजनिक पैकेज जीत सकता है।
## AWS Fix
यह सुरक्षा कमी AWS **CodeArtifact** में पाई गई (पढ़ें [**इस ब्लॉग पोस्ट में विवरण**](https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d)).\
AWS ने इसे इस तरह से ठीक किया कि यह निर्दिष्ट करने की अनुमति देता है कि एक लाइब्रेरी आंतरिक है या बाहरी, ताकि बाहरी repositories से आंतरिक निर्भरताओं को डाउनलोड करने से बचा जा सके।
यह कमजोरियों AWS CodeArtifact में पाई गई थी (इस ब्लॉग पोस्ट में विवरण पढ़ें)। AWS ने निर्भरताओं/फीड को आंतरिक बनाम बाहरी के रूप में चिह्नित करने के लिए नियंत्रण जोड़े ताकि क्लाइंट "आंतरिक" नामों को अपस्ट्रीम सार्वजनिक रजिस्ट्रियों से न लाए।
## Finding Vulnerable Libraries
[**Dependency confusion के बारे में मूल पोस्ट**](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) में, लेखक ने हजारों उजागर package.json फ़ाइलों की खोज की जिनमें जावास्क्रिप्ट प्रोजेक्ट की निर्भरताएँ थीं
निर्भरता भ्रम के बारे में मूल पोस्ट में लेखक ने हजारों उजागर मैनिफेस्ट (जैसे, `package.json`, `requirements.txt`, लॉकफाइल) की खोज की ताकि आंतरिक पैकेज नामों का अनुमान लगाया जा सके और फिर उच्च-संस्करण वाले पैकेजों को सार्वजनिक रजिस्ट्रियों में प्रकाशित किया जा सके
## References
## Practical Attacker Playbook (for red teams in authorized tests)
- Enumerate names:
- मैनिफेस्ट/लॉक फ़ाइलों और आंतरिक नाम स्थानों के लिए रिपॉजिटरी और CI कॉन्फ़िगरेशन को ग्रेप करें।
- संगठन-विशिष्ट उपसर्गों की तलाश करें (जैसे, `@company/*`, `company-*`, आंतरिक groupIds, NuGet ID पैटर्न, Go के लिए निजी मॉड्यूल पथ, आदि)।
- उपलब्धता के लिए सार्वजनिक रजिस्ट्रियों की जांच करें:
- यदि नाम सार्वजनिक रूप से अनरजिस्टर्ड है, तो इसे रजिस्टर करें; यदि यह मौजूद है, तो आंतरिक पारगमन नामों को लक्षित करके उपनिर्भरता हाइजैकिंग का प्रयास करें।
- प्राथमिकता के साथ प्रकाशित करें:
- एक सेमवर चुनें जो "जीतता है" (जैसे, एक बहुत उच्च संस्करण) या हल करने वाले के नियमों से मेल खाता है।
- जहां लागू हो, न्यूनतम स्थापना-समय निष्पादन शामिल करें (जैसे, npm `preinstall`/`install`/`postinstall` स्क्रिप्ट)। पायथन के लिए, आयात-समय निष्पादन पथों को प्राथमिकता दें, क्योंकि पहिए आमतौर पर स्थापना पर मनमाना कोड निष्पादित नहीं करते हैं।
- नियंत्रण का एक्सफिल:
- सुनिश्चित करें कि CI से आपके नियंत्रित एंडपॉइंट तक आउटबाउंड की अनुमति है; अन्यथा, कोड निष्पादन को साबित करने के लिए DNS क्वेरी या त्रुटि संदेशों का उपयोग करें।
> [!CAUTION]
> हमेशा लिखित प्राधिकरण प्राप्त करें, संलग्नक के लिए अद्वितीय पैकेज नाम/संस्करण का उपयोग करें, और परीक्षण समाप्त होने पर तुरंत अनप्रकाशित करें या सफाई का समन्वय करें।
## Defender Playbook (what actually prevents confusion)
उच्च-स्तरीय रणनीतियाँ जो पारिस्थितिक तंत्रों में काम करती हैं:
- अद्वितीय आंतरिक नाम स्थानों का उपयोग करें और उन्हें एकल रजिस्ट्रि से बांधें।
- समाधान के समय विश्वास स्तरों को मिलाने से बचें। अनुमोदित सार्वजनिक पैकेज को प्रॉक्सी करने के लिए एकल आंतरिक रजिस्ट्रि को प्राथमिकता दें, बजाय इसके कि पैकेज प्रबंधकों को आंतरिक और सार्वजनिक एंडपॉइंट दोनों दें।
- जिन प्रबंधकों का समर्थन है, पैकेजों को विशिष्ट स्रोतों से मानचित्रित करें (रजिस्ट्रियों के बीच कोई वैश्विक "सर्वश्रेष्ठ-संस्करण" नहीं)।
- पिन और लॉक:
- उन लॉकफाइलों का उपयोग करें जो हल की गई रजिस्ट्रि URLs को रिकॉर्ड करती हैं (npm/yarn/pnpm) या हैश/प्रमाणन पिनिंग का उपयोग करें (pip `--require-hashes`, Gradle निर्भरता सत्यापन)।
- आंतरिक नामों के लिए सार्वजनिक फॉलबैक को रजिस्ट्रि/नेटवर्क परत पर अवरुद्ध करें।
- भविष्य के स्क्वाट को रोकने के लिए जब संभव हो, सार्वजनिक रजिस्ट्रियों में अपने आंतरिक नामों को आरक्षित करें।
## Ecosystem Notes and Secure Config Snippets
नीचे व्यावहारिक, न्यूनतम कॉन्फ़िगरेशन हैं जो निर्भरता भ्रम को कम या समाप्त करने के लिए हैं। इन्हें CI और डेवलपर वातावरण में लागू करने को प्राथमिकता दें।
### JavaScript/TypeScript (npm, Yarn, pnpm)
- सभी आंतरिक कोड के लिए स्कोप्ड पैकेज का उपयोग करें और स्कोप को अपने निजी रजिस्ट्रि पर पिन करें।
- CI में इंस्टॉलेशन को अपरिवर्तनीय रखें (npm लॉकफाइल, `yarn install --immutable`)।
.npmrc (प्रोजेक्ट-स्तरीय)
```
# 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 (आंतरिक पैकेज के लिए)
```
{
"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
```
संचालन संबंधी सुझाव:
- केवल `@company` स्कोप के भीतर आंतरिक पैकेज प्रकाशित करें।
- तृतीय-पक्ष पैकेज के लिए, अपने निजी प्रॉक्सी/मिरर के माध्यम से सार्वजनिक रजिस्ट्री की अनुमति दें, सीधे ग्राहकों से नहीं।
- ट्रेसबिलिटी बढ़ाने के लिए सार्वजनिक पैकेज के लिए npm पैकेज उत्पत्ति सक्षम करने पर विचार करें (यह अपने आप में भ्रम को रोकता नहीं है)।
### Python (pip / Poetry)
मुख्य नियम: विश्वास स्तरों को मिलाने के लिए `--extra-index-url` का उपयोग न करें। या तो:
- एकल आंतरिक इंडेक्स को उजागर करें जो अनुमोदित PyPI पैकेजों को प्रॉक्सी और कैश करता है, या
- स्पष्ट इंडेक्स चयन और हैश पिनिंग का उपयोग करें।
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 के साथ हैश किए गए आवश्यकताएँ उत्पन्न करें:
```
# From pyproject.toml or requirements.in
pip-compile --generate-hashes -o requirements.txt
pip install --require-hashes -r requirements.txt
```
यदि आपको सार्वजनिक PyPI तक पहुंचना है, तो इसे अपने आंतरिक प्रॉक्सी के माध्यम से करें और वहां एक स्पष्ट अनुमति सूची बनाए रखें। CI में `--extra-index-url` से बचें।
### .NET (NuGet)
पैकेज आईडी पैटर्न को स्पष्ट स्रोतों से जोड़ने और अप्रत्याशित फीड से समाधान को रोकने के लिए पैकेज स्रोत मैपिंग का उपयोग करें।
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 (सभी को आंतरिक में मिरर करें; POMs में ad-hoc repos को Enforcer के माध्यम से अनुमति न दें):
```
<settings>
<mirrors>
<mirror>
<id>internal-mirror</id>
<mirrorOf>*</mirrorOf>
<url>https://maven.corp.example/repository/group</url>
</mirror>
</mirrors>
</settings>
```
Enforcer को POMs में घोषित रिपॉजिटरीज़ पर प्रतिबंध लगाने और आपके मिरर के उपयोग को मजबूर करने के लिए जोड़ें:
```
<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: निर्भरता को केंद्रीकृत और लॉक करें।
- केवल `settings.gradle(.kts)` में रिपॉजिटरी लागू करें:
```
dependencyResolutionManagement {
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
repositories {
maven { url = uri("https://maven.corp.example/repository/group") }
}
}
```
- निर्भरता सत्यापन (चेकसम/हस्ताक्षर) सक्षम करें और `gradle/verification-metadata.xml` को कमिट करें।
### गो मॉड्यूल
निजी मॉड्यूल को इस तरह से कॉन्फ़िगर करें कि सार्वजनिक प्रॉक्सी और चेकसम DB का उनके लिए उपयोग न किया जाए।
```
# 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)
क्रेट्स.io को अनुमोदित आंतरिक मिरर या विक्रेता निर्देशिका के साथ बदलें; मनमाने सार्वजनिक बैकफॉल की अनुमति न दें।
.cargo/config.toml
```
[source.crates-io]
replace-with = "corp-mirror"
[source.corp-mirror]
registry = "https://crates-mirror.corp.example/index"
```
प्रकाशन के लिए, `--registry` के साथ स्पष्ट रहें और क्रेडेंशियल्स को लक्षित रजिस्ट्री तक सीमित रखें।
### Ruby (Bundler)
स्रोत ब्लॉकों का उपयोग करें और मल्टीसोर्स Gemfiles को अक्षम करें ताकि जेम्स केवल इच्छित रिपॉजिटरी से आएं।
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
```
कॉन्फ़िग स्तर पर लागू करें:
```
bundle config set disable_multisource true
```
## CI/CD और रजिस्ट्रि नियंत्रण जो मदद करते हैं
- प्राइवेट रजिस्ट्रि एकल इनग्रेस के रूप में:
- Artifactory/Nexus/CodeArtifact/GitHub Packages/Azure Artifacts का उपयोग करें जो एकमात्र एंडपॉइंट है जिसे डेवलपर्स/CI पहुंच सकते हैं।
- ब्लॉक/अनुमति नियम लागू करें ताकि आंतरिक नामस्थान कभी भी अपस्ट्रीम सार्वजनिक स्रोतों से हल न हों।
- लॉकफाइल्स CI में अपरिवर्तनीय हैं:
- npm: `package-lock.json` को कमिट करें, `npm ci` का उपयोग करें।
- Yarn: `yarn.lock` को कमिट करें, `yarn install --immutable` का उपयोग करें।
- Python: हैश किए गए `requirements.txt` को कमिट करें, `--require-hashes` को लागू करें।
- Gradle: `verification-metadata.xml` को कमिट करें और अज्ञात आर्टिफैक्ट्स पर विफल हों।
- आउटबाउंड ईग्रेस नियंत्रण: CI से सार्वजनिक रजिस्ट्रियों तक सीधे पहुंच को ब्लॉक करें सिवाय स्वीकृत प्रॉक्सी के माध्यम से।
- नाम आरक्षण: जहां समर्थित हो, सार्वजनिक रजिस्ट्रियों में अपने आंतरिक नाम/नामस्थान को पूर्व-रजिस्टर करें।
- पैकेज प्रॉविनेंस / अटेस्टेशन: जब सार्वजनिक पैकेज प्रकाशित करें, तो छेड़छाड़ को नीचे की ओर अधिक पहचानने योग्य बनाने के लिए प्रॉविनेंस/अटेस्टेशन सक्षम करें।
## संदर्भ
- [https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610)
- [https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d](https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d)
- [https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping](https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping)
- [https://yarnpkg.com/configuration/yarnrc/](https://yarnpkg.com/configuration/yarnrc/)
{{#include ../banners/hacktricks-training.md}}