Redis CVE-2018-12326 分析

redis CVE-2018-12326 分析

前言

影响版本: Redis 3.2.x-3.2.4.

分析版本: 5.0, 4.0, 3.2

环境:ubuntu 17.10

0x01 漏洞类型

整型溢出导致缓冲区溢出

0x02 漏洞原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

static void cliRefreshPrompt(void) {
int len;

if (config.eval_ldb) return;
if (config.hostsocket != NULL)
len = snprintf(config.prompt,sizeof(config.prompt),"redis %s",
config.hostsocket);
else
len = anetFormatAddr(config.prompt, sizeof(config.prompt),
config.hostip, config.hostport);
/* Add [dbnum] if needed */
if (config.dbnum != 0)
len += snprintf(config.prompt+len,sizeof(config.prompt)-len,"[%d]",
config.dbnum);
snprintf(config.prompt+len,sizeof(config.prompt)-len,"> ");
}

当执行流到达

len = anetFormatAddr(config.prompt, sizeof(config.prompt), config.hostip, config.hostport);的时候,参数长度由 anetFormatAddr决定。当我们的输入足够大的时候,sizeof(config.prompt)-len 变发生整型溢出

如上图。

1
2
3
4
5
    if (config.dbnum != 0)
len += snprintf(config.prompt+len,sizeof(config.prompt)-len,"[%d]",
config.dbnum);
snprintf(config.prompt+len,sizeof(config.prompt)-len,"> ");
}

程序会通过 snprintf 这个函数向 config.prompt+len写入东西由于len是可控,所以我们可以向指定位置写入,但是写入的东西却是不可控的,他向 config.prompt+len 的位置写入的东西是 字符 >

如图,由于写入参数不可控制,这个CVE 依旧无法做到任意代码执行。

0x03 POC

1
r  -h `python -c 'print "A" * 340'`

0x04 漏洞修复

修复后把len的获取修改了。

0x05 疑问

这个CVE 在exp-db的描述如下:

1
2
3
4
5
6
7
8
9
10
11
# Exploit Title: Redis-cli < 5.0 - Buffer Overflow (PoC)
# Date: 2018-06-13
# Exploit Author: Fakhri Zulkifli
# Vendor Homepage: https://redis.io/
# Software Link: https://redis.io/download
# Version: 5.0, 4.0, 3.2
# Fixed on: 5.0, 4.0, 3.2
# CVE : CVE-2018-12326

# Buffer overflow in redis-cli of Redis version 3.2, 4.0, and 5.0 allows a local attacker
# to achieve code execution and escalate to higher privileges via a long string in the hostname parameter.

描述中说了可以 代码执行,但是在我的分析中,这个溢出似乎是不可控的。如果有人发现这个有代码执行的可能性或者方法请告知。

Emal: bestswngs@gmail.com

0x06 参考