Linux入侵监测系统LIDS原理Word格式.docx

上传人:b****6 文档编号:17630325 上传时间:2022-12-07 格式:DOCX 页数:22 大小:27.60KB
下载 相关 举报
Linux入侵监测系统LIDS原理Word格式.docx_第1页
第1页 / 共22页
Linux入侵监测系统LIDS原理Word格式.docx_第2页
第2页 / 共22页
Linux入侵监测系统LIDS原理Word格式.docx_第3页
第3页 / 共22页
Linux入侵监测系统LIDS原理Word格式.docx_第4页
第4页 / 共22页
Linux入侵监测系统LIDS原理Word格式.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

Linux入侵监测系统LIDS原理Word格式.docx

《Linux入侵监测系统LIDS原理Word格式.docx》由会员分享,可在线阅读,更多相关《Linux入侵监测系统LIDS原理Word格式.docx(22页珍藏版)》请在冰豆网上搜索。

Linux入侵监测系统LIDS原理Word格式.docx

如果你要杀死一个进程的话,首先,你键入“ps”来得到进程的PID,然后,你键入“kill〈pid〉”来杀死它。

但是,如果我不让你看到进程,你怎么来杀死这个进程呢?

因此,LIDS是用隐藏进程来保护它的。

  另外一个重要的方法就是不让任何人可以杀死进程,包括root用户。

LIDS能够保护父进程是init(pid=1)的所有进程。

  封装内核。

有时候我们需要要把一些必要的模块加入到内核里来使用,另外,我们也要拒绝任何人包括root用户向内核插入模块。

那么如何来平衡这个矛盾的问题呢?

我们可以只允许在系统启动的时候插入模块,然后我们封装模块,在封装后,内核不允许任何人插入模块到内核里。

通过这种封装功能,我们能用它来保护重要的文件,进程,我们可以在系统启动的时候只允许必要的进程,只改变必要的文件。

在封装内核后,我们就不能在对文件有任何的修改。

二、保护文件系统

  2.1保护文件系统是LIDS的重要功能之一。

这个功能是在内核的VFS(虚拟文件系统)层实现的,我们可以保护任何种类的文件系统,如EXT2,FAT。

  在LIDS,保护的文件按种类分为以下几种:

  只读的文件或目录。

只读文件意味着它们不被允许改写,如,在目录/usr/bin,/sbin。

这些类型的文件大多数都是二进制系统程序或是系统配置文件,除了在升级系统的时候,我们不需要改变它们。

  只可增加文件或目录。

这些文件是那些只可以增加大小的文件。

大多数是系统的日值文件,如在/var/log里的只可增加文件。

  额外的文件或目录,这些文件没有被保护。

一般来说,你想要保护目录下的所有文件,但是,还需要有一些特殊的文件不要被保护。

所以我们可以定义这些文件作为额外的其他的只读文件。

  保护挂载或卸载文件系统。

当你在启动的时候挂载文件系统的时候,你可以禁止所有人,甚至是root,去卸载文件系统。

你也可以禁止任何人在当前文件系统下挂载文件系统来覆盖它。

  2.2LIDS如何在内核保护文件

  在这部分,我们会看到一些内核的代码来理解LIDS是如何保护文件的。

  Linux文件系统数据结构程序

  首先,我们必须了解Linux的虚拟文件系统。

  在Linux里的每一个文件,不管是什么样子的,都有一个结点inode数,文件系统提供了以下数据结构。

在/usr/src/Linux/include/Linux/fs.h

structinode{

structlist_headi_hash;

structlist_headi_list;

structlist_headi_dentry;

unsignedlongi_ino;

---->

inodenumber.

unsignedinti_count;

kdev_ti_dev;

devicenumber.

umode_ti_mode;

nlink_ti_nlink;

uid_ti_uid;

......

}

  注意:

用来鉴定一个结点inode。

这个意思是你可以用一对来得到一个系统里独一无二的inode。

在/ur/src/Linux/cinclude/Linux/dcache.h里

