导语:研究人员发现开源流媒体服务器Icecast的Snprintf漏洞,本文对该漏洞进行分析。

研究人员发现xiph.org基金会支持的开源流媒体服务器Icecast的漏洞。攻击者可以伪造HTTP header来覆写服务器的栈内容,导致远程代码执行漏洞。因为Icecast常用于网络电台,所以攻击者利用该漏洞可以完全控制网络电台。该漏洞的CVE编号为CVE-2018-18820

版本号为2.4.0到2.4.3的Icecast服务器和使用URL认证的Icecast服务器受该漏洞的影响。研究人员建议尽快升级到v 2.4.4。

Snprintf

我们都知道sprintf是不安全的,因为不提供对缓冲区溢出的保护。许多文档中都说Snprintf是更安全版本的sprintf,但如果缓冲区太小,输出就会变短。但我们不清楚的是如果输出缩短,snprintf就不会返回写的字节。事实上,如果输出缓存足够大,那么返回的是已经写入的字节数。如果提供一个大于缓冲区大小的size参数,根本无法应对缓冲区溢出。

下面是来自Icecast的有漏洞的代码:

在来自用户请求的HTTP header之上循环,并复制到缓冲区,构建一个发送到认证服务器的POST请求主体:

post_offset += snprintf(post + post_offset,                        
 sizeof(post) - post_offset,                        
 "&%s%s=%s",
                        
                     url->prefix_headers ? url->prefix_headers : "",
                         cur_header, header_valesc);

下面是代码的简化版:

post_offset += snprintf(post + post_offset,
                        sizeof(post) - post_offset,
                        "%s",
                        cur_header);

如果sizeof(post)的大小是10,那么就写入了8字节。那么如果下一个复制的header是baz会怎么样呢?

输出会变短,但post_offset在缓存的尾部会递增:

下面设想另一个复制的header内容为“AAAAA…”。 到snprintf的size参数是sizeof(post) – post_offset,这会下溢变成一个非常大的数。结果就是之后对snprintf的调用会有效地写入尽可能多的数据。数据会被写入post + post_offset,可能会超出post缓存的范围,那么就会覆盖栈中的其他内容。

也就是说我们可以发送一个随后会被缩短的长HTTP header,但是长度可以让我们定位栈中的任何位置post_offset。然后,可以发送第二个HTTP header,其内容会被写入定位的位置。

对攻击者来说,比较难的一点是header在复制到snprintf之前会进行处理,所以限制在可以写入到栈中的数据。研究人员的POC漏洞利用可以引发服务器进程段错误(segfault),类似DoS攻击。但研究人员认为攻击者可以对该攻击进行升级来获得完全远程代码执行。

修复

Xiph很快对漏洞进行了回应,并发布了补丁。补丁非常简单,检查了snprintf的返回值,如果使post_offset指向缓冲区的尾部,就记录错误并退出循环。

源链接

Hacking more

...