2017-10-11 17:22:24 +07:00
|
|
|
# 1.5.6 动态链接
|
2017-09-19 21:01:26 +07:00
|
|
|
|
|
|
|
- [动态链接相关的环境变量](#动态链接相关的环境变量)
|
|
|
|
|
|
|
|
|
|
|
|
## 动态链接相关的环境变量
|
|
|
|
#### LD_PRELOAD
|
|
|
|
LD_PRELOAD 环境变量可以定义在程序运行前优先加载的动态链接库。这使得我们可以有选择性地加载不同动态链接库中的相同函数,即通过设置该变量,在主程序和其动态链接库中间加载别的动态链接库,甚至覆盖原本的库。这就有可能出现劫持程序执行的安全问题。
|
|
|
|
|
|
|
|
```c
|
|
|
|
#include<stdio.h>
|
|
|
|
#include<string.h>
|
|
|
|
void main() {
|
|
|
|
char passwd[] = "password";
|
|
|
|
char str[128];
|
|
|
|
|
|
|
|
scanf("%s", &str);
|
|
|
|
if (!strcmp(passwd, str)) {
|
|
|
|
printf("correct\n");
|
2017-10-11 17:22:24 +07:00
|
|
|
return;
|
2017-09-19 21:01:26 +07:00
|
|
|
}
|
|
|
|
printf("invalid\n");
|
|
|
|
}
|
|
|
|
```
|
|
|
|
下面我们构造一个恶意的动态链接库来重载 `strcmp()` 函数,编译为动态链接库,并设置 LD_PRELOAD 环境变量:
|
|
|
|
```
|
|
|
|
$ cat hack.c
|
|
|
|
#include<stdio.h>
|
|
|
|
#include<stdio.h>
|
|
|
|
int strcmp(const char *s1, const char *s2) {
|
|
|
|
printf("hacked\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
$ gcc -shared -o hack.so hack.c
|
|
|
|
$ gcc ldpreload.c
|
2017-10-11 17:22:24 +07:00
|
|
|
$ ./a.out
|
2017-09-19 21:01:26 +07:00
|
|
|
asdf
|
|
|
|
invalid
|
|
|
|
$ LD_PRELOAD="./hack.so" ./a.out
|
|
|
|
asdf
|
|
|
|
hacked
|
|
|
|
correct
|
|
|
|
```
|
|
|
|
|
|
|
|
#### LD_SHOW_AUXV
|
|
|
|
AUXV 是内核在执行 ELF 文件时传递给用户空间的信息,设置该环境变量可以显示这些信息。如:
|
|
|
|
```text
|
|
|
|
$ LD_SHOW_AUXV=1 ls
|
|
|
|
AT_SYSINFO_EHDR: 0x7fff41fbc000
|
|
|
|
AT_HWCAP: bfebfbff
|
|
|
|
AT_PAGESZ: 4096
|
|
|
|
AT_CLKTCK: 100
|
|
|
|
AT_PHDR: 0x55f1f623e040
|
|
|
|
AT_PHENT: 56
|
|
|
|
AT_PHNUM: 9
|
|
|
|
AT_BASE: 0x7f277e1ec000
|
|
|
|
AT_FLAGS: 0x0
|
|
|
|
AT_ENTRY: 0x55f1f6243060
|
|
|
|
AT_UID: 1000
|
|
|
|
AT_EUID: 1000
|
|
|
|
AT_GID: 1000
|
|
|
|
AT_EGID: 1000
|
|
|
|
AT_SECURE: 0
|
|
|
|
AT_RANDOM: 0x7fff41effbb9
|
|
|
|
AT_EXECFN: /usr/bin/ls
|
|
|
|
AT_PLATFORM: x86_64
|
|
|
|
```
|