structdentry{

intd_count;

unsignedintd_flags;

structinode*d_inode;

/*Wherethenamebelongsto-NULLisnegative*/

structdentry*d_parent;

/*parentdirectory*/

structdentry*d_mounts;

/*mountinformation*/

structdentry*d_covers;

structlist_headd_hash;

/*lookuphashlist*/

structlist_headd_lru;

/*d_count=0LRUlist*/

structlist_headd_child;

/*childofparentlist*/

structlist_headd_subdirs;

/*our

  dentry是一个目录文件的入口。

通过这个入口,我们可以很容易的在文件的父目录下移动。

  例如,如果你一文件的inode是(structinode*)file_inode,如果你可以用file_inode->

d_entry来得到它的目录入口并且用file_inode->

d_entry->

d_parent来得到父目录的目录入口。

LIDS保护数据结构

  在分析完Linux文件系统后,让我们来看看LIDS是如何容VFS来保护文件和目录的。

在/usr/src/Linux/fs/lids.c

structsecure_ino{

unsignedlongintino;

/*theinodenumber*/

kdev_tdev;

/*thedevnumber*/

inttype;

/*thefiletype*/

};

  上面的结构用一对来存储保护文件或目录的结点。

“type”是用来标明保护结点文件类型的。

  LIDS有4种类型

  在/usr/src/Linux/include/Linux/fs.h

  #defineLIDS_APPEND1/*APPENDONLYFILE*/

  #defineLIDS_READONLY2/*ReadOnlyFile*/

  #defineLIDS_DEVICE3/*ProtectMBRWritingtodevice*/

  #defineLIDS_IGNORE4/*Ignoretheprotection*/

  通过secure_ino结构,我们能很容易的初使化保护的文件或是在内核里执行以下函数。

intlids_add_inode(unsignedlongintinode,kdev_tdev,inttype)

