Зловживання Cloudflare Workers як pass-through proxies (IP rotation, FireProx-style)

Reading time: 8 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

Cloudflare Workers можна розгорнути як прозорі HTTP pass-through проксі, де upstream target URL надається клієнтом. Запити виходять із мережі Cloudflare, тому ціль бачить Cloudflare IPs замість IP клієнта. Це віддзеркалює відому техніку FireProx на AWS API Gateway, але використовує Cloudflare Workers.

Ключові можливості

  • Підтримка всіх HTTP-методів (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
  • Ціль можна передати через query-параметр (?url=...), заголовок (X-Target-URL) або навіть закодувати в шляху (наприклад, /https://target)
  • Заголовки та тіло проксуються із фільтрацією hop-by-hop/заголовків за потреби
  • Відповіді пересилаються назад, збережено статус-код і більшість заголовків
  • Опціональне підроблення X-Forwarded-For (якщо Worker встановлює його з керованого користувачем заголовка)
  • Надзвичайно швидка/проста ротація через деплой кількох Worker endpoints і розподіл запитів

How it works (flow)

  1. Клієнт відправляє HTTP-запит на Worker URL (<name>.<account>.workers.dev або маршрут на кастомному домені).
  2. Worker витягує ціль з query-параметра (?url=...), заголовка X-Target-URL або сегмента шляху, якщо реалізовано.
  3. Worker пересилає вхідний метод, заголовки та тіло до вказаного upstream URL (з фільтрацією проблемних заголовків).
  4. Відповідь upstream стримується назад до клієнта через Cloudflare; origin бачить Cloudflare egress IPs.

Worker implementation example

  • Читає target URL з query-параметра, заголовка або шляху
  • Копіює безпечну підмножину заголовків і пересилає оригінальний метод/тіло
  • Опційно встановлює X-Forwarded-For, використовуючи керований користувачем заголовок (X-My-X-Forwarded-For) або випадкову IP
  • Додає ліберальну CORS-політику та обробляє preflight
Приклад Worker (JavaScript) для 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('.') }

Автоматизація розгортання та ротації за допомогою FlareProx

FlareProx — це інструмент на Python, який використовує Cloudflare API для розгортання багатьох Worker endpoints і ротації між ними. Це забезпечує FireProx-like IP rotation з мережі Cloudflare.

Налаштування

  1. Створіть Cloudflare API Token, використавши шаблон “Edit Cloudflare Workers”, і отримайте свій Account ID із панелі керування.
  2. Налаштуйте FlareProx:
bash
git clone https://github.com/MrTurvey/flareprox
cd flareprox
pip install -r requirements.txt

Створіть файл конфігурації flareprox.json:

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

Використання CLI

  • Створити N Worker proxies:
bash
python3 flareprox.py create --count 2
  • Перелік endpoints:
bash
python3 flareprox.py list
  • Ендпоінти перевірки стану:
bash
python3 flareprox.py test
  • Видалити всі endpoints:
bash
python3 flareprox.py cleanup

Маршрутизація трафіку через Worker

  • Форма параметра запиту:
bash
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/ip"
  • Форма заголовка:
bash
curl -H "X-Target-URL: https://httpbin.org/ip" https://your-worker.account.workers.dev
  • Форма шляху (якщо реалізовано):
bash
curl https://your-worker.account.workers.dev/https://httpbin.org/ip
  • Приклади методів:
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 контроль

Якщо Worker враховує X-My-X-Forwarded-For, ви можете впливати на значення X-Forwarded-For, яке буде передано upstream:

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

Програмне використання

Використовуйте бібліотеку FlareProx для створення/переліку/тестування endpoints та маршрутизації запитів з Python.

Приклад на Python: Надіслати POST через випадковий Worker endpoint
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}")

Burp/Scanner integration

  • Налаштуйте інструменти (наприклад, Burp Suite) на Worker URL.
  • Надайте реальний upstream, використовуючи ?url= або X-Target-URL.
  • HTTP semantics (methods/headers/body) зберігаються, одночасно маскуючи ваш вихідний IP за Cloudflare.

Операційні нотатки та обмеження

  • Cloudflare Workers Free plan дозволяє приблизно 100,000 запитів/день на акаунт; використовуйте кілька endpoints для розподілу трафіку за потреби.
  • Workers працюють в мережі Cloudflare; багато цілей бачитимуть лише Cloudflare IPs/ASN, що може обійти наївні списки дозволених/заборонених IP або geo heuristics.
  • Використовуйте відповідально і тільки з авторизацією. Дотримуйтесь ToS та robots.txt.

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks