前言
出品|且听安全(ID:QCyber)
以下内容,来自且听安全公众号的作者原创,由于传播,利用此文所提供的信息而造成的任何直接或间接的后果和损失,均由使用者本人负责,长白山攻防实验室以及文章作者不承担任何责任。
漏洞简介
在`v3.2.2`版本之前的`Apache CouchDB`中,可以在不进行身份验证的情况下访问不正确的默认安装并获得管理员权限,进而实现RCE ,漏洞编号CVE-2022-24706。除了需要满足版本需求外,漏洞触发还需有以下条件:
-
`4369` `epmd` 端口暴露至公网;
-
`Erlang`使用默认`Cookie` 值( `monster` );
-
目标主机防火墙未设置拦截访问任意端口。
该漏洞看似是`Apache CouchDB`的漏洞,实际上是`Erlang`分布式系统的正常功能,只不过`Apache CouchDB`的`erl`节点使用了默认的`monster` `Cookie` ,其他`erl`节点使用相同的`Cookie`可以与`CouchDB`中的分布式节点建立连接并进行通信,在通信的过程中就可以使用`os:cmd`执行底层系统命令。具体交互过程如下:
利用者只需要完成以下操作:
-
使用`epmd`协议,与`epmd`程序进行交互查询其中的`erl`节点;
-
直接与`CouchDB`中的`erl`节点进行通信,接收节点发送来的`Challenge`;
-
向`CouchDB` `erl`节点发送根据`Challenge`计算的`hash`值;
-
`CouchDB` `erl`节点比对`hash`值相同后回复`Challenge ACK` 。
之后利用者可执行任意指令。
漏洞分析
可以通过`Docker`搭建`Apache Couch-DB`,手动编译生成`Erlang`分布式应用:
在漏洞简介部分已经说明该漏洞是`erl`分布式的正常功能,因此在漏洞分析的时候主要分析`erlang`节点通信相关流程及协议交互过程。
`erlang`分布式协议主要在源代码的`/erts/doc/src/erl_dist_protocol.xml`文件中,也可以在`erlang`官网
`https://www.erlang.org/doc/apps/erts/erl_dist_protocol.html`查看协议格式。
0x01 启动 erl 节点
在两个不同的虚拟机上启动 `erl` 节点:
- `192.168.147.129`
cd /usr/local/erlang/otp_src_19.3/bin
./erl -setcookie monsters -name test@192.168.147.129
- `192.168.147.22`
./erl -setcookie monsters -name test2
0x02 查询EPMD节点请求
在`192.168.147.22`机器上执行如下指令:
通过`wireshark`获取流量,协议内容如下:
`epmd`回应包如下,在数据包中可看到在`epmd`注册的所有`erl`节点名称:
根据`erlang`分布式协议`epmd`节点查询请求格式,构造查询数据包,协议格式如下:
EPM_NAME_CMD = b"\x00\x01\x6e" #1 110
s.send(EPM_NAME_REQ)
data=s.recv(4)
erl_node = s.recv(1024)
print erl_node
代码运行结果如下,将会获取所有注册在`epmd`上的`erl`节点:
0x03 erlang 分布式节点挑战相应机制
在`192.168.147.22`上执行如下指令:
./erl -setcookie monsters -name test2 -remsh test@192.168.147.129
该指令属于两个节点的通信交互指令,在`erlang`分布式协议中,`A`节点向`B`节点建立连接需要发起连接请求,`A`节点发送当前主机名等信息,并接受来自`B`节点的`status`响应,协议数据如下所示:
`send_name`协议格式如下:
`Version0`和`Version1`是`A`基于`EPMD`选择的分布式协议版本
`capability flags`为`A`设置的能力标志,`Name`为`A`节点的全名:
NAME_MSG = "test@DESKTOP-M4IDODK.localdomain"
s.send(NAME_MSG)
s.recv(5) # Receive "ok" message
之后便开始执行挑战响应。挑战响应机制总共分为三个步骤,如下图所示
`SEND_CHALLENGE`、
`SEND_CHANLLENGE_REPLY` 、
`SEND_CHALLENGE_ACK` :
(1)发送`Challenge`数据
服务端发送带有随机数的 `Challenge` 数据包,如下图所示:
获取固定偏移的`Challenge`字符串。
(2)发送带有`Cookie` + `Challenge`哈希值连接端将`Cookie` 和`Challenge`拼接在一起计算`MD5`值,如下图`Digest`
所示:
使用`MD5`算法计算`Cookie`和`Chall-enge`的哈希值。
(3)`Challenge` 响应包
如果含有的`Cookie`相同则发送带有内容的响应数据包:
0x04 erlang 节点命令执行
`erlang`分布式节点的命令执行语句如下:
os:cmd("id").
通过该语句可以在远程分布式节点执行系统命令,协议中的主要内容如下:
`erlang`分布式节点在执行命令时需要发送对应的控制指令:
执行的命令需要进行一层封装。
漏洞复现
编写EXP,验证命令执行:
小结
此次`Apache CouchDB`漏洞实际的利用使用的是在2017年曝光的`erlang`分布式RCE漏洞,`CouchDB`使用了`erlang`的分布式架构进行处理,在正常的配置使用过程中`erlang`分布式节点开放的端口是可以外部访问,并且在 `CouchDB`部署启动时内置了默认`Cookie` ,这就可以使用合法`Cookie`操作`erlang`内部分布式节点执行系统命令。