⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_hunter.c

📁 也是一个linux系统下的网络入侵检测程序
💻 C
字号:
/* * name: module hunter 2.6 ver 1.4 * first release date: 04.9.6 * test on 2.6.5-2.6.10 (normal)/RedHat FC2 (2.6.5) * *  Author: *  2003 		madsys   Implemented original code *  *  Fix: *  2004.7	madsys	made it works on 2.6 kernel *  2004.10	CoolQ 	Added the ability of finding module on 4g/4g patch(ingo) and PAE mode *  2004.12	madsys	Added a trick for compiling on SUSE *  2004.12	madsys	Added the ability of revealing hidden module *  2004.12	madsys	Fixed the serious bug about revealing hidden module *  2004.12	madsys	Made the output more heuristic *  2005.1	madsys Cool	Fixed a bug of seeking modules throughout memory  * 					(because the stepping is not 4k, mayb the module is across a page) * * *  usage:  *  list all modules:	 insmod mh.ko && cat /proc/showmodules *  reveal the hidden module:  echo "0xaabbccdd" > /proc/showmodules *  Note: 0xaabbccdd is the address of the suspect module and it must be 10 characters *                                         */#include <linux/config.h>#ifdef CONFIG_SMP#define __SMP__ #endif#if CONFIG_MODVERSIONS == 1#define MODVERSIONS#endif#include <linux/module.h>#include <linux/kernel.h>#include <linux/version.h>#include <linux/unistd.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/proc_fs.h>#include <linux/errno.h>#include <asm/uaccess.h>#include <asm/pgtable.h>#include <asm/fixmap.h>#include <asm/page.h>#include <asm/types.h>#define HARDCORE_PD 0xc041f000#define STEPPING (PAGE_SIZE/32)#define __VMALLOC_RESERVE	(128 << 20)#define MAX_MODULE 128#ifdef __VMALLOC_RESERVE_DEFAULT#define VMALLOC_RESERVE __VMALLOC_RESERVE_DEFAULT //for SUSE#endifstatic unsigned int reveal  = 0;module_param(reveal, int, 0);typedef enum RAM_MODE{	MODE_NORMAL_4K,	MODE_NORMAL_4M,}MODE;static MODE 	mode;static u32 	cr3, cr4;struct module *listed_modules[MAX_MODULE];struct list_head *globle_module_head;unsigned int total_normal_modules;/* * valid_addr_normal_4K,valid_addr_normal_4M * valid_addr_pae_4K, valid_addr_pae_2M * do the dirty job separately * return 1 for valid * return 0 for invalid */static int valid_addr_normal_4K(u32 address){	u32 	pde, pte;	u32	cr3_tmp;	u32	pde_idx, pte_idx;	u32	addr;		if (!address)		return 0;	cr3_tmp = cr3 & 0xfffffe00;	//cr3_tmp = HARDCORE_PD;	pde_idx = address >> 22;	pte_idx = (address & 0x003ff000) >> PAGE_SHIFT;		pde = ((unsigned long *) __va(cr3_tmp))[pde_idx]; /* pde entry*/		if (pde & _PAGE_PRESENT){		addr = pde & PAGE_MASK;		//address &= 0x003ff000;		/* pte */		pte = ((unsigned long *) __va(addr))[pte_idx];		if (pte)			return 1;		else			 return 0;	}else		return 0;}static int valid_addr_normal_4M(u32 address){	u32	pde;	u32	cr3_tmp;	u32	pde_idx;	if(!address)		return 0;	cr3_tmp = cr3 & 0xfffffe00;	pde_idx = address >> 22;	pde = ((u32 *) __va(cr3_tmp))[pde_idx];	if(pde)		return 1;	else		return 0;}int valid_addr(u32 address){	switch(mode){				case MODE_NORMAL_4K:			return valid_addr_normal_4K(address);			break;		case MODE_NORMAL_4M:			return valid_addr_normal_4M(address);			break;		default:			return 0;			break;	}}unsigned int reveal_mod(struct module *evil){	if (evil && valid_addr_normal_4K((u32)&evil->list))	{		list_add(&evil->list, &THIS_MODULE->list);		printk("module revealed\n");				return 0;	}		else 		 return -EFAULT;}void get_listed_mod(void){	struct module *rover;	int listed_count=0;	if (globle_module_head->next == globle_module_head)	{		printk("No module\n");		return;	}	for (rover = list_entry(globle_module_head->next, struct module, list); ; rover=list_entry(rover->list.next, struct module, list), listed_count++)	{		if (listed_count>=MAX_MODULE)		{			total_normal_modules = MAX_MODULE;			printk("too many module!\n");			return;		}		listed_modules[listed_count]=rover;				if (rover->list.next == globle_module_head)	//first module		{			total_normal_modules = listed_count+1;			break;		}	}}int is_normal_mod(struct module *addr){	int i;	for (i=0; i<total_normal_modules; i++)	{		if (listed_modules[i] == addr)			return 1;	}	return 0;}ssize_t showmodule_read(struct file *unused_file, char *buffer, size_t len, loff_t *off){	struct module *p;	unsigned int count =1;		printk("\n      address                name     size"		"      core_addr     flags  \n\n");		__asm__ __volatile__ ( "movl %%cr3, %0" : "=r"(cr3) );	get_listed_mod();		/* brute force all the possible vms */	for (p = (struct module *)VMALLOC_START;	     p <= (struct module*)(VMALLOC_START + VMALLOC_RESERVE - PAGE_SIZE);	     p = (struct module *)((u32)p + STEPPING)){				if (valid_addr((u32)p + (u32)&((struct module *)NULL)->name)  && valid_addr((u32)p+sizeof(struct module)-1))		{			/* the valid module struct should match some rules */			if ((     (p->name[0]>=0x30 && p->name[0]<=0x39)			       || (p->name[0]> 0x41 && p->name[0]<=0x7a )) 			    && (p->core_size < 1 <<20) 			    && (p->core_size>= sizeof(struct module))			    && p->state <3			    && (u32)p->module_core > 0x02000000UL 			    && ((u32)p->module_core & 0x00000fff)  == 0)				printk("%3d  0x%p%18s   %6lu     0x%4p     %3d    %s\n", count++, 					p, p->name, p->core_size, 					p->module_core, p->state, (is_normal_mod(p)?" ":"Warning"));		}				}		 	return 0;}ssize_t showmodule_write(struct file *unused_file, const char *buffer, size_t len, loff_t *off){	char mod_string[11];	unsigned int evil_addr;	int error;	if (len != (sizeof(mod_string)))	{		printk("wrong address, it must be 10 chars,len: %d buf: %s \n", len, buffer);		return(-EINVAL);	}	if (copy_from_user(mod_string, buffer, len))	{		printk("copy characters to kernel failed\n");		return(-EFAULT);	}		mod_string[10] = '\0';		//it should be '\0' already	evil_addr = simple_strtoul(mod_string, NULL, 0);//printk("evil_addr: 0x%x\n", evil_addr);	if (evil_addr < PAGE_OFFSET)	{		printk("wrong address\n");		return -EFAULT;	}	get_listed_mod();	if (is_normal_mod((struct module *)evil_addr))	{		printk("the module which u want to reveal is not hidden\n");		return -EFAULT;	}	__asm__ __volatile__ ( "movl %%cr3, %0" : "=r"(cr3) );	if ((error = reveal_mod((void *)evil_addr)))	{			printk("reveal module failed: %d\n", error);		return -EFAULT;	}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7)printk("kobj refcount: %ud\n", ((struct module *)evil_addr)->mkobj->kobj.kref.refcount.counter);	if (kobject_register(&((struct module *)evil_addr)->mkobj->kobj))	{		printk("kobject already registered or registered failed\n");		return -EFAULT;	}#endif	return len;}static struct file_operations showmodules_ops = {		read:showmodule_read,		write:showmodule_write,};int init_module(void){	struct proc_dir_entry *entry;	u32	addr;	u32	pde, pde_idx;	/* get cr3,cr4 registers and tell the VM mode */		__asm__ __volatile__ ( "movl %%cr3, %0" : "=r"(cr3) );	__asm__ __volatile__ ( "movl %%cr4, %0" : "=r"(cr4) );	addr = (u32)&__this_module;		pde_idx = addr >> 22;	pde = ((u32 *) __va(cr3))[pde_idx];			if(pde & (1 << 7))		mode = MODE_NORMAL_4M;	else		mode = MODE_NORMAL_4K;	printk("cr3 = 0x%x\n", cr3);	printk("VM mode is %s\n", (mode == MODE_NORMAL_4K) ? "normal_4k" :"normal_4M");		entry = create_proc_entry("showmodules", S_IRUSR, &proc_root);	entry->proc_fops = &showmodules_ops;	globle_module_head = THIS_MODULE->list.prev;	return 0;}void cleanup_module(){	remove_proc_entry("showmodules", &proc_root);}MODULE_LICENSE("GPL");MODULE_AUTHOR("madsys<at>ercist.iscas.ac.cn; qufuping<at>ercist.iscas.ac.cn");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -