在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);
不足之处,敬请指出