工具checksec.sh用于检查编译时强化选项,例如 NX、RELRO、PIE 等。
它还使用以下逻辑报告二进制文件是否设置了 RPATH 或 RUNPATH:
这些在存在时被标记为红色。
设置 RPATH 或 RUNPATH 有什么安全风险?
工具checksec.sh用于检查编译时强化选项,例如 NX、RELRO、PIE 等。
它还使用以下逻辑报告二进制文件是否设置了 RPATH 或 RUNPATH:
这些在存在时被标记为红色。
设置 RPATH 或 RUNPATH 有什么安全风险?
TL;DR:R*PATH
在引入运行不受信任(攻击者控制)库的新方法方面有着不幸的历史。RPATH
/RUNPATH
通常是可以避免的,应该避免。
首先,可能值得回顾一下我们为什么要标记这些二进制文件的非安全原因:发行版(例如RPATH 上的 Debian Wiki)不喜欢它优先于本地
LD_LIBRARY_PATH
和/etc/ld.so.conf
设置/配置和约定。readelf
与运行我们想要考虑的每个二进制文件相比,通过更可见的方式对库进行推理变得更加困难,并且它使维护者的生活变得复杂,他们通过这些其他机制来处理许多相互交织的依赖关系,这些机制很容易被RPATH
/破坏RUNPATH
。但也有例外——这是 Debian 的政策:
Debian 软件包中的二进制或共享库唯一一次应该设置
RPATH
,或者RUNPATH
如果它链接到同一软件包中的私有共享库。
其次,相对RPATH
(即foo.so
而不是
/usr/lib/foo.so
)可能会出错:您的用户可能从一个工作目录(例如/tmp
)运行,该目录受攻击者控制,谁可以植入恶意版本的/tmp/foo.so
. 这是Debian bug #754278 针对 openjdk的观察结果。
这听起来可能是良性的,但它可能会导致 privesc,特别是在 setuid/setgid 程序上,例如IBM 的 DB2 privesc CVE-2014-0907:只需从准备滥用任何
RPATH
设置的目录中运行 suid 二进制文件,您的代码就会在上下文中运行的特权程序。其他示例包括Slackware 的 llvm CVE-2013-7171 封装、Gentoo 的 Imagemagick CVE-2005-3582 封装、SuSE 的 CVSup CVE-2004-2133 封装,...)。这是一个稳定的涓涓细流,Apple 的等效程序避免了“受限”(suid/sgid)二进制文件中的相对 RPATH。
第三,特殊$ORIGIN
变量(调用可执行路径)是一种避免绝对路径的方法,同时将搜索锚定在
某处。但它存在问题:glibc CVE-2011-0536未能正确扩展它,这给了攻击者一个相当于 RPATH 相对情况的情况,其中可执行文件的作者$ORIGIN
认为他们得到了一些更强大的东西。
考虑到这一点,您可能确实想要checksec.sh
标记
RPATH
/ RUNPATH
- 这并不总是很糟糕,但checksec.sh
没有像发行版 linter 那样有更大的图景来为您发出调用,因此需要手动审查。
附录:Breaking the links:在您的 Twitter 对话的回复中提到了 Tim Brown 的 Exploiting the linker,这是一篇关于攻击面的好论文,更普遍地适用于 POSIX 样式的链接器,精明的读者绝对应该看看。尚未涵盖的最相关的事情是:
至少在 GNU/Linux 上,当
DT_RPATH
或DT_RUNPATH
存在于二进制文件的 ELF 标头中时,在查找共享库时将首先使用这些标头。此外,此标头中的关键字$ORIGIN
扩展为找到对象的目录的路径,而 . 并且空目录规范得到尊重,即使对于设置了 setUID 位的二进制文件也是如此。从攻击者的角度来看,setUID 二进制文件DT_RPATH
特别好,因为我们可以使用硬链接来操纵运行时链接器以使用$ORIGIN
我们可以控制的。
...正如本文其他地方所观察到的,大多数系统在大多数情况下都会忽略用户提供的环境变量,例如LD_LIBRARY_PATH
setuid 二进制文件,但正如您所见,粗心RPATH
会给攻击者同等的礼物。
第二个附录:ContextIS 有一篇很棒的文章,涵盖了 RPATH 攻击。