zookeeper未授权访问渗透测试及修复方法

1,125 阅读5分钟

一、四字命令

1. 四字命令

用户在客户端可以通过 telnet 或 nc 向 ZooKeeper 提交四字命令,来探测四字命令是否开启

  • conf命令
    输出相关服务配置的详细信息,端口、数据路径、日志路径、session 超时时间,最大连接数等。
echo conf | nc xx.xx.xx.xx 2181
  • cons命令
    列出所有连接到当前服务器的客户端/会话的详细信息
echo cons | nc xx.xx.xx.xx 2181 | more
  • dump命令
    输出未处理的会话和临时节点,leader 节点有效。
echo dump | nc xx.xx.xx.xx 2181 | more
  • envi命令
    输出服务器的详细信息。
root@kali:~# echo envi | nc xx.xx.xx.xx 2181
[root@localhost zookeeper-3.4.10]# echo stat |ncat 127.0.0.1 2181
Zookeeper version: 3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT
Clients:
 /127.0.0.1:34004[0](queued=0,recved=1,sent=0)

Latency min/avg/max: 0/0/0
Received: 5
Sent: 4
Connections: 1
Outstanding: 0
Zxid: 0x0
Mode: standalone
Node count: 4

[root@localhost zookeeper-3.4.10]# echo envi |ncat 127.0.0.1 2181
Environment:
zookeeper.version=3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT
host.name=localhost
java.version=1.8.0_05
java.vendor=Oracle Corporation
java.home=/zywa/jdk/jre
java.class.path=/zywa/zookeeper-3.4.10/bin/../build/classes:/zywa/zookeeper-3.4.10/bin/../build/lib/*.jar:/zywa/zookeeper-3.4.10/bin/../lib/slf4j-log4j12-1.6.1.jar:/zywa/zookeeper-3.4.10/bin/../lib/slf4j-api-1.6.1.jar:/zywa/zookeeper-3.4.10/bin/../lib/netty-3.10.5.Final.jar:/zywa/zookeeper-3.4.10/bin/../lib/log4j-1.2.16.jar:/zywa/zookeeper-3.4.10/bin/../lib/jline-0.9.94.jar:/zywa/zookeeper-3.4.10/bin/../zookeeper-3.4.10.jar:/zywa/zookeeper-3.4.10/bin/../src/java/lib/*.jar:/zywa/zookeeper-3.4.10/bin/../conf:
java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.io.tmpdir=/tmp
java.compiler=<NA>
os.name=Linux
os.arch=amd64
os.version=3.10.0-229.el7.x86_64
user.name=root
user.home=/root
user.dir=/zywa/zookeeper-3.4.10

2. 关闭四字命令

四字白名单默认是开启的

#默认
4lw.commands.whitelist=*

关闭四字白名单

4lw.commands.whitelist=

测试获取服务信息

[root@localhost zookeeper-3.4.10]# echo stat |ncat 127.0.0.1 2181
stat is not executed because it is not in the whitelist.
[root@localhost zookeeper-3.4.10]# echo envi |ncat 127.0.0.1 2181
envi is not executed because it is not in the whitelist.

开启部分四字命令

4lw.commands.whitelist=envi

测试获取服务信息

[root@localhost zookeeper-3.4.10]# echo stat |ncat 127.0.0.1 2181
stat is not executed because it is not in the whitelist.
[root@localhost zookeeper-3.4.10]# echo envi |ncat 127.0.0.1 2181
Environment:
zookeeper.version=3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT
host.name=localhost
java.version=1.8.0_05
java.vendor=Oracle Corporation
java.home=/zywa/jdk/jre
java.class.path=/zywa/zookeeper-3.4.10/bin/../build/classes:/zywa/zookeeper-3.4.10/bin/../build/lib/*.jar:/zywa/zookeeper-3.4.10/bin/../lib/slf4j-log4j12-1.6.1.jar:/zywa/zookeeper-3.4.10/bin/../lib/slf4j-api-1.6.1.jar:/zywa/zookeeper-3.4.10/bin/../lib/netty-3.10.5.Final.jar:/zywa/zookeeper-3.4.10/bin/../lib/log4j-1.2.16.jar:/zywa/zookeeper-3.4.10/bin/../lib/jline-0.9.94.jar:/zywa/zookeeper-3.4.10/bin/../zookeeper-3.4.10.jar:/zywa/zookeeper-3.4.10/bin/../src/java/lib/*.jar:/zywa/zookeeper-3.4.10/bin/../conf:
java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.io.tmpdir=/tmp
java.compiler=<NA>
os.name=Linux
os.arch=amd64
os.version=3.10.0-229.el7.x86_64
user.name=root
user.home=/root
user.dir=/zywa/zookeeper-3.4.10

所有的四字命令

4lw.commands.whitelist=conf, cons, crst, dirs, dump, envi, gtmk, ruok, stmk, srst, srvr, stat, wchc, wchp, wchs, mntr, isro, telnet close

二、登录Zookeeper,对节点进行查看和操作

1. 登录zk

./zkCli.sh -server x.x.x.x:2181
ls /
# 输出目录就是 连接成功
# 输出 Authentication is not valid : /   就是没有权限

2. 查看和操作

查看集群节点状态:

zkServer.sh status

主要有2个命令:ls 和 get
(1) 查看所有节点: ls /
在这里插入图片描述
(2) 查看forever节点下的内容: ls /forever
在这里插入图片描述 (3) 查看forever节点的信息: get /forever
在这里插入图片描述

三、修复方法

步骤一 关闭四字命令

ZooKeeper3.4.6支持某些特定的四字命令与其的交互。它们大多是查询命令,但也有重启zk之类的命令,四字命令可以用来获取、重启 ZooKeeper 服务的当前状态及相关信息。用户在客户端可以通过 telnet 或 nc 向 ZooKeeper 提交相应的命令。
从运维的角度看,这个功能很方便,但是从安全角度来看,就需要关闭这些特定的四字命令来确保安全了,修复方式为:升级zookeeper>=3.5.3(旧版本不能给四字命令加白名单哦,升级请自行评估风险),然后设置四字命令白名单、关闭http使用四字命令工具即可,示范如下:

/home/work/software/apache-zookeeper-3.6.1-bin/conf/zoo.cfg
 
#限制tcp使用4字命令的白名单,添加了白名单的四字命令才能执行 (升级到高版本以后默认的白名单4字命令里只有srvr这一个,请按需增加)
4lw.commands.whitelist=stat, srvr 
 
#是否开启jetty服务允许使用http方式执行4字命令,默认为true开启,false为关闭(升级到高版本以后默认开启http方式)
admin.enableServer=false
  • 如果真的有需求要开启http功能
    如果有需求要开启http功能,可以修改根路径名称,改成20位的随机字符
#修改http四字命令的根路径,默认为/commands
admin.commandURL=/2cgyS2rQGW4yzjJlXV0k

访问路径就会变成:curl http://10.39.27.200:8080/2cgyS2rQGW4yzjJlXV0k/envi

设置成功之后 ,继续做修复步骤二;

步骤二 关闭未授权访问

auth ACL授权策略 或 digest Acl授权策略(用户名和密码认证)

image.png 图片中的解决方式都是通过设置认证用户,但是仅仅设置用户和密码的话集群(kafka集群)会出现问题,所以单单上面的解决方式是不行的。可以通过限制IP只使集群内相关主机能访问2181端口

ip ACL授权策略:添加IP白名单对连接ZK的客户端进行限制

通过IP白名单对连接ZK的客户端进行限制,比较简单,只需要收集一下IP即可。因zookeeper不支持节点间权限的继承,所以需要对关键节点进行权限控制。
因为zookeeper会默认启动这几个具有world和cdrwa权限的znode,“/” "/zookeeper" "/zookeeper/config"和"/zookeeper/quota"
这里之所以设置完zookeeper节点还要设置quota 是因为znode的ACL是相互独立的。也就是说,任意不同节点可以用不同的acl列表,互不影响,并且ACL是不可被继承的。
这里对“/”、“/zookeeper”节点进行限制,示范如下:

./zkCli.sh -server ip:port
setAcl / ip:xx.xx.xx.152:cdrwa,ip:xx.xx.xx.151:cdrwa,ip:xx.xx.xx.156:cdrwa,ip:xx.xx.xx.155:cdrwa,ip:xx.xx.xx.150:cdrwa,ip:xx.xx.xx.149:cdrwa
setAcl /zookeeper ip:xx.xx.xx.152:cdrwa,ip:xx.xx.xx.151:cdrwa,ip:xx.xx.xx.156:cdrwa,ip:xx.xx.xx.155:cdrwa,ip:xx.xx.xx.150:cdrwa,ip:xx.xx.xx.149:cdrwa

设置完setAcl,然后用getAcl 查看一下是否配置成功.

getAcl /zookeeper

或者更简单的方式:配置防火墙策略

使集群内机器才能访问2181端口,具体命令如下(配置防火墙需谨慎):

iptables -A INPUT -p tcp -m iprange --src-range 1.1.1.1-1.1.1.25 --dport 2181 -j ACCEPT
iptables -A INPUT -p tcp --dport 2181 -j DROP

service iptables save
service iptables restart
chkconfig iptables on

参考文章

Zookeeper 四字白名单防止信息泄露
ZooKeeper未授权访问漏洞确认与修复