linux文件过滤的实现

本文介绍了Linux系统中文件过滤的两种实现方式:一是通过修改系统调用表来劫持系统函数;二是利用Linux安全模块(LSM)注册新的模块。由于第一种方法在MIPS架构上难以实现,而第二种方法在Linux 2.6之后也变得困难,文章提出了通过劫持VFS(虚拟文件系统)进行文件过滤的方案。提供了具体的源码实现,并欢迎读者指正不足。
在80386的cpu基础上    个人认为linux操作系统实现系统劫持最简单的方法有两种


一 系统调用层, 系统调用是基于中断机制,所以系统调用表是中断描述表(位于idtr)中的某一项,可以从idtr寄存器读取idt(中断描述表)的基址,并搜索sys_call的

关键字"\xff\x14\x85 "  来寻找sys_call的基址,然后将某个系统函数调用的地址替换掉来实现劫持。


二 linux安全模块-----lsm。通过注册新的lsm模块来完成系统劫持。



第一种方法在mips架构上无法实现的。第二种方法继linux2.6以后也很难实现。




不过还有一种较好的方法就是对linux的 vfs-------虚拟操作系统进行劫持。

具体实现的源码如下



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


MODULE_DESCRIPTION("By utilizing the VFS filesystem, this module can capturesystem calls.");
MODULE_LICENSE("GPL");

char *root_fs="/media/.greesec";


typedef ssize_t (*read_t) (struct file *, char __user *, size_t, loff_t *);

typedef ssize_t(*write_t) (struct file *, const char __user *, size_t, loff_t *);


read_t orig_root_read=NULL;
write_t orig_root_write=NULL;


struct file *filep=NULL;

#define PATH_LEN 256
#define STRLEN 1024
char path[PATH_LEN]={0};




void encrypt(char * tran_buf,char * keyword)
{
	int tlen=strlen(tran_buf);
	printk("str_enc :%s,tlen=%d\n",tran_buf,tlen);
	while(tlen!=0)
	{
//简单的取反加密
		tran_buf[tlen-1]=~tran_buf[tlen-1];
		tlen--;

	}	
}

void decrypt(char * tran_buf,char * keyword)
{
	int tlen=strlen(tran_buf);
	printk("str_dec :%s,tlen=%d\n",tran_buf,tlen);
	while(tlen!=0)
	{

		tran_buf[tlen-1]=~tran_buf[tlen-1];
		tlen--;

	}

}




ssize_t myread(struct file *fp, char __user *buffer, size_t len, loff_t *offset)
{

	ssize_t len_t=orig_root_read(fp,buffer,len,offset);
	ssize_t r=len_t;	
	unsigned long ret;
	
	//printk("%s\n",d_path(&(fp->f_path),path,PATH_LEN));
	
	if(strncmp("/media",d_path(&(fp->f_path),path,PATH_LEN),strlen("/media"))==0){
	
		char tran_buf[STRLEN]={0};

		printk("path:  %s len:%zd\n",d_path(&(fp->f_path),path,PATH_LEN),len);

		if(len_t-STRLEN<0)
		{
			printk("myread before decrypt:%s\n",buffer);
			ret=copy_from_user(tran_buf,buffer,len_t);
			decrypt(tran_buf,"greesec");
			ret=copy_to_user(buffer,tran_buf,len_t);
			printk("myread after decrypt:%s\n",buffer);
		}else{
			char *p=buffer;
			while(len_t-STRLEN>0){
			
				printk("myread before decrypt:%s\n",p);
				ret=copy_from_user(tran_buf,p,STRLEN-1);
				decrypt(tran_buf,"greesec");
				ret=copy_to_user(p,tran_buf,STRLEN-1);
				printk("myread after decrypt:%s\n",p);
				p+=STRLEN-1;
				len_t-=STRLEN-1;
			}

			printk("myread before decrypt:%s\n",p);
			ret=copy_from_user(tran_buf,p,len_t);
			decrypt(tran_buf,"greesec");
			ret=copy_to_user(p,tran_buf,len_t);
			printk("myread after decrypt:%s\n",p);
			
		}
	}
	return r;

}


ssize_t mywrite(struct file *fp, char __user *buffer, size_t len, loff_t *offset)
{
	ssize_t r=0;
	int len_t=strlen(buffer);
	unsigned long ret;
	if(strncmp("/media",d_path(&(fp->f_path),path,PATH_LEN),strlen("/media"))==0){
		
		char tran_buf[STRLEN]={0};
		printk("path:  %s len:%zd\n",d_path(&(fp->f_path),path,PATH_LEN),len);

		if(len_t-STRLEN<0)
		{
			printk("mywrite before encrypt:%s\n",buffer);
			ret=copy_from_user(tran_buf,buffer,len_t);
			decrypt(tran_buf,"greesec");
			ret=copy_to_user(buffer,tran_buf,len_t);
			printk("mywrite after decrypt:%s\n",buffer);
		}else{
			char *p=buffer;
			while(len_t-STRLEN>=0){
				printk("mywrite before encrypt:%s\n",p);
				ret=copy_from_user(tran_buf,p,STRLEN-1);
				decrypt(tran_buf,"greesec");
				ret=copy_to_user(p,tran_buf,STRLEN-1);
				printk("mywrite after decrypt:%s\n",p);
				p+=STRLEN-1;
				len_t-=STRLEN-1;
			}
			printk("mywrite before encrypt:%s\n",p);
			ret=copy_from_user(tran_buf,p,len_t);
			decrypt(tran_buf,"greesec");
			ret=copy_to_user(p,tran_buf,len_t);
			printk("mywrite after decrypt:%s\n",p);
			
		}
		
	}

	
	r=orig_root_write(fp,buffer,len,offset);
	return r;
}


int intercept_vfs(const char *p)
{


	struct file_operations *fp=NULL;	

	filep=filp_open(p,O_RDONLY|O_CREAT,0);

	if(IS_ERR(filep)){
		printk("filp_open is error in pathc_vfs\n");
		return -1;
	}


	fp =(struct file_operations *)filep->f_op;

//intercept
	read**************************************************************
	orig_root_read= filep->f_op->read;
	fp->read=myread;

//intercept
	wirte**************************************************************
	orig_root_write=filep->f_op->write;
	fp->write=(write_t)mywrite;





//	filp_close(filep,0);

	return 0;
}

int recove_vfs(const char *p)
{
	struct file_operations *fp=NULL;

	/*filep=filp_open(p,O_RDONLY,0);
	if(IS_ERR(filep)){
		printk("file_ipen is error is unpatch_vfs\n");
		return -1;
	}
	*/
	fp = (struct file_operations *)(filep->f_op);



	//recover read**************************************************************
	fp->read=orig_root_read;

	//recover wirte**************************************************************
	fp->write=orig_root_write;



	filp_close(filep,0);
	return 0;
}

static int init(void)
{
	intercept_vfs(root_fs);
	return 0;
}
static void cleanup(void)
{
	recove_vfs(root_fs);
}
module_init(init);
module_exit(cleanup);






不足之处,敬请指出

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值