Cloudflare Workers를 패스스루 프록시로 악용하기 (IP 회전, FireProx-style)
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
Cloudflare Workers는 업스트림 대상 URL을 클라이언트가 제공하는 투명한 HTTP 패스스루 프록시로 배포될 수 있습니다. 요청은 Cloudflare 네트워크에서 egress되므로 대상은 클라이언트 대신 Cloudflare IP를 관찰합니다. 이는 AWS API Gateway에서 잘 알려진 FireProx 기법과 유사하지만 Cloudflare Workers를 사용합니다.
주요 기능
- 모든 HTTP 메서드 지원 (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
- 대상은 쿼리 매개변수(?url=…), 헤더(X-Target-URL), 또는 경로 인코딩(예: /https://target)으로 제공 가능
- 필요에 따라 hop-by-hop/header filtering을 적용하면서 헤더와 바디를 프록시
- 상태 코드와 대부분의 헤더를 보존하여 응답을 클라이언트로 전달
- Worker가 사용자 제어 헤더에서 설정하는 경우 X-Forwarded-For 스푸핑 선택 가능
- 여러 Worker 엔드포인트를 배포하고 요청을 분산(fanning out)하여 매우 빠르고 쉬운 회전 가능
작동 방식 (흐름)
- 클라이언트가 Worker URL(
<name>.<account>.workers.dev또는 커스텀 도메인 라우트)로 HTTP 요청을 보냅니다. - Worker는 쿼리 매개변수(?url=…), X-Target-URL 헤더, 또는 구현된 경우 경로 세그먼트에서 대상을 추출합니다.
- Worker는 문제를 일으킬 수 있는 헤더를 필터링하면서 들어온 메서드, 헤더, 바디를 지정된 업스트림 URL로 전달합니다.
- 업스트림 응답은 Cloudflare를 통해 클라이언트로 스트리밍되어 발신지는 Cloudflare egress IP를 보게 됩니다.
Worker 구현 예시
- 쿼리 파라미터, 헤더 또는 경로에서 대상 URL을 읽음
- 안전한 헤더 하위 집합을 복사하고 원본 메서드/바디를 전달
- 선택적으로 사용자 제어 헤더(X-My-X-Forwarded-For)나 랜덤 IP로 X-Forwarded-For 설정
- 관대한 CORS 추가 및 preflight 처리
패스스루 프록시용 예제 Worker (JavaScript)
```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>
### FlareProx를 사용한 배포 및 회전 자동화
FlareProx는 Cloudflare API를 사용해 여러 Worker endpoints를 배포하고 그 사이를 회전하는 Python 도구입니다. 이를 통해 Cloudflare의 네트워크에서 FireProx-like한 IP 회전을 제공합니다.
설정
1) 대시보드에서 “Edit Cloudflare Workers” 템플릿을 사용하여 Cloudflare API Token을 생성하고 Account ID를 확인합니다.
2) FlareProx 구성:
```bash
git clone https://github.com/MrTurvey/flareprox
cd flareprox
pip install -r requirements.txt
flareprox.json 구성 파일 생성:
{
"cloudflare": {
"api_token": "your_cloudflare_api_token",
"account_id": "your_cloudflare_account_id"
}
}
CLI 사용법
- N개의 Worker proxies 생성:
python3 flareprox.py create --count 2
- 엔드포인트 나열:
python3 flareprox.py list
- 헬스 체크 엔드포인트:
python3 flareprox.py test
- 모든 엔드포인트 삭제:
python3 flareprox.py cleanup
Worker를 통한 트래픽 라우팅
- 쿼리 파라미터 형식:
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/ip"
- 헤더 형식:
curl -H "X-Target-URL: https://httpbin.org/ip" https://your-worker.account.workers.dev
- 경로 형식 (구현된 경우):
curl https://your-worker.account.workers.dev/https://httpbin.org/ip
- 방법 예시:
# 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 값을 조작할 수 있습니다:
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 예시: 임의의 Worker endpoint를 통해 POST 전송
```python #!/usr/bin/env python3 from flareprox import FlareProx, FlareProxError import jsonInitialize
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>
**Burp/Scanner 통합**
- 도구(예: Burp Suite)를 Worker URL로 지정하세요.
- 실제 업스트림은 ?url= 또는 X-Target-URL을 사용해 제공하세요.
- HTTP 의미론(메서드/헤더/바디)은 유지되며 소스 IP는 Cloudflare 뒤에 가려집니다.
**운영상의 주의사항 및 제한**
- Cloudflare Workers Free plan은 계정당 하루 약 100,000 요청을 허용합니다; 필요하면 트래픽 분산을 위해 여러 엔드포인트를 사용하세요.
- Workers는 Cloudflare의 네트워크에서 실행됩니다; 많은 대상은 Cloudflare IPs/ASN만 보게 되어 단순한 IP 허용/차단 목록이나 지리적 휴리스틱을 우회할 수 있습니다.
- 책임 있게, 권한이 있는 경우에만 사용하세요. ToS와 robots.txt를 준수하세요.
## 참고자료
- [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]
> 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;">\
> 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;">
> 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>HackTricks 지원하기</summary>
>
> - [**구독 계획**](https://github.com/sponsors/carlospolop) 확인하기!
> - **💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 참여하거나 **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**를 팔로우하세요.**
> - **[**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.**
>
> </details>
HackTricks Cloud

