我正在尝试覆盖程序的 malloc/free 函数,这需要 setuid/setgid 权限。为此,我使用 LD_PRELOAD 变量。根据ld 文档,我需要将我的库放入标准搜索目录之一(我选择 /usr/lib)并为其授予 setuid/setgid 权限。我已经做到了。但是,我仍然无法链接到我的 .so 文件,出现错误:
object 'liballoc.so' from LD_PRELOAD cannot be preloaded: ignored
可能的原因是什么?在没有 setuid/setgid 权限的程序上测试了这个 .so 文件,一切正常。操作系统:红帽 7.0
那是错误。你应该把它放进去
/usr/lib64
(假设你的机器是 x86_64)。我刚刚在 Centos 7 VM(应该与 RHEL 7 相同)上尝试了手册页中的配方,它可以工作:
作为根:
作为使用 setuid 程序的普通用户:
使用该功能是否是一个好主意是完全不同的事情(恕我直言,不是)。
man ld.so
如果执行 SUID 二进制文件,则会出现这种情况:真实 UID 和有效 UID 不同。但如果此二进制文件执行不同的(非 SUID)二进制文件,则父项的 EUID 将成为子项的 RUID 和 EUID:
因此,如果您想避免 LD_PRELOAD 限制,您可以通过 sudo 调用您的二进制文件,或者创建一个调用实际二进制文件的包装 SUID 二进制文件。
这样做的原因是为了防止恶意代码提升。AC 程序未在 main() 中开始运行。相反,首先调用 C 运行时库,它设置其环境(包括 STDIO 流)、任何不是编译时常量的全局变量,然后调用 main()。
恶意行为者可以使用 LD_PRELOAD= 使用具有修改的启动功能的自定义库覆盖 libc.o 库(例如) - 恢复 LD_PRELOAD,然后调用 /bin/sh。如果 SUID 进程没有忽略 LD_PRELOAD=,则该用户可以运行 /bin/passwd,并且他们现在有一个 root shell。他们现在可以从那里安装 rootkit 等。