“在序列化实例中具有 NULL 字节的文件名”是什么意思?

信息安全 上传文件
2021-08-13 16:04:24

我正在浏览这个页面,因为我是一名 Java 开发人员并且我知道受影响的库,所以我将我重定向到了这个漏洞。

基本上,该漏洞说:

发现 Apache Commons FileUpload 错误地处理了序列化实例中具有 NULL 字节的文件名。攻击者可以利用这个问题来写入任意文件。

我只是想知道这句话是什么意思?

...序列化实例中具有 NULL 字节的文件名。

2个回答

空字节是值为零的字节,即十六进制的 0x00。

存在与空字节相关的安全漏洞。这些发生是因为 C 使用空字节作为字符串终止符。其他语言(Java、PHP 等)没有字符串终止符;它们分别存储每个字符串的长度。

现在,考虑一个接受文件上传的 Java Web 应用程序。也许我们想让用户上传.jpg文件,但没有别的。事实上,如果用户可以上传.jsp文件,这将是一个严重的安全漏洞。

黑客可能会尝试上传hack.jsp<NUL>.jpg. 让我们想想这将如何处理。首先,Java 会查看文件名,看到它的结尾.jpg并允许上传。然后它调用用 C 编写的操作系统库。C 将<NUL>字符视为字符串终止符,因此将文件保存为hack.jsp.

许多语言通过明确禁止<NUL>文件名中的字节来解决此问题。我知道 Python 和 PHP 可以做到这一点。但是,如果您的语言不适合您,您必须自己做。更多信息 - OWASP:空字节注入

我不知道“序列化实例”与此有何关系,但我认为这让您对发生了什么有所了解。

每个字符都有一个由相应字符集规定的数值。因此,例如,通常Ais65ais 97但是如果数字是0,那么它就不是一个真正的字符,它是一个“空”;这基本上意味着不是一个字符

在 C 和 C++ 中,此“空”字符用于表示字符串的结尾。所以“HELLO”是这样存储的:

 H   E   L   L   O  
72  69  76  76  79  00 

最后00说“停在这里”。但并非所有框架都使用 C 字符串及其“空终止符”格式;事实上大多数都没有。相反,字符串的长度是预先存储的,实际内容可以包含任何内容,包括这些字符——数值为 的字符0

所以在这种情况下,如果名称包含这些字符之一,大多数代码都不会介意;允许字节。但是,当该名称出现在 FileUpload 代码中时,该null最终会引起一些混乱。一些代码认为名称字节结尾,而其他位认为字节只是另一个字母。这种混淆,即两段代码对名称的实际含义不一致,会导致安全漏洞。