ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Redis未授权访问与提权攻击全解析:原理、检测与加固实战

Redis未授权访问与提权攻击全解析:原理、检测与加固实战 在安全评估和应急响应工作中我最常遇到的现象往往不是某个神秘的0day漏洞而是 Redis 未授权访问。很多团队把 Redis 当成单纯的缓存中间件觉得它藏在内网就是安全的结果一不留神6379 端口就直接成了攻击者进入内网的“免费门票”。而“Redis提权”这个词在红蓝对抗里出现的频率也越来越高——攻击者未必需要多高深的技术只要 Redis 配置稍有松懈就能拿下一台主机的高权限再以此作为跳板在内网横向渗透。今天我从防守方的视角出发把 Redis 提权的原理、攻击链、检测方法和加固方案完整拆解一遍。这篇内容适合安全工程师、运维同学也适合做开发但想了解中间件安全的读者哪怕你之前完全没接触过 Redis也能通过这篇文章看懂它为什么总是“翻车”。1. 为什么 Redis 会成为内网提权的“跳板”1.1 Redis 在内网部署太常见暴露面天然就大Redis 本身是一款高性能的键值存储数据库因为读写速度快、语义简单被大量用来做缓存、分布式锁、排行榜、会话存储等场景。几乎每个中大规模系统的技术栈里都会出现 Redis 的身影而且数量往往不止一台业务缓存一主多从、集群架构几十个节点、环境上还要分 dev、test、prod加起来就是一笔不小的资产。对于攻击者来说Redis 的“价值”在于它的身份很特殊它通常运行在高权限用户下而且默认配置并不强制开启密码认证。很多公司为了管理方便直接把 Redis 部署在 Web/应用服务器上或者用同一个账号跑多个服务。这样一来一旦 Redis 被攻破攻击者拿到的可能不只是一个数据库控制权而是整台服务器的高权限执行入口。这也是“Redis提权”这个说法在安全圈里流传度越来越高的根本原因。1.2 “提权”的本质是权限边界被突破先明确一个概念Redis 本身不是一个漏洞软件它不会主动去攻击别人。但攻击者利用 Redis 的配置缺陷、功能特性和运行权限把自己从“只能操作数据库”提升到“能在操作系统里执行命令”这个过程就是提权。换句话说Redis 的很多功能在正常情况下是为了方便开发比如持久化到磁盘、加载模块、复制数据等可一旦落入攻击者手里这些“正常功能”就全变成了攻击工具。最核心的一点是Redis 是以操作系统的某个用户身份运行的而这个用户往往拥有高权限。如果 Redis 以 root 启动攻击者通过 Redis 获得代码执行能力后天然就是 root 权限根本不需要再费劲去提权。如果 Redis 以 redis 用户运行攻击者有了代码执行权限后还需要借助内核漏洞、SUID 文件、sudo 配置错误等方式把权限升到 root。所以我们说的“Redis提权”实际是两层含义一层是 Redis 到操作系统命令执行的“横跳”另一层是操作系统普通权限到 root/system 权限的“爬升”。1.3 默认配置和安全习惯的双重缺失Redis 之所以成为内网提权的重灾区很大程度上要“归功”于几个惯性操作Redis 安装后bind默认可能是 127.0.0.1有人为了局域网访问改成0.0.0.0或内网网段但忘了加防火墙限制。requirepass始终不设置认为内网不可信这句老话恰恰就是最大的漏洞来源。protected-mode被改成no或者配置顺序有误导致保护模式没生效。运维为了方便直接用 root 用户启动 Redis 进程还理直气壮地说“没人能连上来”。这些配置单独看都不致命但叠在一起后Redis 就像一个开着门、站在内网广场上的保险库谁路过都能翻两下。而“内网提权”这个场景里Redis 往往是攻击者发的第一张牌也是最容易打出的那张牌。2. Redis 未授权访问的利用原理与攻击链2.1 未授权访问是怎么产生的未授权访问简单说就是任何人都可以连上 Redis 并执行命令无需密码。正常情况下Redis 提供了两种基本认证方式一是通过requirepass设置管理员密码二是通过protected-mode限制外部访问。只要开了其中一个且配置正确攻击者就不能轻易得手。问题出在Redis 的某些配置需要重启才能生效而有些命令可以动态修改。比如攻击者连上 Redis 后执行CONFIG GET requirepass一看是空值就知道可以直接操作了。更麻烦的是Redis 默认有CONFIG SET命令允许运行时修改运行参数这就给攻击者提供了很大的操作空间。我见过不少实际案例Redis 进程在 root 下运行绑定了内网 IP并且没有密码结果攻击者扫描内网时发现 6379端口开放直接从数据库一路打到了主机权限。整个过程不到五分钟甚至没有使用任何公开的漏洞。2.2 四种常见的 Redis 提权利用方式原理与排查思路站在防守方角度我们需要知道攻击者通常会走哪几条路才能去检查和保护。这里梳理四种最常见的利用方式不涉及具体攻击载荷只讲原理和痕迹特征。方式一利用dir和dbfilename写文件Redis 持久化默认会把数据保存到磁盘上的 RDB 文件路径由dir和dbfilename两个配置项决定。攻击者会先把dir切换到目标目录比如 Web 服务的根目录或临时目录然后把包含恶意内容的键值写入 Redis最后执行SAVE或BGSAVE触发持久化恶意内容就被写进文件。如果写在 Web 目录下就可能形成一个 WebShell如果写进了用户的 SSH 目录就可能变成授权后的公钥文件如果写进计划任务目录就可能形成定时执行的后门。这个手法的核心在于Redis 进程对目标目录有写权限同时攻击者知道目录的绝对路径。方式二写入 SSH 公钥实现免密登录很多 Linux 服务器开启了 SSH 服务允许 root 远程登录。如果 Redis 进程权限足够高例如 root攻击者可以在 Redis 中构造一条 SSH 公钥内容通过dir和dbfilename把它写到/root/.ssh/authorized_keys文件里然后直接使用对应的私钥登录服务器。这种方式的标志性排查点非常明显/root/.ssh/authorized_keys文件里多了一条不认识的公钥或者文件权限和属主变得异常。但在攻防演练中很多防守方并不会去主动检查这个目录等到攻击者已经通过 SSH 登录已经太晚了。方式三写计划任务实现命令执行对于运行 Linux 的系统攻击者会尝试把恶意命令写进 crontab 目录比如/var/spool/cron/root或/etc/cron.d/然后定时执行。这样即使在当前会话断开后攻击者依然能周期性获得权限。在 CentOS 等系统中cron 服务读取文件时的格式要求和权限检查相对宽松因此这种利用方式很常见。防守方要留意/var/spool/cron/下有没有异常用户文件以及/etc/cron.d/里有没有刚刚生成的可疑脚本。方式四主从复制加载恶意模块Redis 4.0 引入模块机制允许神器加载 .so 文件扩展功能。攻击者可以搭建一个自己的 Redis 实例作为主节点然后让目标 Redis 通过REPLICAOF命令成为自己的从节点再向主节点请求加载恶意模块最终在目标系统上实现代码执行。这种方式在 Redis 4.x/5.x 版本中都比较有效而且攻击链更隐蔽因为直接写文件的方式各有约束而模块加载可以绕过很多规则。防守方需要检查 Redis 日志中是否出现异常的MODULE LOAD或REPLICAOF操作并监控 Redis 进程加载的模块文件。2.3 攻击链的整体视图把上面几种利用方式串起来看典型的 Redis 提权攻击链一般是探测内网中未授权访问的 Redis 实例常见于扫描 6379 端口。连接 Redis执行INFO、CONFIG GET dir、CONFIG GET requirepass等命令探清环境和权限。根据 Redis 进程权限、系统类型、目录可行性选择一种或多种利用方式。获得命令执行或文件写入能力随后将权限提升到 root/system。植入持久化后门并以内网扫描、密码抓取、代理转发等方式进行横向移动。这个链条每一环都有对应的检测点防守方只要能在其中一环拦截住就能有效降低风险。比如及时升级版本、配置强密码、限制命令、监控持久化文件都会让攻击者无路可走。3. 内网场景下的提权路径与联动利用3.1 从 Redis 到主机权限中间发生了什么在实际内网渗透中攻击者拿到 Redis 后会先验证自己能做什么。最基础的他们可以读CONFIG GET dir、CONFIG GET dbfilename、CONFIG GET logfile等了解当前持久化文件在哪个目录、Redis 日志在哪个路径从而判断 Redis 进程到底属于哪个用户、系统上是否存在 Web 服务、SSH 是否开启等信息。权限判断很关键如果dir指向/var/lib/redis并且文件属主是 redis 用户那说明 Redis 是低权限运行攻击者写文件的目标就受限如果dir指向/root或/var/www/html且属主是 root那说明 Redis 很可能以 root 运行攻击者一旦获得写文件能力就相当于直接拿到了 root 权限。这也是为什么“低权限运行 Redis”会在加固建议里被反复强调。3.2 内网横向移动的典型路径Redis 提权成功之后攻击者通常不会只待在这一台机器上。内网里往往有成百上千台机器他们会把当前主机当作“根据地”然后开展横向移动常见的手段包括扫描内网存活 IP 和开放端口寻找更多未授权 Redis、弱口令 SSH、开放数据库等服务。抓取本机内存中的密码、浏览器或登录工具中的保存口令、配置文件里的数据库账号尝试复用口令。利用 Linux 系统的密码 hash 或 SSH 密钥跳到其他运维管理的机器。在内网建立代理或端口转发形成一条稳定的隧道方便后续进出内网。这些动作在没有纵深防御的环境里很难被阻止。特别是 Redis 大量部署在测试环境和办公网内一旦一个开发测试机器被攻破攻击者就能沿着开发运维链路摸到生产网络。3.3 为什么说 Redis 是“内网提权”的高频入口内网提权这个词这些年越提越频繁和攻击者视角的转变有很大关系。早期大家关注的焦点是 Web 漏洞、SQL 注入但随着 Web 防护体系的增强攻击者开始寻找边界没那么明显的中间件和基础组件。Redis 就是这样一个组件它不像 Web 服务那样暴露在公网也常常没有 WAF 防火墙的保护但它一旦失守却能直接提供内网主机的入口。另外Redis 相关的攻击手段大多不需要特别的工具依赖只要能通过 TCP 连接用 Redis 自己的命令就能完成大部分操作。这让它在攻击者眼里性价比极高。反过来作为防守方也必须对这类“低频、高影响”的入口有足够的感知力。4. 快速自查5 个命令定位 Redis 提权风险与其等出事了再焦虑不如在日常巡检里就把 Redis 的险情摸清楚。下面这 5 个检查命令是我在安全评估中经常用的不需要太多额外工具一条条跑下来基本能判断当前 Redis 是否处于高风险状态。检查项命令示例判断标准是否可未授权访问redis-cli -h IP ping返回 PONG 说明服务端可连接且无需密码认证配置是否为空CONFIG GET requirepass返回空字符串即为高危监听地址是否过宽CONFIG GET bind若为0.0.0.0或内网全段风险升高保护模式是否开启CONFIG GET protected-modeno或注释掉都算高危进程权限是否过高ps -ef | grep redis-server进程用户为 root 或 system 即为高危在实际检查时还可以追加两条查看关键目录的命令确认有没有已经被写入恶意文件ls -la /root/.ssh/authorized_keys ls -la /var/spool/cron/如果一个 Redis 同时满足不需要密码、绑定所有地址、保护模式关闭、进程以 root 运行那基本可以断定只要这台机器在内网可达攻击者随时可以提权到 root。这时候唯一的处理方式就是立刻切断网络访问然后按下一节的加固方案执行修复。5. 企业级加固方案让 Redis 无“权”可利用5.1 配置层面把默认的“随意访问”关紧最直接有效的做法是在 Redis 配置文件redis.conf中把认证、监听和保护模式三件事一次性做好# 开启保护模式 protected-mode yes # 仅监听需要的地址建议绑定回环或内网专用网段 bind 127.0.0.1 192.168.10.10 # 设置强密码不要用 admin/123456 这类弱口令 requirepass 你的强随机密码 # 关闭所有外部来源的危险命令 rename-command CONFIG 注意rename-command把 CONFIG 禁掉后虽然会影响运维人员动态调整配置但对很多内部业务来说它并不是必须的。如果实在需要保留 CONFIG 命令建议仅允许某个特定受控网络地址访问并配置好密码认证。另外rename-command对已经不在内存中的配置项不生效需要在配置文件里改好之后再重启 Redis才能彻底生效。5.2 系统层面弱化 Redis 进程的权限边界配置只是第一步进程权限和文件系统权限才是关键。建议把 Redis 放到独立的低权限用户下运行比如创建一个专门用于 Redis 的redis用户并把数据目录、日志目录、配置文件都设置为该用户所有。这样即使攻击者利用了 Redis获得的也只是普通用户的执行权限后续要提权到 root 还需要面对其他门槛。如果你使用 Docker 运行 Redis可以进一步使用只读文件系统挂载、禁止特权模式、限制 Linux capabilities 等方式让容器内的 Redis 无法影响宿主机。容器虽不是安全隔离的银弹但能显著提高攻击者利用成本。还需要注意一点即使 Redis 以 redis 用户运行如果该用户对 Web 目录或 SSH 目录有写权限同样可以被利用。所以还要检查 Redis 用户的目录写权限范围尽量做到最小化授权。尤其不要把 Redis 的数据目录直接指向/var/www/html或用户家目录。5.3 网络层面让 6379 不暴露给无关主机Redis 不应该直接暴露在所有内网主机可达的网段里。以下几条是实践过比较有效的网络策略使用防火墙或安全组限制 6379 端口只能被访问方 IP 访问。比如业务应用 IP、管理机 IP其它全部拒绝。如果业务上只需要本机访问 Redis直接bind 127.0.0.1是最省心的方案其他人连 TCP 包都送不进来。不建议把 Redis 端口映射到公网。如果团队有远程开发需求走 SSH 隧道或堡垒机访问即可。定期使用端口扫描工具检查内网是否存在异常开放的 6379/6380 端口及时发现裸奔服务。5.4 监控层面发现可疑命令要立刻告警Redis 的命令日志通常默认不开启但为了安全最好打开。在配置里设置loglevel notice并让日志采集工作收集 Redis 日志再针对几个高危操作配置告警包括但不限于CONFIG SET dir/CONFIG SET dbfilenameSAVE/BGSAVE在非正常时间段执行REPLICAOF或SLAVEOFMODULE LOAD密码验证失败次数过多如果日志显示有人在执行这些命令大概率是在尝试利用 Redis 提权。告警只是第一步还要有响应流程例如及时断开该 Redis 的网络、备份日志、拉取当前进程信息、检查持久化文件是否被篡改等。安全加固永远不是改一个配置就结束而是配置、监控、响应三者配合。5.5 版本升级别在旧版本上浪费时间Redis 官方持续修复安全漏洞比如著名的 Lua 沙盒绕过、模块加载相关的代码执行漏洞等。老版本虽然在业务上稳定但在攻击者眼里内置漏洞可能都是现成的武器。建议把生产环境的 Redis 升级到官方维护的最新稳定版至少也要选择仍处于安全维护期内的版本。升级前要在测试环境做充分的兼容性验证尤其是主从复制、持久化、连接池等核心场景。别把安全修复和业务稳定性对立起来现代 Redis 的新版本在高性能方面并不逊色反而带来了更好的安全特性和可观测性。6. 常见问题与误区排查6.1 设了 requirepass 就万事大吉不少团队初始的加固方案就是加一个密码而且用的还是项目名年份这类简单组合。可问题是内网攻击者如果已经拿下一台机器很可能通过抓包、读取配置文件、翻历史命令等方式拿到这个密码。换句话说密码只是第一道门槛不是唯一门槛。更稳妥的做法是把密码认证、网络限制、命令降权三者结合起来。另外Redis 的密码也不是越复杂越好实用做法是生成一串随机的长字符串集中保存在密钥管理系统或配置中心里避免硬编码在应用配置中尤其是不能提交到 Git 仓库。6.2 protected-mode 开启后内网还是暴露protected-mode yes不是万金油。它的本质是当 Redis 没有配置密码且没有显式绑定地址时只允许本机回环地址访问。但如果运维已经编译了bind 192.168.x.x即使protected-mode yes从其它内网主机依然可以连上来。因为保护模式主要作用于默认绑定场景显式绑定后保护模式的实际约束会弱化。所以你在 Redis 里看到protected-mode yes时别高兴太早还要再确认bind和requirepass两个值。这三个配置项必须一起看才能判断暴露面。6.3 把 CONFIG 命令禁掉就万无一失了吗对很多运维来说禁用CONFIG确实能挡住一大波利用手段比如修改dir和dbfilename的经典写 shell 方式。但要注意攻击者如果拿到了 Redis 连接权限即使没有CONFIG命令也可能利用MODULE LOAD、主从复制、Lua脚本等方式尝试执行代码。所以rename-command只是补漏不能替代强密码和低权限用户。在实际评估中我会同时检查 Redis 有没有加载过异常的模块文件有没有成为某个可疑主节点的从机等。这些痕迹不会出现在 Web 日志里只有长期保留 Redis 日志才能追查到。6.4 Redis 被提权之后清理 RDB 文件就恢复了吗很多应急响应的“常规操作”是删掉 RDB 文件中残留的恶意键值重启 Redis觉得这样攻击者就进不来了。但现实是攻击者一旦获得过 root 权限可能在计划任务、SSH 公钥、系统服务、定时脚本等多个位置留下了后门甚至替换了系统命令。只清洗 Redis 相关的痕迹远远不够。正确的应急流程应当是先断网隔离然后连同系统日志、Redis 日志、进程列表、网络连接、文件系统时间戳一起取证排查确认所有后门位置再从干净备份恢复或重装系统最后修改所有相关密码和密钥。Redis 本身的数据文件往往不是唯一受灾点。6.5 内网 Redis 数量太多如何做批量巡检如果内网设备数量比较大可以写一个简单的脚本批量探测常见 Redis 端口并对未授权访问、绑定地址、requirepass 状态、进程权限等字段进行扫描和汇总。脚本逻辑并不复杂用 Python 的 socket 库就能实现import socket ip 目标IP port 6379 s socket.socket() s.settimeout(3) try: s.connect((ip, port)) s.send(bPING\r\n) data s.recv(100) if bPONG in data: print(f{ip}:{port} Redis 未授权访问) except Exception: pass finally: s.close()这只是最小验证片段真正的批量巡检还要结合 CONFIG GET 命令验证 requirepass 等配置。建议把巡检做成周期性任务并纳入企业安全管理平台由平台统一展示风险和派发工单这样才能避免“巡检一时爽过后没人管”的情况。6.6 遇到疑似 Redis 提权攻击该报警还是断网第一时间应该“断网隔离”而不是“继续观察”。只要确认 Redis 存在未授权访问最好的处理方式就是把该主机的网络连接先断掉再用只读方式备份日志和数据避免攻击者销毁证据。等应急人员介入后再根据取证结果判断是否扩容攻击路径、是否已横向渗透到其它主机。在实际攻防演练里我发现很多防守方会想先看攻击者做了什么再决定怎么处置。但大部分情况下攻击者保持连接的时间窗口非常短反应慢半拍就可能导致整个内网被翻个底朝天。快速断网保留现场是可控且稳妥的。写在最后我在实际安全运营中有一个很深的体会Redis 安全问题绝大多数不是技术门槛造成的而是“配置基线”没有立起来。只要把密码认证、地址绑定、保护模式、进程权限、高危命令禁用、日志告警这六件事做扎实绝大部分 Redis 提权尝试都会被挡在第一步。日常运维中大家习惯把大量精力花在业务可用性上但安全加固往往只需要几次版本发布就能顺手完成。如果你负责的系统里正好有 Redis 服务建议今天就去检查一下requirepass、bind和运行用户也许一次小小的调整就能避免一次内网失陷。
返回列表