【问题标题】:LD_PRELOAD with setuid binary带有 setuid 二进制文件的 LD_PRELOAD
【发布时间】:2012-03-03 05:22:37
【问题描述】:

我正在尝试使用 LD_PRELOAD 预加载具有 setuid 权限的应用程序的库。起初尝试LD_PRELOAD,它似乎被setuid二进制文件忽略了,尽管当我与lsdir等其他人一起尝试时它正在工作。

来自 LD_PRELOAD 的文档:

   LD_PRELOAD
          A whitespace-separated list of additional, user-specified, ELF shared
          libraries to be loaded before all others.  This can be used to
          selectively override functions in other shared libraries.  For set-
          user-ID/set-group-ID ELF binaries, only libraries in the standard
          search directories that are also set-user-ID will be loaded.

我尝试按照上面的文档将库放在具有 setuid 权限的 /usr/lib/usr/local/lib/usr/lib64 中,但它似乎仍然不起作用。如果我在标准目录中有带有 setuid 的库的情况下不给 LD_PRELOAD 一个路径,它似乎无法找到该库。如果我给它路径,它不会做任何事情。

setuid 二进制文件是在非 root 用户 shell 中运行的 root 权限二进制文件。有什么想法吗?不确定我是否缺少路径、环境变量,或者我误解了上面的文档。

编辑:请求的权限是:

图书馆:

-rwsr-sr-x 1 root root 72580 2012-02-10 07:51

应用:

-rwsr-xr-x 1 root root 137517601 2012-02-10 

env | grep LD
LD_LIBRARY_PATH=/usr/lib (I added this manually myself, usually LD_LIBRARY_PATH is empty)

【问题讨论】:

  • 你在运行 SELinux 吗?
  • 是的,Suse enterprise 11.1 是我目前正在运行的......
  • 终于成功了。在整套测试中,我一定搞砸了。将它放在具有正确权限(setuid)的 lib64 中并且不提供 LD_PRELOAD 的路径是有效的。感谢大家的帮助!

标签: linux setuid ld-preload


【解决方案1】:

LD_PRELOAD 不能与 setuid 一起使用。这是linux中的一个安全特性。 如需参考,请查看this article,其中详细介绍了如何使用LD_PRELOAD 将一些库调用替换为自定义代码,例如malloc

【讨论】:

    【解决方案2】:

    如果您使用的是 SELinux,这可能是由于它。 glibc 支持的 ELF 辅助向量之一是 AT_SECURE。这个特定参数(默认为 0 或 1)告诉 ELF 动态链接器取消设置被认为可能对您的系统有害的各种环境变量。其中之一是LD_PRELOAD。通常,当调用 setuid/setgid 应用程序时会完成此环境清理工作(以防止明显的漏洞)。 SELinux 还增强了这种卫生,每当应用程序在 SELinux 中触发域转换时(比如通过标记为moz 的二进制文件将sysadm_t 转换为mozilla_t,或其他); SELinux 为已加载的应用程序(在示例中为 mozilla/firefox)设置 AT_SECURE 标志。

    noatsecure 权限会禁用特定过渡的环境卫生活动。您可以通过以下允许语句来执行此操作(如上例所示):

    allow sysadm_t mozilla_t:process { noatsecure };
    

    【讨论】:

    • selinux安全是增强linux还是suse企业?我运行后者。您提到的内容是否仍然适用于 suse 企业?
    • 根据this,SELinux 是从 11.1 开始的 SUSE Enterprise 中的一个选项。但是,如果您不使用它,我的回答不适用。
    • 据我所知,我没有运行 Selinux。我没有看到任何常用的 selinux 配置选项。我确实看到了 AppArmour,但它也被禁用了。
    【解决方案3】:

    在带有 glibc 的系统上,您可以使用另一种受支持的方式预加载库:将库添加到 /etc/ld.so.preload。这个不受LD_PRELOAD的限制。

    特别是,通过这种方式,我能够将libgtk3-nocsd.so 预加载(无用,只是为了证明它有效)到/usr/bin/passwd,并且当我运行passwd ruslan 时,库确实出现在/proc/<PID_OF_PASSWD>/maps 中,而passwd 正在等待当前密码输入。

    一个缺点是您不能像 LD_PRELOAD 那样在每个应用程序的基础上执行此操作。如果你真的需要这个,也许你可以改变你的库来尝试检查它是否想做任何事情,基于当前进程二进制文件的路径(检测它就像讨论的here)。

    【讨论】:

      【解决方案4】:

      LD_PRELOAD 不能与 set-user-ID/set-group-ID 程序一起使用,除非 et-user-ID/set-group-ID 程序以 same 的方式运行strong> 真实有效的用户和组。

      例如在fork之后和exec*之前,设置

      • setreuid 给 set-user-ID 程序的所有者
      • setregid到set-group-ID程序的组

      【讨论】:

        【解决方案5】:

        这样安装你的库:

        • 位置:/lib 或 /usr/lib
        • 权限:root:root
        • 已启用 setuid 和 setgid

        确保将 LD_PRELOAD 导出到您的环境中

        $ export LD_PRELOAD=/usr/lib/yourlib.so
        $ env | grep LD_PRELOAD  # verify
        

        然后运行你的程序。

        【讨论】:

        • 它不起作用,它将库应用于所有应用程序。我试图使用 LD_PRELOAD=... appname 来为这个应用程序预加载它。作为一个实验,我将 ls 复制到我自己的目录中,并为其添加了 setuid 权限(chmod u+s ./ls)。我的库以前与 ls 一起使用,不再使用此本地权限更改了。:( 作为另一个实验,我尝试将 lib 添加到 /etc/ld.so.preload,它可以工作,但同样,它适用于所有人应用程序。如果可能,我希望它与 LD_PRELOAD=.. appname 一起使用。
        • 您能否编辑以在您的库和程序上显示ls -lad 的结果,以及env | grep LD 的结果?
        • 添加了编辑。谢谢你的帮助!再澄清一点,当我把它放在 /etc/ld.so.preload 中时,我的应用程序似乎也可以与 lib 一起使用,它只适用于所有应用程序。在 ld.so.preload 情况下,可能会跳过加载程序作为 LD_PRELOAD 一部分所做的一些检查。此外,当我 sudo 并以 root 身份运行时,LD_PRELOAD 可以与我的应用程序一起使用,但不幸的是我无法以 root 身份运行该应用程序。这只是一个快速的实验。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-25
        • 1970-01-01
        • 2011-07-11
        • 2012-03-25
        • 1970-01-01
        • 1970-01-01
        • 2015-01-12
        相关资源
        最近更新 更多