MEMCACHE 反射放大攻击分析

85 阅读3分钟

简介

Memcached 是一种高性能的分布式内存对象缓存系统,常用于加速动态 Web 应用程序。然而,由于其默认配置和 UDP 协议的特性,Memcached 服务器容易受到反射放大攻击,对互联网安全构成威胁。本文将深入分析 Memcached 反射放大攻击的原理、实现和防范措施,并探讨其在 DDoS 攻击中的现状。

Memcached 反射放大攻击

原理

Memcached 反射放大攻击的原理是利用 Memcached 服务器的 stats 命令,该命令会返回大量的服务器统计信息。攻击者通过伪造源 IP 地址,向大量的 Memcached 服务器发送 stats 命令,服务器将响应发送给伪造的源 IP 地址,即受害者。由于响应包远大于请求包,因此可以实现流量放大。

攻击者还可以利用 setget 命令,通过设置超大 value 的 key,然后使用 get 命令获取该 key,从而实现更大的放大倍数。

放大倍数

Memcached 反射放大攻击的放大倍数非常高,最大可接近 50000 倍。

Memcached默认对Key和Value长度做如下限制:

  • Key字符串的长度不能超过255个字符;
  • Value字符串的长度不能超过1024 * 1024个字符, 即存储数据不能超过1M;

防范措施

  • 禁用 UDP 协议:如果 Memcached 服务器不需要提供 UDP 服务,应禁用 UDP 协议。
  • 配置防火墙规则,只允许特定的 IP 地址或 IP 地址范围访问 Memcached 服务器的端口(默认为 11211)
  • 如果 Memcached 服务器只被本地应用程序使用,可以将其绑定到本地回环接口(127.0.0.1)

Golang 客户端

使用 Golang 编写 Memcached 客户端,可以通过 github.com/bradfitz/gomemcache/memcache 库实现。

以下是一个简单的示例:

main.go

package main

import (
        "fmt"
        "log"
        "github.com/bradfitz/gomemcache/memcache"
)


func main() {
        // 获取memcache客户端
        mc := memcache.New("127.0.0.1:11211")
        // 添加键为key,值为value的数据
        clen := 1024*1024-62
        cvalue := make([]byte, clen)
        err := mc.Set(&memcache.Item{Key: "key", Value: cvalue})
        if err != nil {
           log.Fatal(err)
        }
        // 获取键为key的Item
        item, err := mc.Get("key")
        if err != nil {
           log.Fatal(err)
        }
        fmt.Println(string(item.Value))
}
  • set 请求报文

image.png

  • STORED 响应报文

image.png

  • gets 请求报文 image.png

  • VALUE 响应报文 image.png

命令分析

Memcached 协议基于 TCP 协议,客户端通过发送文本命令给服务器,服务器返回文本响应。每个命令以换行符 \r\n 结束。

命令格式

<command> <key> <flags> <exptime> <bytes> \r\n [<data>] \r\n

常用命令

  • set <key> <flags> <exptime> <bytes> \r\n [<data>] \r\n:存储数据。
  • get <key> \r\n:获取数据。
  • stats\r\n:获取统计信息。

响应格式

  • STORED\r\n:表示数据存储成功。
  • VALUE <key> <flags> <bytes> \r\n<data>\r\nEND\r\n:表示获取数据成功。

构建请求包

使用 Golang 构建 Memcached 请求包的示例代码:

Go

memcache := []byte{
        0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // 协议头
}
setRequest := fmt.Sprintf("stats\r\n")
memcache = append(memcache, []byte(setRequest)...)

UDP 协议

Memcached 也支持 UDP 协议,但是由于 UDP 协议的特性,需要一个特定协议头。

使用 netcat 工具发送 UDP 请求的示例:

Bash

echo -en "\x00\x00\x00\x00\x00\x01\x00\x00stats\r\n" | nc -u 127.0.0.1 11211

Fofa、ZoomEye、Shadow 平台的利用

攻击者可以使用 Fofa、ZoomEye、Shadow 等网络空间安全搜索引擎,搜索暴露在公网上的 Memcached 服务器。

  • Fofa: app="Memcached"

攻击者可以利用搜索结果,筛选出存在安全漏洞的 Memcached 服务器,发起反射放大攻击。

image.png

参考