当你安装一台Linux系统,你就拥有了一个强大的、高级的、多任务的网络操作系统。但是该系统功能有些过于强大了.某些发布版本缺省启动很多服务(如:rlogind, inetd, httpd, innd, fingerd, timed, rhsd,等等)。作为系统管理员需要熟悉了解这些服务。如果你的机器连接到了Internet的话你更需要关注你的系统安全。
大多数攻击者并不是一个革新者,他们往往利用最新的公布的系统工具技术等突破一个众所周知的或一个新的刚刚发现的安全漏洞。但作为一个管理者,通过访问你使用的Linux发布的官方站点如www.redhat.com/、http://www.calderasystems.com/等可以获知最新的安全漏洞及相应的补丁程序。也可以通过定期访问http://www.securityfocus.com/、http://www.cert.org/等安全漏洞通告站点。
最方便的的控制访问服务器的方法是通过一个叫TCP wrapper的程序。在大多数发布版本中该程序往往是缺省地被安装。利用TCP wrapper你可以限制访问前面提到的某些服务。而且TCP wrapper的记录文件记录了所有的企图访问你的系统的行为。通过last命令查看该程序的og管理员可以谁在企图连接你的系统。 在Linux的/etc目录下,有一个如下所示inetd.conf文件,该文件是TCP wrapper的配置文件,定义了TCP wrapper可以控制启动哪些服务。比如要将finger服务去除,就将finger服务的那一行注释掉(在前面加上"# "即可);
# inetd.conf This file describes the services that will be available
# through the INETD TCP/IP super server. To re-configure
# the running INETD process, edit this file, then send the # INETD
# process a SIGHUP signal。
# service_name sock_type proto flags user server_path args
ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd -l -a telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd # Finger, systat and netstat give out user information which may be 。。。 。。。
但是对于诸如sendmail,named等服务,由于它们不象finger,telnet等服务,在请求到来时由inet守护进程启动相应的进程提供服务,而是在系统启动时,作为守护进程运行的。在slackware版本的Linux,可以通过修改/etc/rc.d目录下的启动配置文件rc.M文件,将启动sendmail的命令行注释掉:
#!/bin/sh
# rc.M This file is executed by init(8) when the system is being
# initialized for one of the "multi user" run levels (i.E.
# levels 1 through 6). It usually does mounting of file
# systems et al.
# Start the sendmail daemon:
# if [ -x /usr/sbin/sendmail ]; then
# echo "Starting sendmail daemon (/usr/sbin/sendmail -bd -q 15m)… "
# /usr/sbin/sendmail -bd -q 15m
# fi 。。。。。。
对于诸如named等其他服务,也是通过将同一个目录下相应启动配置文件中相应的启动命令注释掉,从而当你重新启动机器时,相应的服务将不会启动。而对于高版本的redhat linux,提供了一个linuxconfig命令,可以通过它在图形界面下交互式地设置是否在启动时,运行相关服务。 但是对于telnet、ftp等服务,如果将其一同关闭,那么对于管理员需要远程管理时, 将非常不方便。Linux提供另外一种更为灵活和有效的方法来实现对服务请求用户的限制, 从而可以在保证安全性的基础上,使可信任用户使用各种服务。 在/etc目录下,有两个文件:hosts.deny hosts.allow 通过配置这两个文件,你可以指定 哪些机器可以使用这些服务,哪些不可以使用这些服务。 配置这两个文件是通过一种简单的访问控制语言来实现的,访问控制语句的基本格式为:
程序名列表,主机名/IP地址列表。
程序名列表指定一个或者多个提供相应服务的程序的名字,名字之间用逗号或者空格分割,可以在inetd.conf文件里查看提供相应服务的程序名:如上面的文件示例中,telent所在行的最后一项就是所需的程序名:in.telnetd 主机名/IP地址列表指定允许或者禁止使用该服务的一个或者多个主机的标识,主机名之间用逗号或空格分隔。程序名和主机地址都可以使用通配符,实现方便的指定多项服务和多个主机。 当服务请求到达服务器时,访问控制软件就按照下列顺序查询这两个文件,直到遇到一个匹配为止:
1. 当在/etc/hosts.allow里面有一项与请求服务的主机地址项匹配,那么就允许该主机获取该服务
2. 否则,如果在/etc/hosts.deny里面有一项与请求服务的主机地址项匹配,就禁止该主机使用该项服务 如果相应的配置文件不存在,访问控制软件就认为是一个空文件,所以可以通过删除或者移走配置文件实现对所有主机关闭所有服务。在文件中,空白行或者以#开头的行被忽略,你可以通过在行前加 # 实现注释功能。 Linux提供了下面灵活的方式指定进程或者主机列表:
1. 一个以"。"起始的域名串,如 .amms.ac.cn 那么www.amms.ac.cn就和这一项匹配成功 2. 以.结尾的IP串如 202.37.152. 那么IP地址包括202.37.152. 的主机都与这一项匹配 3. 格式为n.n.n.n/m.m.m.m表示网络/掩码,如果请求服务的主机的IP地址与掩码的位与的结果等于n.n.n.n 那么该主机与该项匹配。
4. ALL表示匹配所有可能性
5. EXPECT表示除去后面所定义的主机。如:list_1 EXCEPT list_2 表示list_1主机列表中除去List_2所列出的主机
6. LOCAL表示匹配所有主机名中不包含。的主机 上面的几种方式只是Linux提供的方式中的几种,但是对于我们的一般应用来说是足够了。我们通过举几个例子来说明这个问题: 例一:
我们只希望允许同一个局域网的机器使用服务器的ftp功能,而禁止副广域网上面的ftp服务请求,本地局域网由 202.39.154. 、202.39.153. 和202.39.152. 三个网段组成。 在hosts.deny文件中,我们定义禁止所有机器请求所有服务: ALL:ALL 在hosts.allow文件中,我们定义只允许局域网访问ftp功能: in.ftpd -l -a: 202.39.154 202.39.153. 202.39.152. 这样,当非局域网的机器请求ftp服务时,就会被拒绝。而局域网的机器可以使用ftp服务。
ALL:ALL
然后重新启动你的 inetd进程:
/etc/rc.d/init.d/inet restart
但是hosts.deny文件只能控制/etc/inetd.conf文件中包含的服务的访问这些服务有/usr/bin/tcpd管理。wrapper监听接入的网络请求,然后与在hosts.allow和hosts.deny的中的服务比较,然后做出允许或拒绝的决定。 files, and makes a yes or no decision on what to allow through. 但是对于wrapper没有包含的服务你就需要采用其他方法了
有个笑话里说一个小偷进入到一家,偷光了屋子里所有的东西,但是却用一个相同的拷贝代替了偷走的东西。但是在网络攻击环境下,这却是可能发生的。当一个攻击者利用一个系统漏洞非法入侵进入到你的系统。当你使用ps命令列出系统中的所有的进程时,却看不到什么异常的证据。你查看你的password文件,一切也是那么的正常。到底发生了什么事情呢?当系统进入到你的系统以后,第一步要做的事情就是取代系统上某些特定的文件:如netstat命令等。当你使用netstat -a命令时,就不会显示系统攻击者存在的信息。当然攻击者将替代所有的可能泄露其存在的文件。一般来说包括:
/bin/ps
/bin/netstat
/usr/bin/top
由于这些文件已经被取代。所以简单的利用ls命令查看这些文件是看不出什么破绽的。有若干种方法你可以验证系统文件的完整性。如果你安装的是Red Hat, Caldera, TurboLinux或任何使用RPM的系统。你可以利用RPM来验证系统文件的完整性:
首先你应该查明你的那些你需要查看的文件来自哪个软件包,使用rpm命令你可以查明某个文件属于某个包:
# rpm -qf /bin/netstat
net-tools-1.51-3
然后,可以扫描整个rpm包来查看那些发生了改变。对没有发生改变的包使用该命令将没有任何输出信息,如下所示:
# rpm -V net-tools
将netstat的5.2版本的二进制可执行文件替换为6.0的版本以后再使用该命令的结果为:
.......T /bin/netstat
这说明/bin/netstat/文件已经被修改。若我使用rpm -qf测试ps和top命令可以得到其属于包procps,然后在验证包procps的完整性。下面是一个被黑的站点的结果:
# rpm -qf /bin/ps
procps.2.0.2-2
# rpm -V procps
SM5..UGT /bin/ps
SM5..UGT /usr/bin/top
攻击者入侵到系统中,并且用自己的ps及top命令替代了我们系统中的命令。从而使管理员看不到其运行的进程,也许是一个sniffer来监听所有的用户所有进出网络的数据并找寻到密码信息。
下面是一个小的script来扫描你系统的所有的rpm库,并检查所有的包是否被篡改。但是应该注意的是并不是所有该scripts报告的问题都是说明该系统文件被攻击者破坏。例如你的apssword文件一般肯定和你安装系统时是不同的:
#!/bin/bash
#
# Run through rpm database and report inconsistencies
#
for rpmlist in `rpm -qa` # These quotes are back quotes
do
echo " ----- $rpmlist -----" ; rpm -V $rpmlist
done > /tmp/rpmverify.out
当你运行该scripts时,输出被定向到文件/tmp/rpmverify.out你可以使用less命令查看该文件。但是由于文本文件如:/etc/passwd, /etc/inetd.conf等很可能显示为被修改过。但是你如何知道这些是管理员自己修改的还是入侵者修改的呢方法是在你确保你的系统是干净的,没有被攻击者入侵时,你为这些系统文件创建指纹信息。在你怀疑你的系统被入侵时使用这些这些指纹信息来判定系统是否被入侵。创建文件的指纹信息是通过命令md5sum 来实现的:
# md5sum /etc/passwd
d8439475fac2ea638cbad4fd6ca4bc22 /etc/passwd
# md5sum /bin/ps
6d16efee5baecce7a6db7d1e1a088813 /bin/ps
# md5sum /bin/netsat
b7dda3abd9a1429b23fd8687ad3dd551 /bin/netstat
这些数据是我的系统上的文件的指纹信息。不同的系统上的文件的 指纹信息可能是不同的,你应该是使用md5sum来计算自己系统文件的指纹信息。下面是一些你应该创建指纹信息的文件;
/usr/bin/passwd
/sbin/portmap
/bin/login
/bin/ls
/usr/bin/top
/etc/inetd.conf
/etc/services
当netstat,ls等命令被修改,从而发现系统已经被入侵,下面该怎么办?根据你系统的重要性的不同,你有很多种选择。但是我推荐对用户目录,password及其他关键的系统文件进行备份。然后重新安装系统。但是不要随便就将备份的文件拷贝到新系统,因为攻击者可能在这些文件中隐藏一些非法的东西。
也可以不重新安装系统,而是通过TCP wrapper来限制对主机的访问,并且关闭非关键的网络服务。然后更新被影响的包。重新干净的启动系统是很重要的,但是要实现这点并不容易。若你发现procps或net-tools包已经被攻击者修改,第一件事情是重新安装干净的包来替换被攻击者做了手脚留下后门的包。一般最好从你的系统发布者处得到最新的包来重新安装一旦攻击者进入到系统其就将在系统上存放一些工具并且将之隐藏起来,使你不容易发现。下面是一个事实在在的被攻击者入侵的系统的实例。当系统被攻击者入侵,服务器被限制网络访问,并且替代所有的受影响的包。然后就需要通过仔细查看log文件来发现重复的企图进入系统。查看/etc/passwd文件,发现一个不属于合法的用户。进入到该用户的目录下:/home/jon,运行 "ls -l"得到如下的内容:
. .. .. .bashrc .bash_history .screenrc emech.tar.gz
除了一个名字为emech.tar.gz的文件以外,看不出什么异常现象。但是仔细观察,你就会发现系统有两个 ".."目录。(指该子目录的上一级目录)是的确很奇怪,我使用命令"cd .."我就会进入到/home目录。原来其中子目录名字是在两个点后面有一个空格。(".. ")你可以通过如下命令发现:
# cd /home/jon
# echo .* | cat -v
. .. .. .bashrc .bash_history .screenrc emech.tar.gz
仔细观察可以发现每个子目录都是被一个空格隔开,而在第二个“..”和.bashrc之间有两个空格。这就意味着第二个".."子目录其实为点-点-空格。下面进入到该目录:
# cd ".. "
然后列出该目录下的内容:
#ls
randfiles mech.set mech.pid checkmech cpu.memory
mech.help mech.usage mech mech.levels emech.users
psdevtab
下一步我们再查看是否其还在其他地方隐藏了文件:
# find / -user jon -print
除了/home/jon目录以外,还发现如下的内容;
/usr/local/bin/.httpd
/tmp/cl
/tmp/.l/bcast
/tmp/.l/.l
/tmp/.l/imapd
/tmp/.l/log
/tmp/.l/pscan
/tmp/.l/pscan.c
/tmp/.l/rpc
/tmp/.l/slice2
/tmp/.l/sniffer
/tmp/.l/sxploit
/tmp/.l/thc
/tmp/.l/ufs.c
这个入侵者已经在系统上安装了Sniffers、端口扫描器,他给自己营造了一个很好的"窝" 。在查看中,还在合法的用户的目录下发现了一个可怕的名为"tcp.log"的文件。文件该文件有几百行长,包括每一次telnet 及 ftp 出入该系统的连接!除了通告在该文件中出现的可能已经被入侵的机器管理员应该重新安装系统以外,我同样告诉他们需要重新系统的所有的用户的口令。
下面有一些例子来帮助你搜索隐藏的危险。首先查看位于用户目录的有"suid"或"guid"的文件。这些文件的可执行属性位为s而不是x。如:
#ls -s /usr/bni/passwd
-r-s--x--x 1 root root 10704 Apr 14 1999 /usr/bin/passwd
属性第四位的 "s" 表示该命令被执行时,该进程的实际有效用户ID就变为root用户。为了允许普通用户修改自己的密码,这是必须的。第七位的x若为s则表示别的组的用户若运行该程序则该程序则具有用户所有组的有效组ID。使程序能冒充特定的用户或者组并不是一件有害的事情。但是一般来说非管理用户在其目录下不应该具root-suid 程序。我们可以使用下面的命令来查寻这样的文件:
# find /home -perm -4000 -o -perm -2000 -print
下一步我们继续寻找入侵者留下的程序和文件,所以需要一个快速的寻找隐藏目录的方法。下面的方法就是寻找如".kde"的隐藏目录。你也可以找到如".. "或“..."等目录:cracker.
# find / -type d -name ".*" -print
"-type d"选项指仅仅列出目录。这个命令不会不会将"."或".."列出。
作为一个好的系统管理者,为了击败攻击者的攻击行动,最好的方法是了解攻击者的工作原理和机制。它们使用了那些工具,它们如何操作入侵等等。所以深入理解掌握我这里讲解的各种网络工具是很有必要的。
我用实例的方式说到了了一个攻击者使用sniffer监听网络流来搜集用户名和密码。下面我们就详细说明sniffer是如何工作的。简单的说,sniffer是一个使你能检测你的网络接口接收到所有的数据报。一般情况下,计算机仅仅接受目的地址是自身的数据报,而sniffer使网络接口进入杂错模式,从而可以接受网卡收到的所有的数据报。
若你运行ifconfig eth0命令,会得到下面的结果:
eth0 Link encap:Ethernet HWaddr 00:C0:4F:E3:C1:8F
inet addr:192.168.22.2 Bcast:192.168.22.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:49448 errors:0 dropped:0 overruns:0 frame:0
TX packets:33859 errors:0 dropped:0 overruns:0 carrier:0
collisions:6 txqueuelen:100
Interrupt:10 Base address:0x300
打开两个终端,一个终端里运行sniffer器-sniffit;
# sniffit -i
另外一个虚拟终端里你可以再次运行ifconfig eth0。你将会发现输出中有下面的内容:
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
注意和上面相比较,增加了一个单词"PROMISC" 这是杂错模式(promiscuous mode)的缩写,
sniffit是一个轻量级的,基于终端的sniffer器。你可以从http://reptile.rug.ac.be/~coder/sniffit/sniffit.html得到它。
另外一个类似的sniffer是netwatch,你可以从http://www.slctech.org/~mackay/netwatch.html得到它。如果你不希望在系统中安装另外的sniffer,你可以使用系统中带有的一个工具:tcpdump 这个工具虽然不如前面两个工具那么华丽,但是她可以完成所有同样的功能。
# tcpdump host www.linuxjournal.com -l | tee /tmp/tcpdump.out
其中-l指示tcpdump将输出数据存进入一个文件中。下面是输出的内容:
16:41:49.101002 www2.linuxjournal.com.www > marcel.somedomain.com.1432: F
2303148464:2303148464(0) ack 1998428290 win 16352
16:41:49.101206 marcel.somedomain.com.1432 > www2.linuxjournal.com.www: . ack
1 win 32120 (DF)
16:41:50.001024 www2.linuxjournal.com.www > marcel.somedomain.com.1429: F
1805282316:1805282316(0) ack 1988937134 win 16352
16:41:50.001215 marcel.somedomain.com.1429 > www2.linuxjournal.com.www: . ack
1 win 32120 (DF)
16:41:50.840998 www2.linuxjournal.com.www > marcel.somedomain.com.1431: F
1539885010:1539885010(0) ack 1997163524 win 16352
16:41:50.841198 marcel.somedomain.com.1431 > www2.linuxjournal.com.www: . ack
1 win 32120 (DF)
16:41:51.494356 marcel.somedomain.com.1429 > www2.linuxjournal.com.www: P
1:335(334) ack 1 win 32120 (DF)
16:41:51.497003 marcel.somedomain.com.1433 > www2.linuxjournal.com.www: S
2019129753:2019129753(0) win 32120
(DF)
16:41:51.671023 www2.linuxjournal.com.www > marcel.somedomain.com.1429:
R.
Linux系统中可以得到有很多种的sniffer。攻击者在入侵系统以后,也许会使用修改的ps命令来隐藏其运行的sniffer器。或者将其改为一个看上去很正常的进程的名字。
在Linux环境下,比较著名的后门程序名字是rootkit,在各个搜索引擎都可以找到相关资料。你可以尝试使用这些工具来促进你对攻击者使用工具的了解.