如何创建文件名中包含空字节的文件?
How can I create a file with null bytes in the filename?
对于安全测试,我需要传递一个在其内容和文件名中包含空字符的文件。
正文内容,好用printf
:
$ printf "Hello[=10=], Null!" > containsnull.txt
$ xxd contains.null
0000000: 4865 6c6c 6f00 2c20 4e75 6c6c 21 Hello., Null!
但是我如何创建名称中包含空字节的文件?
注意:如果可能,首选 bash
、python
或 nodejs
中的解决方案
不可能通过POSIX或WindowsAPI创建包含空字节的文件名。在我所知道的所有 Unix 系统上,创建一个包含空字节的文件名是不可能的,即使是一个行为不端的应用程序绕过了正常的 API,因为内核本身会处理它的所有文件将输入命名为以 null 结尾的字符串。我相信 Windows 也是如此,但我不完全确定。
作为应用程序程序员,就安全性而言,这意味着您无需担心包含空字节的文件名,如果您确定您拥有的是文件名的话。另一方面,如果给定一个字符串并告诉您将其用作文件名,例如,如果您正在对服务器进行编程并让客户端选择文件名,则需要确保该字符串不包含 null字节。这只是其他要求之一,包括字符串长度、目录分隔符(/
或 \
)、保留名称(.
和 ..
、保留名称 Windows 文件名,如 nul.txt
或 prn
) 等。在大多数 Unix 系统上,在其本机文件系统上,文件名的约束是:没有空字节或斜杠,长度在 1 到一些之间maximum,.
和 ..
这两个名字是保留的。 Windows 和 Unix 上的非本机文件系统有额外的限制(可以通过对 Windows 的直接内核调用将 /
放在文件名中)。
要将空字节放入文件内容,只需使用任何允许字符串中出现空字节的语言将字符串写入文件即可。在bash中,你不能在字符串中存储空字节,所以你需要使用另一种方法,如printf '[=19=]'
或echo "abc" | tr b '[=20=]'
。
您不必担心文件名在 Unix 和 Windows 上包含空字节,因为它们不能。
但是,被视为 UTF-8 的文件名可以使用无效的“超长”序列指定 NUL 字符 (U+0000):全为零的两个、三个或四个字节的 UTF-8 序列在他们的代码点有效载荷位中。
这可能是一个安全问题。例如,不检查这一点的 UTF-8 解码器最终会生成 wchar_t
字符值 0,然后意外终止宽字符串。
例如,the byte sequence C0 80是NUL的超长编码。这显然被称为“Modified UTF-8”的东西使用,专门用于编码不终止用于保存 UTF-8 的 C 字符串的 NUL 字符。
如果您正在进行安全测试,这很重要;您可以通过超长编码测试程序是否容易受到 NUL 字符(和其他)注入的影响。
尝试$'\u000d'
实际上不是空字节,但可能接近到让人迷惑,因为你必须仔细观察才能看到最后一个字符是 D 而不是 0,因为它通常会打印(如果不是空白的话) ) 作为带有十六进制代码的小盒子。
当我在我的 $HOME 中找到一个名为...的目录时发现了这个...
对于安全测试,我需要传递一个在其内容和文件名中包含空字符的文件。
正文内容,好用printf
:
$ printf "Hello[=10=], Null!" > containsnull.txt
$ xxd contains.null
0000000: 4865 6c6c 6f00 2c20 4e75 6c6c 21 Hello., Null!
但是我如何创建名称中包含空字节的文件?
注意:如果可能,首选 bash
、python
或 nodejs
中的解决方案
不可能通过POSIX或WindowsAPI创建包含空字节的文件名。在我所知道的所有 Unix 系统上,创建一个包含空字节的文件名是不可能的,即使是一个行为不端的应用程序绕过了正常的 API,因为内核本身会处理它的所有文件将输入命名为以 null 结尾的字符串。我相信 Windows 也是如此,但我不完全确定。
作为应用程序程序员,就安全性而言,这意味着您无需担心包含空字节的文件名,如果您确定您拥有的是文件名的话。另一方面,如果给定一个字符串并告诉您将其用作文件名,例如,如果您正在对服务器进行编程并让客户端选择文件名,则需要确保该字符串不包含 null字节。这只是其他要求之一,包括字符串长度、目录分隔符(/
或 \
)、保留名称(.
和 ..
、保留名称 Windows 文件名,如 nul.txt
或 prn
) 等。在大多数 Unix 系统上,在其本机文件系统上,文件名的约束是:没有空字节或斜杠,长度在 1 到一些之间maximum,.
和 ..
这两个名字是保留的。 Windows 和 Unix 上的非本机文件系统有额外的限制(可以通过对 Windows 的直接内核调用将 /
放在文件名中)。
要将空字节放入文件内容,只需使用任何允许字符串中出现空字节的语言将字符串写入文件即可。在bash中,你不能在字符串中存储空字节,所以你需要使用另一种方法,如printf '[=19=]'
或echo "abc" | tr b '[=20=]'
。
您不必担心文件名在 Unix 和 Windows 上包含空字节,因为它们不能。
但是,被视为 UTF-8 的文件名可以使用无效的“超长”序列指定 NUL 字符 (U+0000):全为零的两个、三个或四个字节的 UTF-8 序列在他们的代码点有效载荷位中。
这可能是一个安全问题。例如,不检查这一点的 UTF-8 解码器最终会生成 wchar_t
字符值 0,然后意外终止宽字符串。
例如,the byte sequence C0 80是NUL的超长编码。这显然被称为“Modified UTF-8”的东西使用,专门用于编码不终止用于保存 UTF-8 的 C 字符串的 NUL 字符。
如果您正在进行安全测试,这很重要;您可以通过超长编码测试程序是否容易受到 NUL 字符(和其他)注入的影响。
尝试$'\u000d'
实际上不是空字节,但可能接近到让人迷惑,因为你必须仔细观察才能看到最后一个字符是 D 而不是 0,因为它通常会打印(如果不是空白的话) ) 作为带有十六进制代码的小盒子。
当我在我的 $HOME 中找到一个名为...的目录时发现了这个...