Redis Lua 远程代码执行漏洞(CVE-2024-46981)
一、漏洞描述RedisRemote Dictionary Server是美国Redis公司的一套开源的使用ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值Key-Value存储数据库并提供多种语言的API。扫描发现 Redis存在Lua脚本执行远程代码漏洞这个漏洞是由于Redis中Lua脚本功能被滥用而产生的经过身份验证的攻击者可构造恶意的Lua脚本控制垃圾回收器进而可能在服务器上执行任意代码。另外同时还曝出redis拒绝服务漏洞它是畸形ACL选择器引发的拒绝服务漏洞拥有足够权限的认证用户创建一个畸形的访问控制列表ACL选择器当访问这个畸形选择器时服务器就会崩溃从未进入拒绝服务状态漏洞编号Redis 拒绝服务漏洞(CVE-2024-51741)、远程代码执行漏洞(CVE-2024-46981)危机等级高危利用条件一定权限的用户影响版本CVE-2024-51741影响版本Redis7.0.0及以上版本CVE-2024-46981影响版本所有开启了Lua脚本功能的Redis版本处置建议(CVE-2024-51741)升级到7.2.7和7.4.2版本(CVE-2024-46981)升级到6.2.x、7.2.x和7.4.x版本。缓解措施(CVE-2024-46981)可通过修改ACL规则阻止“EVAL”和“EVALSHA”命令来禁用Lua脚本。安全加固确保只有受信任的用户才能在Redis服务器上执行特权命令。关联资源Redis7.4文档、Redis7.4安装文档、Redis下载地址、windows版本下载二、漏洞修复2.1、升级redis#现场7.0.4需升级到74redis-cliping#验证redis工作正常PONG redis-cli CONFIG GETdir#确认redis工作目录即 Redis 持久化文件如 RDB 快照、AOF 日志的存储路径。#查看配置文件确认pidfile /var/run/redis_6379.pid dbfilename dump.rdb#推荐配置requirepass YourStrongPassword123!loglevel warning高性能文件体积小,可能丢失最后一次快照后的数据save9001# 900秒15分钟内至少1个key变更则触发快照save30010# 300秒5分钟内至少10个key变更save6010000# 60秒内至少10000个key变更dir/var/lib/redis# 直接指定持久化文件存储目录dbfilename dump.rdb# RDB文件名AOF数据丢失风险低最多丢1秒数据文件较大写入性能略低量不大几乎可忽略 appendonlyyes# 启用AOFappendfilenameappendonly.aofappendfsync everysec# 每秒同步平衡性能与安全dir/var/lib/redis# AOF文件存储目录aof-rewrite-incremental-fsyncyes混合持久化Redis4.0aof-use-rdb-preambleyes# AOF文件包含RDB头部兼顾恢复速度和数据安全#关停redis-cli bgSAVE#保存数据它会创建一个RDB或aof 文件下次恢复启动再重新加载redis-clishutdown#关停#备份cp-r/path/to/redis-data-dir/ /path/to/backup/#备份#升级wget-c--show-progress https://download.redis.io/releases/redis-7.4.5.tar.gztar-xzvfredis-7.4.5.tar.gzmakeBUILD_TLSyes#依赖libssl-devsudocputils/redis_init_script /etc/init.d/redis_6379# 0755权限sudovi/etc/init.d/redis_6379#确定端口、pid file path、REDISPORT6379EXEC/usr/local/redis-7.4.5/src/redis-serverCLIEXEC/usr/local/redis-7.4.5/redis-cliPIDFILE/var/run/redis_${REDISPORT}.pidCONF/etc/redis/$(REDISPORT.conf sudo update-rc.d redis_6379 defaults #如果你想在所有 runlevels 下运行redis执行它 #升级后重启redis验证数据恢复 sudo /etc/init.d/redis_6379 start #启动 redis-cli -a YourStrongPassword123! #或AUTH YourStrongPassword123! redis-cli INFO persistence #检查持久化状态 # Persistence loading:0 # 是否正在加载持久化文件0否1是重启后加载持久化文件时为 1正常运行时应为 0 rdb_changes_since_last_save:15 # 自上次RDB保存后的key变更次数 rdb_bgsave_in_progress:0 # 后台RDB保存是否进行中0否1是若长期为 1可能持久化卡住检查磁盘I/O或内存 rdb_last_save_time:1630000000 # 最后一次成功RDB保存的Unix时间戳 rdb_last_bgsave_status:ok # 最后一次RDB保存状态ok/fail若为 fail检查日志/var/log/redis/redis-server.log rdb_last_bgsave_time_sec:1 # 最后一次RDB保存耗时秒若大于5s甚至耗时过长可能数据量过大或磁盘慢 rdb_current_bgsave_time_sec:-1 # 当前RDB保存已耗时-1表示未运行 aof_enabled:1 # AOF是否启用0关闭1开启 aof_rewrite_in_progress:0 # AOF重写是否进行中0否1是 aof_rewrite_scheduled:0 # 是否计划下次AOF重写0否1是 aof_last_rewrite_time_sec:2 # 最后一次AOF重写耗时秒 aof_current_rewrite_time_sec:-1 # 当前AOF重写已耗时-1表示未运行 aof_last_bgrewrite_status:ok # 最后一次AOF重写状态ok/fail若为 fail检查磁盘空间或权限 aof_last_write_status:ok # 最后一次AOF写入状态ok/fail aof_current_size:123456 # 当前AOF文件大小字节若远大于 aof_base_size需手动触发 BGREWRITEAOF aof_base_size:100000 # 最后一次重写时的AOF基础大小字节 aof_pending_rewrite:0 # 是否有AOF重写等待触发0否1是若为 1表示AOF需重写但未触发 aof_buffer_length:0 # AOF缓冲区大小字节 aof_rewrite_buffer_length:0 # AOF重写缓冲区大小字节 aof_pending_bio_fsync:0 # 等待后台fsync的任务数 aof_delayed_fsync:0 # 延迟的fsync次数 #或 redis-cli INFO persistence | grep -E rdb_last_bgsave_status|aof_last_write_status#正常输出 rdb_last_bgsave_status:ok aof_last_write_status:ok redis-cli INFO persistence | grep -E aof_current_size|aof_base_size #若 aof_current_size / aof_base_size 2建议手动触发重写 redis-cli BGREWRITEAOF redis-cli INFO server | grep redis_version #ACL 细粒度控制Redis 6.0 # 创建用户并限制权限禁用高危命令如 FLUSHDB、CONFIG ACL SETUSER alice on herpassword ~* all -dangerous ACL LIST # 显示所有用户权限 # 创建用户 secureuser允许大部分命令但禁用 EVAL/EVALSHA ACL SETUSER secureuser on StrongPass123 ~* all -eval -evalsha # 验证规则 ACL GETUSER secureuser #永久生效写入配置文件 user secureuser on StrongPass123 ~* all -eval -evalsha #配置推荐 user default off # 禁用默认用户 user admin on AdminPass456 ~* all # 管理员全权限 user appuser on AppPass789 ~* read -admin -eval -evalsha # 应用用户只读禁用脚本 #测试ACL redis-cli -u redis://secureuser:StrongPass123localhost 127.0.0.1:6379 EVAL return 1 0 # 应返回 (error) NOPERM Permission denied#监控检查脚本通过 Prometheus Grafana 监控 aof_current_size#!/bin/bashREDIS_PASSyourpasswordSTATS$(redis-cli-a$REDIS_PASS INFO persistence)check_status(){echo$STATS|grep$1|awk-F:{print $2}}rdb_status$(check_statusrdb_last_bgsave_status)aof_status$(check_statusaof_last_write_status)if[$rdb_status!ok]||[$aof_status!ok];thenechoCRITICAL: Persistence error! RDB:$rdb_status, AOF:$aof_statusexit1elseechoOK: Persistence healthyfi2.2、缓解措施3、其他漏洞3.1、Redis Lua脚本远程代码执行漏洞(CVE-2025-49844)2025年10月 Redis 官方发布安全通告披露了redis存在远程代码执行严重经过认证的攻击者可以利用该漏洞通过Lua脚本触发释放后重用执行任意代码导致服务器失陷。Redis 作为一个使用 ANSI C 语言编写开源的服务组件、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库并提供多种语言的 API使用广泛根据官方描述在 Redis 的 Lua 脚本引擎的垃圾回收机制中存在 Use After Free 漏洞经过身份验证的远程攻击者可通过构造特殊的 Lua 脚本触发从而最终可能导致远程任意代码的执行等所有使用 Lua 脚本的 Redis 都受该漏洞影响。漏洞编号CVE-2025-49844漏洞威胁等级严重。影响范围Redis 6.2.207.2.0 ≤ Redis 7.2.117.4.0 ≤ Redis 7.4.68.0.0 ≤ Redis 8.0.48.2.0 ≤ Redis 8.2.2检测是否受影响redis-cli EVAL return test 0 后执行INFO SERVER修复 2025年10月3日由Redis 官方已发布修复版本可升级到redis8.2.2及以上或8.4或 禁用 Lua 脚本–disable-lua最新版为 Reids 8.6.3。缓解措施 阻止用户执行 Lua 脚本通过访问控制列表同时限制普通用户执行 EVAL 和 EVALSHA 命令进行缓解。参考如下#编辑配置文件 /etc/redis/redis.conf#启用认证requirepass your_strong_password_here#限制网络访问bind127.0.0.1 ::1 protected-modeyes#禁用危险命令rename-command FLUSHDBrename-command FLUSHALLrename-command CONFIGrename-command EVALrename-command EVALSHA#开启日志loglevel notice logfile /var/log/redis/redis-server.log升级更多参看独立版升级不建议直接跨大版本升级涉及数据持久化的需注意停用前需前数据落盘redis-server--version#查看redis版本redis-cli info server|grepredis_version#依赖更新更多参见https://github.com/redis/redisapt-getupdateapt-getinstall-ysudosudoapt-getinstall-y--no-install-recommends ca-certificateswgetdpkg-dev gcc g libc6-dev libssl-devmakegitcmake python3 python3-pip python3-venv python3-devunziprsyncclang automake autoconf libtoolcd/usr/srcwget-Oredis-8.6.3.tar.gz https://github.com/redis/redis/archive/refs/tags/8.6.3.tar.gztarxvf redis-version.tar.gzcd/usr/src/redis-version#编译前配置环境变量exportSTD-pedantic -DREDIS_STATIC -stdc99WARN-Wall -Wno-missing-field-initializersOPT-O2exportFINAL_CFLAGS${STD}${WARN}${OPT}-g -ggdb -I../deps/hiredis -I../deps/linenoise -I../deps/lua/src -I../deps/hdr_histogram -DUSE_JEMALLOC -I../deps/jemalloc/includeexportFINAL_LDFLAGS-g -ggdb -rdynamicexportBUILD_TLSyesBUILD_WITH_MODULESyesINSTALL_RUST_TOOLCHAINyesDISABLE_WERRORSyesMALLOCjemallocmake-j$(nproc)all#如遇到 jemalloc/jemalloc.h: No such file or directory 类错误说明你的系统缺少jemalloc的开发库安装libjemalloc-dev或jemalloc-develHint: Its a good idea to run maketest ;) make[1]: 离开目录“/home/ygcg/redis-8.6.3/src” make[1]: 进入目录“/home/ygcg/redis-8.6.3/modules” for dir in redisjson redistimeseries redisbloom redisearch; do make -C $dir get_source; done make[2]: 进入目录“/home/ygcg/redis-8.6.3/modules” make[2]: 警告: jobserver 不可用: 正使用 -j1。添加 “” 到父 make 的规则。 Detected architecture: x86_64 and libc: gnu Downloading and installing Rust standalone installer: rust-1.92.0-x86_64-unknown-linux-gnu mkdir -p src git clone --recursive --depth 1 --branch v8.6.0 https://github.com/redisjson/redisjson src 正克隆到 src... remote: Enumerating objects: 414, done. remote: Counting objects: 100% (414/414), done. remote: Compressing objects: 100% (246/246), done. remote: Total 414 (delta 67), reused 304 (delta 57), pack-reused 0 (from 0) 接收对象中: 100% (414/414), 795.21 KiB | 2.04 MiB/s, 完成. 处理 delta 中: 100% (67/67), 完成. 注意正在检出 107144fd2c0a6b325108352bf83ed6e6f731a20f。 您正处于分离头指针状态。您可以查看、做试验性的修改及提交并且您可以通过另外 的检出分支操作丢弃在这个状态下所做的任何提交。 如果您想要通过创建分支来保留在此状态下所做的提交您可以通过在检出命令添加 参数 -b 来实现现在或稍后。例如 git checkout -b 新分支名 子模组 deps/readieshttps://github.com/RedisLabsModules/readies.git未对路径 deps/readies 注册 正克隆到 /home/ygcg/redis-8.6.3/modules/redisjson/src/deps/readies...#数据落盘redis-cli CONFIG GETdir#确认数据目录位置redis-cli INFO persistence redis-cli SAVE redis-cli BGSAVE#生成快照并复制dump.rdb文件至安全位置或appendonly.aof文件# 关闭从节点/app/redis7/bin/redis-cli-a密码-hip-p6933SHUTDOWNcp-r/path/to/redis-data-dir/ /path/to/backup/#验证./src/redis-server redis-full.conf# 使用原有配置文件启动测试模式不会真正启动redis-server /path/to/redis.conf --test-memory021|grep-iwarning\|errorredis-cli INFO server|grepredis_version#如果是集群的话在线滚动升级方案无需停机应先升级从节点关闭备份升级后在升级后的从节点上触发故障转移进行主从切换升级下一个从即原主节点CLUSTER NODESCLUSTER MEETip6933#重新加入集群使用旧版客户端CLUSTER REPLICATE主节点ID#恢复主从关系通过CLUSTER REPLICATE命令指定新节点的主节点IDINFO serverCLUSTER FAILOVER#主从切换CLUSTER NODES#如果需重建集群/bin/redis-cli-a密码--clustercreate\ip:6938 ip:6939 ip:6940\ip:6941 ip:6942 ip:6943\--cluster-replicas1--cluster-yesCLUSTER INFO#升级后观察内存MODULE LIST#查看当前模块