Abuser Cloudflare Workers en tant que proxies pass-through (rotation d’IP, FireProx-style)

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Cloudflare Workers peuvent être déployés comme des proxies HTTP transparents pass-through où l’URL cible upstream est fournie par le client. Les requêtes sortent du réseau Cloudflare, donc la cible voit les IPs de Cloudflare au lieu de celles du client. Cela reflète la technique bien connue FireProx sur AWS API Gateway, mais utilise Cloudflare Workers.

Fonctionnalités clés

  • Prise en charge de toutes les méthodes HTTP (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
  • La cible peut être fournie via un paramètre de requête (?url=…), un header (X-Target-URL), ou même encodée dans le chemin (par ex. /https://target)
  • Les headers et le corps sont relayés via le proxy avec filtrage des headers hop-by-hop si nécessaire
  • Les réponses sont renvoyées en conservant le code de statut et la plupart des headers
  • Usurpation optionnelle de X-Forwarded-For (si le Worker le définit à partir d’un header contrôlé par l’utilisateur)
  • Rotation très rapide/facile en déployant plusieurs endpoints Worker et en répartissant les requêtes

Comment ça marche (flux)

  1. Le client envoie une requête HTTP vers une URL Worker (<name>.<account>.workers.dev ou un route de domaine personnalisé).
  2. Le Worker extrait la cible soit d’un paramètre de requête (?url=…), soit du header X-Target-URL, ou d’un segment de chemin si implémenté.
  3. Le Worker transfère la méthode, les headers et le corps entrants vers l’URL upstream spécifiée (en filtrant les headers problématiques).
  4. La réponse upstream est streamée vers le client via Cloudflare ; l’origine voit les IPs de sortie de Cloudflare.

Exemple d’implémentation du Worker

  • Lit l’URL cible depuis un paramètre de requête, un header ou le chemin
  • Copie un sous-ensemble sûr de headers et transmet la méthode/le corps originaux
  • Définit optionnellement X-Forwarded-For en utilisant un header contrôlé par l’utilisateur (X-My-X-Forwarded-For) ou une IP aléatoire
  • Ajoute un CORS permissif et gère les preflight
Exemple de Worker (JavaScript) pour le proxy pass-through ```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>

### Automatisation du déploiement et de la rotation avec FlareProx

FlareProx est un outil Python qui utilise l'API Cloudflare pour déployer plusieurs endpoints Worker et effectuer la rotation entre eux. Cela fournit une rotation d'IP de type FireProx depuis le réseau de Cloudflare.

Setup
1) Créez un Cloudflare API Token en utilisant le template “Edit Cloudflare Workers” et récupérez votre Account ID depuis le tableau de bord.
2) Configurez FlareProx:
```bash
git clone https://github.com/MrTurvey/flareprox
cd flareprox
pip install -r requirements.txt

Créer le fichier de configuration flareprox.json :

{
"cloudflare": {
"api_token": "your_cloudflare_api_token",
"account_id": "your_cloudflare_account_id"
}
}

Utilisation de la CLI

  • Créer N proxies Worker :
python3 flareprox.py create --count 2
  • Lister les endpoints :
python3 flareprox.py list
  • Points de terminaison de vérification de santé :
python3 flareprox.py test
  • Supprimer tous les endpoints:
python3 flareprox.py cleanup

Acheminer le trafic via un Worker

  • Forme de paramètre de requête :
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/ip"
  • Formulaire d’en-tête:
curl -H "X-Target-URL: https://httpbin.org/ip" https://your-worker.account.workers.dev
  • Format de chemin (si implémenté):
curl https://your-worker.account.workers.dev/https://httpbin.org/ip
  • Exemples de méthodes:
# 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"

contrôle de X-Forwarded-For

Si le Worker honore X-My-X-Forwarded-For, vous pouvez influencer la valeur en amont de X-Forwarded-For :

curl -H "X-My-X-Forwarded-For: 203.0.113.10" \
"https://your-worker.account.workers.dev?url=https://httpbin.org/headers"

Utilisation programmatique

Utilisez la bibliothèque FlareProx pour créer/lister/tester des endpoints et acheminer des requêtes depuis Python.

Exemple Python : Envoyer un POST via un endpoint Worker aléatoire ```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>

**Intégration Burp/Scanner**
- Redirigez vos outils (par exemple, Burp Suite) vers l'URL du Worker.
- Fournissez l'upstream réel en utilisant ?url= ou X-Target-URL.
- La sémantique HTTP (methods/headers/body) est préservée tout en masquant votre IP source derrière Cloudflare.

**Notes opérationnelles et limites**
- Le plan Free de Cloudflare Workers permet environ 100 000 requêtes/jour par compte ; utilisez plusieurs endpoints pour répartir le trafic si nécessaire.
- Les Workers s'exécutent sur le réseau Cloudflare ; de nombreuses cibles ne verront que les IPs/ASN de Cloudflare, ce qui peut contourner des listes d'autorisation/refus IP naïves ou des heuristiques géographiques.
- Utilisez de manière responsable et seulement avec autorisation. Respectez les ToS et robots.txt.

## Références
- [FlareProx (Cloudflare Workers pass-through/rotation)](https://github.com/MrTurvey/flareprox)
- [Cloudflare Workers fetch() API](https://developers.cloudflare.com/workers/runtime-apis/fetch/)
- [Cloudflare Workers pricing and free tier](https://developers.cloudflare.com/workers/platform/pricing/)
- [FireProx (AWS API Gateway)](https://github.com/ustayready/fireprox)

> [!TIP]
> Apprenez et pratiquez le hacking AWS :<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Apprenez et pratiquez le hacking GCP : <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Apprenez et pratiquez le hacking Azure : <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Soutenir HackTricks</summary>
>
> - Vérifiez les [**plans d'abonnement**](https://github.com/sponsors/carlospolop) !
> - **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez-nous sur** **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Partagez des astuces de hacking en soumettant des PR au** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts github.
>
> </details>