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

Tip

Apprenez & pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Soutenez 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 & pratiquez AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://hacktricks-training.com/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Apprenez & pratiquez GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://hacktricks-training.com/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Apprenez & pratiquez Az Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://hacktricks-training.com/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Soutenez HackTricks</summary>
>
> - Consultez les [**subscription plans**](https://github.com/sponsors/carlospolop)!
> - **Rejoignez le** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) ou le [**telegram group**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐩 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Partagez des hacking tricks en soumettant des PRs aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>