我正在尝试覆盖程序的 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
小智 10
根据 ld 文档,我需要将我的库放入标准搜索目录之一(我选择
/usr/lib)
这就是错误。你应该把它放进去/usr/lib64(假设你的机器是 x86_64)。
我刚刚在 Centos 7 VM 上尝试了联机帮助页中的配方(应该与 RHEL 7 相同)并且它有效:
作为根用户:
cynt# cc -shared -fPIC -xc - <<<'char *setlocale(int c, const char *l){ errx(1, "not today"); }' -o /usr/lib64/liblo.so
cynt# chmod 4755 /usr/lib64/liblo.so
Run Code Online (Sandbox Code Playgroud)
作为使用 setuid 程序的普通用户:
cynt$ LD_PRELOAD=liblo.so su -
su: not today
Run Code Online (Sandbox Code Playgroud)
使用该功能是否是一个好主意是完全不同的事情(恕我直言,事实并非如此)。
man ld.so
安全执行模式
出于安全原因,如果动态链接器确定二进制文件应在安全执行模式下运行,则某些环境变量的影响将被无效或修改
[...]
如果满足以下条件,则二进制文件将以安全执行模式执行:
- 进程真实有效用户ID不同
[...]
LD_PRELOAD
在安全执行模式下,包含斜杠的预加载路径名将被忽略。此外,共享对象仅从标准搜索目录预加载,并且仅当它们启用了 set-user-ID 模式位时(这不是典型的)。
如果执行 SUID 二进制文件,则会出现这种情况:真实 UID 和有效 UID 不同。但是,如果此二进制文件执行不同的(非 SUID)二进制文件,则父级的 EUID 将成为子级的 RUID 和 EUID:
sudo sleep 1000 &
ps -o pid,ruid,euid,args --pid $! --ppid $!
PID RUID EUID COMMAND
7286 1000 0 sudo sleep 1000
7287 0 0 sleep 1000
Run Code Online (Sandbox Code Playgroud)
因此,如果您想避免 LD_PRELOAD 限制,您可以通过 sudo 调用您的二进制文件,或者创建一个包装器 SUID 二进制文件来调用实际的二进制文件。
| 归档时间: |
|
| 查看次数: |
1998 次 |
| 最近记录: |