📜 ⬆️ ⬇️

Anti-rootkit for Userland-RootKit Azazel "on the knee"

Here's some awesome news from ValdikSS user - New Userland-RootKit Azazel . Let me quote the first paragraph:

You may have heard about Jynx and Jynx2 rootkits. These are the so-called userland rootkits; they use the LD_PRELOAD variable feature, which allows you to load any libraries before the program is launched. They are already relatively old, but still work well.
2 days ago, Github-user Chokepoint posted a rootkit Azazel. It is based on the Jynx source code and has many new features:

Anti-debugging mechanisms
Hiding from unhide, lsof, ps, ldd
Hiding files and directories
Hiding remote connections
Hiding processes
Hiding logins
Hiding from local traffic sniffing via PCAP
2 backdoors with full shell (with PTY):
- Crypthook accept () - backdoor
- Normal accept () - backdoor
PAM backdoor for authentication by any user
Clearing utmp / wtmp logs for PTY
Obfuscating compiled library lines with xor.

')
Thus, the rootkit uses the regular ability to load any library via LD_PRELOAD . The question is, is it possible to somehow control it?



In order not to be verbose, I will immediately present a simple solution for the Linux kernel, which, intercepting the execve function (or rather sys_execve ), scans the parameters of the list of environment variables (known as envp ) for the presence of a specific string in them, namely the very LD_PRELOAD .

So, the solution is designed as a kernel module. The function interception is based on the methods described earlier in the articles:



To intercept the sys_execve function, use the following code:

 DECLARE_KHOOK(sys_execve); long khook_sys_execve( const char __user * file, const char __user * const __user * argv, const char __user * const __user * envp ) { long result; KHOOK_USAGE_INC(sys_execve); scan_env_for((void *)file, (void *)envp, env_token); result = KHOOK_ORIGIN(sys_execve, file, argv, envp); KHOOK_USAGE_DEC(sys_execve); return result; } 


Immediately before making the original call of the intercepted function sys_execve , a search is made for matching environmental variables with the specified string env_token . This makes the simple scan_env_for function:

 void scan_env_for(char * file, char * envp[], const char * token) { int i; char * string; char * string_ptr; if (!envp || !token) return; string = kmalloc(MAX_ARG_STRLEN + 1, GFP_KERNEL); if (!string) { debug("Can't get memory for the environ string\n"); return; } for (i = 0; i < MAX_ARG_STRINGS; i++) { if (get_user(string_ptr, envp + i)) { debug("Can't get user pointer value\n"); goto out_kfree; } if (string_ptr == NULL) goto out_kfree; if (strncpy_from_user(string, string_ptr, MAX_ARG_STRLEN) == -EFAULT) { debug("Can't get user string\n"); goto out_kfree; } string[MAX_ARG_STRLEN] = 0; if (strncmp(string, token, strlen(token)) == 0) { char * filename; filename = kmalloc(PATH_MAX + 1, GFP_KERNEL); if (filename) { strncpy_from_user(filename, file, PATH_MAX + 1); filename[PATH_MAX] = 0; } debug("Attention, task \"%s\" trying to execute \"%s\" with \"%s\"\n", \ current->comm, filename ? filename : "(unknown)", string); kfree(filename); goto out_kfree; } } out_kfree: kfree(string); } 


As you can see, when it is launched, memory is allocated and all possible string elements of environment variables are scanned. At the end of the scan, the memory is accordingly freed. In case the required string was found in the kernel log, a warning will be displayed.

To verify that the module is working, after its assembly, you can do the following:

 $ sudo insmod envscan.ko env_token=\"LD_PRELOAD=\" $ dmesg | grep envscan [37713.809903] [envscan] Symbol "module_free" found @ ffffffff810bdcd0 [37713.810190] [envscan] Symbol "module_alloc" found @ ffffffff810407e0 [37713.810523] [envscan] Symbol "sort_extable" found @ ffffffff81048a90 [37713.810524] [envscan] Hunting for "LD_PRELOAD=" [37713.811798] [envscan] Symbol "sys_execve" found @ ffffffff8119ba30 $ LD_PRELOAD=/lib/ld-linux.so.2 ls [37743.786499] [envscan] Attention, task "bash" trying to execute "/bin/ls" with "LD_PRELOAD=/lib/ld-linux.so.2" 


Thus, we can say that for paranoid users there is a solution that allows, if desired, to protect against the troubles associated with the capabilities of LD_PRELOAD .

For those who are less panicked, this material can serve as a source of information on how to work with the kernel, namely, intercept its functions and modify the behavior of the system.

Module code is available on github .

Source: https://habr.com/ru/post/212825/


All Articles