Translated ['', 'src/pentesting-web/dependency-confusion.md'] to el

This commit is contained in:
Translator 2025-08-21 02:42:36 +00:00
parent 0d83bc82f1
commit bc38bda29a

View File

@ -5,41 +5,268 @@
## Basic Information
Συνοπτικά, μια ευπάθεια εξάρτησης συμβαίνει όταν ένα έργο χρησιμοποιεί μια βιβλιοθήκη με **λάθος** όνομα, **ανύπαρκτη** ή με **μη καθορισμένη έκδοση** και το αποθετήριο εξαρτήσεων που χρησιμοποιείται επιτρέπει να **συγκεντρωθούν ενημερωμένες εκδόσεις από δημόσιες** αποθήκες.
Η Διαταραχή Εξάρτησης (γνωστή και ως επιθέσεις υποκατάστασης) συμβαίνει όταν ένας διαχειριστής πακέτων επιλύει ένα όνομα εξάρτησης από μια μη προοριζόμενη, λιγότερο αξιόπιστη πηγή/μητρώο (συνήθως ένα δημόσιο μητρώο) αντί για το προοριζόμενο ιδιωτικό/εσωτερικό. Αυτό συνήθως οδηγεί στην εγκατάσταση ενός πακέτου που ελέγχεται από τον επιτιθέμενο.
Κοινές ρίζες αιτίες:
- Typosquatting/ορθογραφικά λάθη: Εισαγωγή του `reqests` αντί του `requests` (επιλύεται από δημόσιο μητρώο).
- Μη υπάρχον/παρατημένο εσωτερικό πακέτο: Εισαγωγή του `company-logging` που δεν υπάρχει πια εσωτερικά, οπότε ο επιλυτής κοιτάζει σε δημόσια μητρώα και βρίσκει ένα πακέτο του επιτιθέμενου.
- Προτίμηση έκδοσης σε πολλαπλά μητρώα: Εισαγωγή ενός εσωτερικού `company-requests` ενώ ο επιλυτής επιτρέπεται να ερωτά και δημόσια μητρώα και προτιμά την “καλύτερη”/νεότερη έκδοση που δημοσιεύεται δημόσια από έναν επιτιθέμενο.
Κύρια ιδέα: Εάν ο επιλυτής μπορεί να δει πολλαπλά μητρώα για το ίδιο όνομα πακέτου και επιτρέπεται να επιλέξει τον “καλύτερο” υποψήφιο παγκοσμίως, είστε ευάλωτοι εκτός αν περιορίσετε την επίλυση.
- **Λάθος**: Εισαγωγή **`reqests`** αντί για `requests`
- **Ανύπαρκτη**: Εισαγωγή `company-logging`, μιας εσωτερικής βιβλιοθήκης που **δεν υπάρχει πια**
- **Μη καθορισμένη έκδοση**: Εισαγωγή μιας **εσωτερικής** **υπάρχουσας** βιβλιοθήκης `company-requests`, αλλά ο έλεγχος του αποθετηρίου **δημόσιων αποθηκών** για να δει αν υπάρχουν **μεγαλύτερες εκδόσεις**.
## Exploitation
> [!WARNING]
> Σε όλες τις περιπτώσεις, ο επιτιθέμενος χρειάζεται απλώς να δημοσιεύσει ένα **κακόβουλο πακέτο με το όνομα** των βιβλιοθηκών που χρησιμοποιεί η εταιρεία-θύμα.
> Σε όλες τις περιπτώσεις, ο επιτιθέμενος χρειάζεται μόνο να δημοσιεύσει ένα κακόβουλο πακέτο με το ίδιο όνομα όπως η εξάρτηση από την οποία επιλύει η κατασκευή σας από ένα δημόσιο μητρώο. Οι hooks κατά την εγκατάσταση (π.χ., npm scripts) ή οι διαδρομές κώδικα κατά την εισαγωγή συχνά δίνουν εκτέλεση κώδικα.
### Misspelled & Inexistent
Αν η εταιρεία σας προσπαθεί να **εισαγάγει μια βιβλιοθήκη που δεν είναι εσωτερική**, είναι πολύ πιθανό το αποθετήριο βιβλιοθηκών να την αναζητά σε **δημόσιες αποθήκες**. Αν ένας επιτιθέμενος την έχει δημιουργήσει, ο κώδικας και οι μηχανές που τρέχουν είναι πολύ πιθανό να έχουν παραβιαστεί.
Εάν το έργο σας αναφέρεται σε μια βιβλιοθήκη που δεν είναι διαθέσιμη στο ιδιωτικό μητρώο, και τα εργαλεία σας επιστρέφουν σε ένα δημόσιο μητρώο, ένας επιτιθέμενος μπορεί να σπείρει ένα κακόβουλο πακέτο με αυτό το όνομα στο δημόσιο μητρώο. Οι εκτελέσεις σας/CI/μηχανές ανάπτυξης θα το ανακτήσουν και θα το εκτελέσουν.
### Unspecified Version
### Unspecified Version / “Best-version” selection across indexes
Οι προγραμματιστές συχνά αφήνουν τις εκδόσεις μη καθορισμένες ή επιτρέπουν ευρείες γκάμες. Όταν ένας επιλυτής είναι ρυθμισμένος με εσωτερικούς και δημόσιους δείκτες, μπορεί να επιλέξει την πιο πρόσφατη έκδοση ανεξαρτήτως πηγής. Για εσωτερικά ονόματα όπως το `requests-company`, εάν ο εσωτερικός δείκτης έχει `1.0.1` αλλά ένας επιτιθέμενος δημοσιεύει `1.0.2` στο δημόσιο μητρώο και ο επιλυτής σας θεωρεί και τα δύο, το δημόσιο πακέτο μπορεί να κερδίσει.
Είναι πολύ συνηθισμένο για τους προγραμματιστές να **μην καθορίζουν καμία έκδοση** της βιβλιοθήκης που χρησιμοποιείται, ή να καθορίζουν μόνο μια **κύρια έκδοση**. Στη συνέχεια, ο διερμηνέας θα προσπαθήσει να κατεβάσει την **τελευταία έκδοση** που πληροί αυτές τις απαιτήσεις.\
Αν η βιβλιοθήκη είναι μια **γνωστή εξωτερική βιβλιοθήκη** (όπως η python `requests`), ένας **επιτιθέμενος δεν μπορεί να κάνει πολλά**, καθώς δεν θα μπορεί να δημιουργήσει μια βιβλιοθήκη που ονομάζεται `requests` (εκτός αν είναι ο αρχικός συγγραφέας).\
Ωστόσο, αν η βιβλιοθήκη είναι **εσωτερική**, όπως η `requests-company` σε αυτό το παράδειγμα, αν το **αποθετήριο βιβλιοθηκών** επιτρέπει να **ελέγχει για νέες εκδόσεις και εξωτερικά**, θα αναζητήσει μια νεότερη έκδοση που είναι διαθέσιμη δημόσια.\
Έτσι, αν ένας **επιτιθέμενος γνωρίζει** ότι η εταιρεία χρησιμοποιεί τη βιβλιοθήκη `requests-company` **έκδοση 1.0.1** (επιτρέποντας μικρές ενημερώσεις). Μπορεί να **δημοσιεύσει** τη βιβλιοθήκη `requests-company` **έκδοση 1.0.2** και η εταιρεία θα **χρησιμοποιήσει αυτή τη βιβλιοθήκη αντί** της εσωτερικής.
## AWS Fix
Αυτή η ευπάθεια βρέθηκε στο AWS **CodeArtifact** (διαβάστε τις [**λεπτομέρειες σε αυτή την ανάρτηση blog**](https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d)).\
Η AWS το διόρθωσε επιτρέποντας να καθοριστεί αν μια βιβλιοθήκη είναι εσωτερική ή εξωτερική, για να αποφευχθεί η λήψη εσωτερικών εξαρτήσεων από εξωτερικά αποθετήρια.
Αυτή η ευπάθεια βρέθηκε στο AWS CodeArtifact (διαβάστε τις λεπτομέρειες σε αυτή την ανάρτηση blog). Η AWS πρόσθεσε ελέγχους για να επισημάνει τις εξαρτήσεις/τροφές ως εσωτερικές ή εξωτερικές ώστε ο πελάτης να μην ανακτά “εσωτερικά” ονόματα από ανώτερα δημόσια μητρώα.
## Finding Vulnerable Libraries
Στην [**αρχική ανάρτηση σχετικά με την ευπάθεια εξάρτησης**](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) ο συγγραφέας αναζήτησε χιλιάδες εκτεθειμένα αρχεία package.json που περιέχουν τις εξαρτήσεις έργων javascript.
Στην αρχική ανάρτηση σχετικά με τη διαταραχή εξάρτησης, ο συγγραφέας αναζητούσε χιλιάδες εκτεθειμένα μανιφέστα (π.χ., `package.json`, `requirements.txt`, lockfiles) για να συμπεράνει τα εσωτερικά ονόματα πακέτων και στη συνέχεια δημοσίευσε πακέτα με υψηλότερες εκδόσεις σε δημόσια μητρώα.
## References
## Practical Attacker Playbook (for red teams in authorized tests)
- Καταγράψτε ονόματα:
- Grep repos και CI configs για μανιφέστα/lock files και εσωτερικά namespaces.
- Αναζητήστε συγκεκριμένα προθέματα οργανώσεων (π.χ., `@company/*`, `company-*`, εσωτερικά groupIds, πρότυπα NuGet ID, ιδιωτικές διαδρομές module για Go, κ.λπ.).
- Ελέγξτε δημόσια μητρώα για διαθεσιμότητα:
- Εάν το όνομα δεν είναι δημόσια καταχωρημένο, καταχωρήστε το; εάν υπάρχει, προσπαθήστε να κάνετε hijacking υποεξαρτήσεων στοχεύοντας εσωτερικά μεταβατικά ονόματα.
- Δημοσιεύστε με προτεραιότητα:
- Επιλέξτε μια semver που “κερδίζει” (π.χ., μια πολύ υψηλή έκδοση) ή ταιριάζει με τους κανόνες του επιλυτή.
- Συμπεριλάβετε ελάχιστη εκτέλεση κατά την εγκατάσταση όπου είναι εφαρμόσιμο (π.χ., npm `preinstall`/`install`/`postinstall` scripts). Για Python, προτιμήστε διαδρομές εκτέλεσης κατά την εισαγωγή, καθώς οι wheels συνήθως δεν εκτελούν αυθαίρετο κώδικα κατά την εγκατάσταση.
- Εξαγωγή ελέγχου:
- Βεβαιωθείτε ότι επιτρέπεται η έξοδος από το CI προς το ελεγχόμενο endpoint σας; αλλιώς χρησιμοποιήστε DNS queries ή μηνύματα σφάλματος ως side-channel για να αποδείξετε την εκτέλεση κώδικα.
> [!CAUTION]
> Πάντα να αποκτάτε γραπτή εξουσιοδότηση, χρησιμοποιήστε μοναδικά ονόματα/εκδόσεις πακέτων για την εμπλοκή, και αμέσως αφαιρέστε ή συντονίστε την καθαριότητα όταν ολοκληρωθεί η δοκιμή.
## Defender Playbook (what actually prevents confusion)
Στρατηγικές υψηλού επιπέδου που λειτουργούν σε οικοσυστήματα:
- Χρησιμοποιήστε μοναδικά εσωτερικά namespaces και συνδέστε τα σε ένα μόνο μητρώο.
- Αποφύγετε την ανάμειξη επιπέδων εμπιστοσύνης κατά την επίλυση. Προτιμήστε ένα μόνο εσωτερικό μητρώο που προξενεί εγκεκριμένα δημόσια πακέτα αντί να δίνετε στους διαχειριστές πακέτων και τα δύο εσωτερικά και δημόσια endpoints.
- Για διαχειριστές που το υποστηρίζουν, χαρτογραφήστε τα πακέτα σε συγκεκριμένες πηγές (κανένα παγκόσμιο “best-version” σε μητρώα).
- Κλειδώστε και κλειδώστε:
- Χρησιμοποιήστε lockfiles που καταγράφουν τα URLs του επιλυμένου μητρώου (npm/yarn/pnpm) ή χρησιμοποιήστε hash/attestation pinning (pip `--require-hashes`, Gradle dependency verification).
- Εμποδίστε την δημόσια επιστροφή για εσωτερικά ονόματα στο επίπεδο του μητρώου/δικτύου.
- Κρατήστε τα εσωτερικά ονόματά σας σε δημόσια μητρώα όταν είναι εφικτό για να αποτρέψετε μελλοντικό squat.
## Ecosystem Notes and Secure Config Snippets
Παρακάτω είναι πρακτικές, ελάχιστες ρυθμίσεις για να μειώσετε ή να εξαλείψετε τη διαταραχή εξάρτησης. Προτιμήστε να επιβάλλετε αυτές τις ρυθμίσεις σε CI και περιβάλλοντα ανάπτυξης.
### JavaScript/TypeScript (npm, Yarn, pnpm)
- Χρησιμοποιήστε scoped packages για όλο τον εσωτερικό κώδικα και κλειδώστε την εμβέλεια στο ιδιωτικό σας μητρώο.
- Διατηρήστε τις εγκαταστάσεις αμετάβλητες στο CI (npm lockfile, `yarn install --immutable`).
.npmrc (project-level)
```
# 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
```
Operational tips:
- Δημοσιεύστε μόνο εσωτερικά πακέτα εντός του `@company` scope.
- Για τρίτα πακέτα, επιτρέψτε δημόσιο μητρώο μέσω του ιδιωτικού σας proxy/mirror, όχι απευθείας από τους πελάτες.
- Σκεφτείτε να ενεργοποιήσετε την προέλευση πακέτων npm για τα δημόσια πακέτα που δημοσιεύετε για να αυξήσετε την ιχνηλασιμότητα (δεν αποτρέπει από μόνη της την σύγχυση).
### Python (pip / Poetry)
Core rule: Μην χρησιμοποιείτε `--extra-index-url` για να αναμειγνύετε επίπεδα εμπιστοσύνης. Είτε:
- Εκθέστε έναν μόνο εσωτερικό δείκτη που προξενεί και αποθηκεύει τα εγκεκριμένα πακέτα PyPI, είτε
- Χρησιμοποιήστε ρητή επιλογή δείκτη και κωδικοποίηση hash.
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, κάντε το μέσω του εσωτερικού σας proxy και διατηρήστε μια ρητή λίστα επιτρεπόμενων εκεί. Αποφύγετε το `--extra-index-url` στο CI.
### .NET (NuGet)
Χρησιμοποιήστε το Package Source Mapping για να συνδέσετε τα πρότυπα ID πακέτων με ρητές πηγές και να αποτρέψετε την επίλυση από απροσδόκητες πηγές.
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 (καθρέφτης όλα στο εσωτερικό; απαγόρευση ad-hoc repos στα POMs μέσω 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") }
}
}
```
- Ενεργοποιήστε την επαλήθευση εξαρτήσεων (checksums/signatures) και δεσμεύστε το `gradle/verification-metadata.xml`.
### Go Modules
Ρυθμίστε ιδιωτικά modules ώστε να μην χρησιμοποιούνται το δημόσιο proxy και η βάση δεδομένων checksums για αυτά.
```
# 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 με έναν εγκεκριμένο εσωτερικό καθρέφτη ή κατάλογο προμηθευτή για τις κατασκευές. Μην επιτρέπετε αυθαίρετη δημόσια εναλλακτική λύση.
.cargo/config.toml
```
[source.crates-io]
replace-with = "corp-mirror"
[source.corp-mirror]
registry = "https://crates-mirror.corp.example/index"
```
Για τη δημοσίευση, να είστε σαφείς με το `--registry` και να διατηρείτε τα διαπιστευτήρια περιορισμένα στο στοχευμένο μητρώο.
### Ruby (Bundler)
Χρησιμοποιήστε μπλοκ πηγών και απενεργοποιήστε τα Gemfiles πολλαπλών πηγών ώστε τα gems να προέρχονται μόνο από το προοριζόμενο αποθετήριο.
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.
- Εφαρμόστε κανόνες αποκλεισμού/επιτρεπόμενων ώστε οι εσωτερικές ονομασίες να μην επιλύονται ποτέ από δημόσιες πηγές upstream.
- Τα lockfiles είναι αμετάβλητα στο CI:
- npm: δεσμεύστε το `package-lock.json`, χρησιμοποιήστε το `npm ci`.
- Yarn: δεσμεύστε το `yarn.lock`, χρησιμοποιήστε το `yarn install --immutable`.
- Python: δεσμεύστε το κατακερματισμένο `requirements.txt`, επιβάλετε το `--require-hashes`.
- Gradle: δεσμεύστε το `verification-metadata.xml` και αποτύχετε σε άγνωστα αρχεία.
- Έλεγχος εξόδου: αποκλείστε την άμεση πρόσβαση από το CI σε δημόσια μητρώα εκτός μέσω του εγκεκριμένου proxy.
- Διατήρηση ονομάτων: προεγγραφείτε στα εσωτερικά σας ονόματα/ονομασίες σε δημόσια μητρώα όπου υποστηρίζεται.
- Προέλευση πακέτου / πιστοποιήσεις: όταν δημοσιεύετε δημόσια πακέτα, ενεργοποιήστε την προέλευση/πιστοποιήσεις για να κάνετε την παραχάραξη πιο ανιχνεύσιμη downstream.
## Αναφορές
- [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}}