{

if(last_secure==(LIDS_MAX_INODE-1))

return0;

secure[last_secure].ino=inode;

secure[last_secure].dev=dev;

secure[last_secure].type=type;

secure[++last_secure].ino=0;

#ifdefVFS_SECURITY_DEBUG

printk("

lids_add_inode:

return%d

"

last_secure);

#endif

returnlast_secure;

  就象你在上面代码上可以看到的,给secure_ino加到一个结点上是非常容易的。

被保护的结点会在系统启动的时候初使化。

初使化程序在/usr/src/Linux/fs/lids.c的init_vfs_security()里。

  现在,让我们看看LIDS是如何来检查是否一个结点已经受到保护。

在/usr/src/Linux/fs/open.c

intdo_truncate(structdentry*dentry,unsignedlonglength)

structinode*inode=dentry->

d_inode;

interror;

structiattrnewattrs;

/*Notpretty:

"

inode->

i_size"

shouldntreallybe"

off_t"

.Butitis.*/

if((off_t)length<

0)

return-EINVAL;

#ifdefCONFIG_LIDS

if(lids_load&

&

lids_local_load){

error=lids_check_base(dentry,LIDS_READONLY);

if(error){

lids_security_alert("

Trytotruncateaprotectedfile(dev%d%d,inode%ld)"

MAJOR(dentry->

d_inode->

i_dev),

MINOR(dentry->

dentry->

i_ino);

.....................

  这个是LIDS加到内核里做检测的一个例子。

你会看到lids_check_base()是LIDS保护方法的一个核心函数。

  你可以在LIDS要保护的地方看到很多LIDS保护方法用到lids_check_base()函数,特别是在Linux内核的子目录下。

intlids_check_base(structdentry*base,intflag)

..................

inode=base->

/*gettheinodenumber*/

parent=base->

d_parent;

/*gettheparentdiretory*/

.................

---->

do{

if(inode==parent->

d_inode)

break;

if((retval=lids_search_inode(inode))){

if(retval==LIDS_IGNORE||

(retval==LIDS_DEVICE&

flag!

=LIDS_DEVICE))

if(flag==LIDS_READONLY||

(flag==LIDS_APPEND&

retval>

flag)||

(flag==LIDS_DEVICE&

flag==retval)){

return-EROFS;

inode=parent->

}while(((parent=parent->

d_parent)!

=NULL));

lids_check_base()会检查一个给定文件的dentry和它的父目录是否被保护。

如果它的父目录被保护,它下面的文件也会被保护。

  例如,如果“/etc/”被保护,“/etc/passwd”也一样被保护。

在内核保护系统调用

  为了保护系统,LIDS会在一些检查临界的系统调用的时候做检查。

因此,我们可以保护系统调用和限制文件系统的用户调用。

  这些是一些例子,

  open(),open是通过禁止一些权利来保护文件的打开。

你可以在打开调用open_namei()调用的时候LIDS在检测它。

  mknod(),mknod是用来在指定目录下保护mknod。

  unlink(),在内核代码检查do_unlink()。

  三、保护设备

  Linux的设备会在/dev/目录下以文件的形式列出,我们可以用上面保护文件的方法来保护设备。

但是在一些情况下,用户也可以用IO操作来旁路文件系统来读写设备,我们必须注意这个问题。

  3.1设备,内核I/O

  在GNU/Linux系统下的设备会以文件的形式表达,所以我们可以用保护文件系统那样来保护设备。

  用户的I/O访问是通过系统调用sys_operm和sys_iopl来实现的。

你可以看看/usr/src/Linux/arch/i386/kernel/ioport.。

这个是要基于系统结构的,要是到其他平台,就需要注意它们的变化。

  3.2如何用LIDS来保护

  大多数情况下,程序不需要通过在/dev的设备文件名称来访问设备。

但是,一些特殊的程序需要直接访问,如XServer,这个会写到/dev/mem和甚至是I/O设备。

我们需要一些额外的东西来保护设备。

LIDS会在配置内核的时候来定义这个功能。

  CONFIG_LIDS_ALLOW_DEV_MEM,如果你选择了开启这个功能,你就可以允许一些特殊程序来访问/dev/men和/dev/kmen这些内核临界的设备。

如果你想要用内核的XServer,选择这个功能就会在配置内核的时候提供整个路径和文件名。

  CONFIG_LIDS_ALLOW_RAW_DISKS,如果选择这个开启,你就可以允许一些特殊的程序来访问物理磁盘。

  CONFIG_LIDS_ALLOW_IO_PORTS,如果你选择了开启这个功能,你就可以允许一些特殊的程序来访I/O端口。

  当系统运行fs/lids.c里的init_vfs_security()的时候初使化就被调用。

#ifdefCONFIG_LIDS_ALLOW_DEV_MEM

lids_fill_table(allow_dev_mem,&

last_dev_mem,LIDS_MAX_ALLOWED,CONFIG_LIDS_DEV_MEM_PROGS);

#ifdefCONFIG_LIDS_ALLOW_RAW_DISKS

lids_fill_table(allow_raw_disks,&

last_raw_disks,LIDS_MAX_ALLOWED,CONFIG_LIDS_RAW_DISKS_PROGS);

#ifdefCONFIG_LIDS_ALLOW_IO_PORTS

lids_fill_table(allow_io_ports,&

last_io_ports,LIDS_MAX_ALLOWED,CONFIG_LIDS_IO_PORTS_PROGS);

  如果一个进程或是程序要直接访问ip端口或是磁盘设备,LIDS就会检查它在数组allow_raw_disk,last_io_ports,等)。

这个检查是通过调用lids_check_base()里的lids_search_inode(inode)来实现的。

  如,让我们看看CONFIG_LIDS_ALLOW_DEV_MEM

/*inlids_search_inode()*/

for(i=0;

i<

last_dev_mem;

i++){

if(allow_dev_mem[i].ino==ino&

allow_dev_mem[i].dev==dev){

returnLIDS_READONLY;

  在allow_dev_mem包括了哪一个程序结点在系统启动的时候在init_vfs_security()里初使化。

用同样的方法,除了一些特殊程序,我们可以保护设备,I/O访问等等。

  四、保护重要进程

  进程是操作系统的动态入口。

内核里有两个特殊进程,进程ID0(swapd)和进程ID1(init)。

Init进程是在系统启动的时候所有进程的父进程。

  4.1不可杀死的进程。

  就象你可以看到是否有人要夺得root特权一样,我们可以很容易的杀死那些该内核发送特别信号的进程。

为了杀死一个进程,你必须得到进程的ID,然后用kill命令来杀死它。

  系统杀死进程的调用是kill,是在内核里的sys_kill()命令里的调用。

  让我们看看LIDS的保护代码

在/usr/src/Linux/kernel/signal.c里

asmlinkageint

sys_kill(intpid,intsig)

structsiginfoinfo;

#ifdefCONFIG_LIDS_INIT_CHILDREN_LOCKpid_tthis_pid;

inti;

#ifdefCONFIG_LIDS_ALLOW_KILL_INIT_CHILDREN

if(!

(current->

flags&

PF_KILLINITC))

lids_local_load&

LIDS_FISSET(lids_flags,LIDS_FLAGS_LOCK_INIT_CHILDREN)){

this_pid=pid>

0?

pid:

-pid;

for(i=0;

iif(this_pid==lids_protected_pid[i]){

Trytokillpid=%d,sig=%d

pid,sig);

return-EPERM;

...

你可以在内核里看到两个标签,,CONFIG_LIDS_INIT_CHILDREN_LOCK和CONFIG_LIDS_ALLOW_KILL_INIT_CHILDREN.

  在CONFIG_LIDS_INIT_CHILDREN_LOCK的开启状态,LIDS能保护初使的运行程序。

如,如果你在系统里运行inetd程序,你可以在隐藏内核前运行它,然后,你还可以杀死它。

但是一些人如果telnet到你的机器,inetd就会创造子进程来为用户服务,这个子进程不会被LIDS保护,因为用户在任何时候退出和杀死程序。

4.2隐藏进程

  另外一个保护进程的方法就是隐藏进程。

当一个黑客危机你的系统。

他会登陆,然后会看看有没有一些已知的进程在监视它。

然后他就杀死它。

如果你隐藏了这个功能的进程,黑客就不会知道进程的所有情况并且你可以记录他在你系统上做的任何事情。

  如何隐藏进程

  为了隐藏进程,你必须在配置内核的时候提供一个完全的路径名。

  当内核启动的时候,LIDS会访问文件结点到一个叫proc_to_hide[]的结构里。

在include/Linux/sched.h里

#ifdefCONFIG_LIDS_HIDE_PROC

#definePF_HIDDEN0x04000000/*Hiddenprocess*/

/*infs/lids.c*/

structallowed_inoproc_to_hide[LIDS_MAX_ALLOWED];

intlast_hide=0;

....

/*infs/lids.c,init_vfs_security(),

fillupthehiddenprocessinproc_to_hide[]

*/

lids_fill_table(proc_to_hide,&

last_hide,LIDS_MAX_ALLOWED,CONFIG_LIDS_HIDDEN_PROC_PATH);

  PF_HIDDEN是否用户可以用显示进程的命令(如“ps–a”)来显示和检查进程,如果一个进程被LIDS隐藏,当他执行的时候,进程就会得到一个PF_HIDDEN的属性。

然后,当系统输出系统进程信息到用户的时候,它就会可以检查当前输出进程是否有PF_HIDDEN标志。

如果发现了,它就不会输出这个进程的信息。

在infs/exec.c

intdo_execve(char*filename,char**argv,char**envp,structpt_regs*regs)

if(retval>

=0){

if(lids_search_proc_to_hide(dentry->

d_inode))

current->

flags|=PF_HIDDEN;

  因为每一个Linux的进程都有一个在/proc文件系统的入口,我们为了隐藏进程也需要修改proc的文件入口。

在fs/proc/root.c

staticstructdentry*proc_root_lookup(structinode*dir,structdentry*dentry)

inode=NULL;

#if

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 理化生

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1