原理:
什么是LD_PRELOAD:
LD_PRELOAD
是Linux/Unix
系统的一个环境变量,它影响程序的运行时的链接(Runtime linker),它允许在程序运行前定义优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库
利用
具体的操作步骤如下:
-
定义一个函数,函数的名称、变量及变量类型、返回值及返回值类型都要与要替换的函数完全一致。这就要求我们在写动态链接库之前要先去翻看一下对应手册等。
-
将所写的 c 文件编译为动态链接库。
-
对 LD_PRELOAD 及逆行设置,值为库文件路径,接下来就可以实现对目标函数原功能的劫持了
-
结束攻击,使用命令 unset LD_PRELOAD 即可
编写一个文件
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char name[] = "mon";
if (argc < 2) {
printf("usage: %s <given-name>\n", argv[0]);
return 0;
}
if (!strcmp(name, argv[1])) {
printf("\033[0;32;32mYour name Correct!\n\033[m");
return 1;
} else {
printf("\033[0;32;31mYour name Wrong!\n\033[m");
return 0;
}
}
再编写一个动态链接库
#include <stdlib.h>
#include <string.h>
int strcmp(const char *s1, const char *s2) {
if (getenv("LD_PRELOAD") == NULL) {
return 0;
}
unsetenv("LD_PRELOAD");
return 0;
}
动态链接库使用 unsetenv("LD_PRELOAD");的原因
由于我们通过 LD_PRELOAD 劫持了函数,劫持后启动了一个新进程,若不在新进程启动前取消 LD_PRELOAD,则将陷入无限循环,所以必须得删除环境变量 LD_PRELOAD,最直接的就是调用 unsetenv("LD_PRELOAD")
。
成功后输入什么都会提示正确
效果展示
编译
编译动态链接库文件:
-o 是为了生成动态链接库文件
将.so文件用LD_PRELOAD加载到动态链接库
pwd表示当前目录
此时执行。
不管输入什么都会显示
Your name Correct!