什么是 The poisoned NUL byte,1998 和 2014 版本?
what is The poisoned NUL byte, in 1998 and 2014 editions?
我必须就 "poisoned null-byte (glibc)" 做 10 分钟的演讲。
我搜索了很多,但一无所获,我需要帮助,因为操作系统 linux 以及内存和进程管理不是我的事。
这里是 original article, and here is an old article 关于相同问题的另一个版本。
我想要的是对问题的新旧版本的简短解释 or/and 足够的参考资料,我可以在其中更好地了解此安全威胁。
要开始了解这种攻击的工作原理,您至少需要基本了解 CPU 的工作原理、内存的工作原理、"heap" 和 "stack" 的工作原理进程是什么,指针是什么,libc 是什么,链表是什么,函数调用是如何在机器级别实现的(包括对函数指针的调用),malloc
和 free
函数来自什么C 库做,等等。希望您至少具备一些 C 编程的基础知识? (否则,您可能无法及时完成此作业。)
如果您对上述基本主题有一些 "gaps" 知识,请尽快翻阅书籍并填写。如果需要,请与他人交谈,以确保您了解他们。然后仔细阅读以下内容。这不会解释您链接到的文章中的所有内容,但会给您一个良好的开端。准备好了?让我们开始吧...
C 字符串是 "null-terminated"。这意味着字符串的结尾由零字节标记。因此,例如,字符串 "abc"
在内存中表示为(十六进制):0x61 0x62 0x63 0x00
。请注意,由于终止空值,该 3 个字符的字符串实际上需要 4 个字节。
现在如果你这样做:
char *buffer = malloc(3); // not checking for error, this is just an example
strcpy(buffer, "abc");
...然后终止空(零字节)将超过缓冲区的末尾并覆盖一些东西。我们分配了一个 3 字节的缓冲区,但将 4 个字节复制到其中。因此,缓冲区末尾之后的字节中存储的任何内容都将被替换为零字节。
这就是 __gconv_translit_find
中发生的事情。他们有一个缓冲区,已经分配了足够的 space 来追加 ".so"
,包括终止空字节,到字符串的末尾。但是他们从错误的位置开始在中复制了".so"
。他们开始的复制操作距离 "right" 太远了一个字节,因此终止的空字节超过了缓冲区的末尾并覆盖了一些内容。
现在,当您调用 malloc
以取回动态分配的缓冲区时,malloc
的大多数实现实际上会在缓冲区 之前存储一些内务处理数据.例如,它们可能存储缓冲区的大小。稍后,当你将该缓冲区传递给 free
以释放内存,以便它可以重新用于其他用途时,它会发现 "hidden" 数据就在缓冲区开始之前,并且会知道有多少您实际上 free
ing 的内存字节数。 malloc
也可能 "hide" 同一位置的其他管理数据。 (在您提到的 2014 年文章中,malloc
的实现还在那里存储了一些 "flag" 位。)
文章中描述的攻击将精心设计的参数传递给命令行程序,旨在触发 __gconv_translit_find
中的缓冲区溢出错误,以这种方式终止空字节会清除 "flag" 由 malloc
存储的位——不是 溢出缓冲区 的标志位,而是 另一个 缓冲区的标志位在 溢出的那个之后 被分配。 (因为 malloc
在分配缓冲区的开始 之前 存储了额外的内务管理数据,并且我们结束了 运行 宁 previous buffer. 你跟上了吗?)
文章显示了一个图表,其中 0x00000201
存储在溢出的缓冲区之后。溢出的空字节擦除底部 1
并将其更改为 0x00000200
。一开始这可能没有意义,直到您记住 x86 CPUs 是小端字节序——如果您不理解 "little-endian" 和 "big-endian" CPUs 是什么, 查一查。
之后,标志位被擦除的缓冲区被传递给free
。事实证明,清除一个标志位 "confuses" free
并使其反过来也覆盖其他一些内存。 (你必须了解 GNU libc 使用的 malloc
和 free
的实现,才能理解为什么会这样。)
通过仔细选择原始程序的输入参数,您可以进行设置,使 "confused" free
覆盖的内存用于称为 tls_dtor_list
的内存。这是一个由 GNU libc 维护的链表,它包含指向某些函数的指针,当主程序退出时它必须调用这些函数。
所以tls_dtor_list
被覆盖了。攻击者设置得恰到好处,因此被覆盖的 tls_dtor_list
中的函数指针将指向他们想要 运行 的一些代码。当主程序退出时,libc 中的一些代码遍历该列表并调用每个函数指针。结果:攻击者代码被执行!
现在,在这种情况下,攻击者已经可以访问目标系统。如果他们所能做的只是 运行 一些具有他们自己帐户权限级别的代码,那他们就无处可去。他们想要 运行 具有 root(管理员)权限的代码。这怎么可能?这是可能的,因为有问题的程序是一个 setuid 程序,由 root 拥有。如果您不知道 Unix 中的 "setuid" 程序是什么,请查找并确保您理解它,因为这也是整个漏洞利用的关键。
这是关于 2014 年的文章 -- 我没有看 1998 年的那篇。祝你好运!
我必须就 "poisoned null-byte (glibc)" 做 10 分钟的演讲。 我搜索了很多,但一无所获,我需要帮助,因为操作系统 linux 以及内存和进程管理不是我的事。
这里是 original article, and here is an old article 关于相同问题的另一个版本。
我想要的是对问题的新旧版本的简短解释 or/and 足够的参考资料,我可以在其中更好地了解此安全威胁。
要开始了解这种攻击的工作原理,您至少需要基本了解 CPU 的工作原理、内存的工作原理、"heap" 和 "stack" 的工作原理进程是什么,指针是什么,libc 是什么,链表是什么,函数调用是如何在机器级别实现的(包括对函数指针的调用),malloc
和 free
函数来自什么C 库做,等等。希望您至少具备一些 C 编程的基础知识? (否则,您可能无法及时完成此作业。)
如果您对上述基本主题有一些 "gaps" 知识,请尽快翻阅书籍并填写。如果需要,请与他人交谈,以确保您了解他们。然后仔细阅读以下内容。这不会解释您链接到的文章中的所有内容,但会给您一个良好的开端。准备好了?让我们开始吧...
C 字符串是 "null-terminated"。这意味着字符串的结尾由零字节标记。因此,例如,字符串 "abc"
在内存中表示为(十六进制):0x61 0x62 0x63 0x00
。请注意,由于终止空值,该 3 个字符的字符串实际上需要 4 个字节。
现在如果你这样做:
char *buffer = malloc(3); // not checking for error, this is just an example
strcpy(buffer, "abc");
...然后终止空(零字节)将超过缓冲区的末尾并覆盖一些东西。我们分配了一个 3 字节的缓冲区,但将 4 个字节复制到其中。因此,缓冲区末尾之后的字节中存储的任何内容都将被替换为零字节。
这就是 __gconv_translit_find
中发生的事情。他们有一个缓冲区,已经分配了足够的 space 来追加 ".so"
,包括终止空字节,到字符串的末尾。但是他们从错误的位置开始在中复制了".so"
。他们开始的复制操作距离 "right" 太远了一个字节,因此终止的空字节超过了缓冲区的末尾并覆盖了一些内容。
现在,当您调用 malloc
以取回动态分配的缓冲区时,malloc
的大多数实现实际上会在缓冲区 之前存储一些内务处理数据.例如,它们可能存储缓冲区的大小。稍后,当你将该缓冲区传递给 free
以释放内存,以便它可以重新用于其他用途时,它会发现 "hidden" 数据就在缓冲区开始之前,并且会知道有多少您实际上 free
ing 的内存字节数。 malloc
也可能 "hide" 同一位置的其他管理数据。 (在您提到的 2014 年文章中,malloc
的实现还在那里存储了一些 "flag" 位。)
文章中描述的攻击将精心设计的参数传递给命令行程序,旨在触发 __gconv_translit_find
中的缓冲区溢出错误,以这种方式终止空字节会清除 "flag" 由 malloc
存储的位——不是 溢出缓冲区 的标志位,而是 另一个 缓冲区的标志位在 溢出的那个之后 被分配。 (因为 malloc
在分配缓冲区的开始 之前 存储了额外的内务管理数据,并且我们结束了 运行 宁 previous buffer. 你跟上了吗?)
文章显示了一个图表,其中 0x00000201
存储在溢出的缓冲区之后。溢出的空字节擦除底部 1
并将其更改为 0x00000200
。一开始这可能没有意义,直到您记住 x86 CPUs 是小端字节序——如果您不理解 "little-endian" 和 "big-endian" CPUs 是什么, 查一查。
之后,标志位被擦除的缓冲区被传递给free
。事实证明,清除一个标志位 "confuses" free
并使其反过来也覆盖其他一些内存。 (你必须了解 GNU libc 使用的 malloc
和 free
的实现,才能理解为什么会这样。)
通过仔细选择原始程序的输入参数,您可以进行设置,使 "confused" free
覆盖的内存用于称为 tls_dtor_list
的内存。这是一个由 GNU libc 维护的链表,它包含指向某些函数的指针,当主程序退出时它必须调用这些函数。
所以tls_dtor_list
被覆盖了。攻击者设置得恰到好处,因此被覆盖的 tls_dtor_list
中的函数指针将指向他们想要 运行 的一些代码。当主程序退出时,libc 中的一些代码遍历该列表并调用每个函数指针。结果:攻击者代码被执行!
现在,在这种情况下,攻击者已经可以访问目标系统。如果他们所能做的只是 运行 一些具有他们自己帐户权限级别的代码,那他们就无处可去。他们想要 运行 具有 root(管理员)权限的代码。这怎么可能?这是可能的,因为有问题的程序是一个 setuid 程序,由 root 拥有。如果您不知道 Unix 中的 "setuid" 程序是什么,请查找并确保您理解它,因为这也是整个漏洞利用的关键。
这是关于 2014 年的文章 -- 我没有看 1998 年的那篇。祝你好运!