完整性检测工具Tripwire
完整性是安全要求的基本要求之一,本文将向读者详细介绍如何利用 开源 完整性检测工具Tripwire来检查系统的完整性。 一、系统的完整性 我们知道,系统的正常运行要靠系统程序的正常运转,而程序的运行又与其可执行文件休戚相关。所以,维护系统完整性是确保
完整性是安全要求的基本要求之一,本文将向读者详细介绍如何利用开源完整性检测工具Tripwire来检查系统的完整性。
一、系统的完整性
我们知道,系统的正常运行要靠系统程序的正常运转,而程序的运行又与其可执行文件休戚相关。所以,维护系统完整性是确保系统安全的一项基本工作。我们这里的系统完整性是指系统中可执行文件的完整性,也就是说系统中的程序文件没被非法修改。
如果可执行文件被恶意修改的话,如改变、插入或删除等,将直接威胁到系统的安全性。大多数情况下,黑客渗入到系统后会立即修改某些系统文件以创建后门,如用准备好的替代物换掉系统中原有的/bin/login文件以便使其不用口令便能登陆系统;然后再修改某些文件,例如/bin/ls等,以便隐藏其行径。如果我们没能发现这些改变的话,那无异于身处险境却还以为很安全,这就为黑客的长期入侵提供了非常有利的条件,同时也意味着我们的损失将更大!为了改变这种被动的局面,我们需要一种文件完整性检查工具,使得当系统文件被恶意修改后能及时发现,从而为进一步处理创造条件。
二、Tripwire概述
Tripwire的运行机理
Tripwire是一款最为常用的开放源码的完整性检查工具,它生成目标文件的校验和并周期性的检查文件是否被更改。下面我们简单介绍一下Tripwire的运行机理。与大多数完整性检查程序相同,对于需要监视的文件,Tripwire会使用校验和来为文件的某个状态生成唯一的标识(又称为"快照"),并将其存放起来以备后用。当Tripwire程序运行时,它先计算新的标识,并于存放的原标识加以比较,如果发现不匹配的话,它就报告系统管理人员文件已经被修改。接下来,系统管理员就可以利用这个不匹配来判断系统是否遭到了入侵。例如,如果Tripwire已经为/bin/login和/bin/ls存放了快照,那么对它们的尺寸、inode号、权限以及其他属性的任何修改,都逃不过Tripwire的火眼金睛。尤其是对于文件内容的修改,即使只改变了一个字节,Tripwire也能察觉得到,因为校验和是针对文件整体的。
通过对以上运行机制的了解我们不难发现,完整性检查工具的安装时机非常重要,最好是在交付用户使用和连入网络之前的Linux系统初装时进行。因为完整性检查工具只有保留了系统文件的初始状态(快照),才能确保系统文件的完整性;如果在系统使用一段时间后再取其快照的话,它很可能已经不再是原系统文件的映象(如已经遭到破坏),所以这时的完整性检测的可靠性已经打了折扣。
Tripwire的组成
Tripwire主要由策略和数据库组成。策略不仅指出Tripwire应检测的对象即文件和目录,而且还规定了用于鉴定违规行为的规则。一般情况下,对于/root、/bin和/lib目录及其中文件的任何修改都应视为违规行为。数据库则用来存放策略中规定的检测对象的快照。只要建立了策略和数据库,我们就可以随时用快照来比较当前的文件系统,然后生成一个完整性检测报告,从而判断系统的完整性是否受到攻击。除了策略和数据库外,Tripwire还有一个配置文件,用以控制数据库、策略文件和Tripwire可执行程序的位置等。
为了防止被篡改,Tripwire对其自身的一些重要文件进行了加密和签名处理。这里涉及到两个密钥:site密钥和local密钥。其中,前者用于保护策略文件和配置文件,如果多台机器具有相同的策略和配置的话,那么它们就可以使用相同的site密钥;后者用于保护数据库和报告,因此不同的机器必须使用不同的local密钥。
三、Tripwire的安装和设置
Tipwire的安装
Tripwire的下载地址为http://www.tripwire.org。如果您使用的是Red Hat Linux的话,可以下载该站点上的RPM格式的程序(当前最新版本为rpm4-tripwire-2.3-47.i386.tar.gz),假设将其下载到/A目录的话,安装过程如下所示:
rpm -ivh /A/rpm4-tripwire-2.3-47.i386.tar.gz |
如果从源代码中进行软件安装,先下载tar格式源程序并解包。接下来在相应目录中执行如下操作:
./configure
make
make install |
安装后的设置
在安装Tripwire之后,可以进行如下的设置:
# cd /etc/tripwire
# ./twinstall.sh
# tripwire --init
# rm twcfg.txt twpol.txt |
这里,脚本twinstall.sh的作用在于执行下列任务:
1) 创建site和local密钥,这时会要求输入口令;如果这两个密钥业已存在,则可以跳过此步骤。其中,site密钥存放在site.key文件中,而local密钥则存放在hostname-local.key(这里的hostname是指该机器的主机名)文件之中。
2) 利用site密钥对默认配置文件twcfg.txt进行签名,并将签名(而非被签名的文件twcfg.txt)存放于文件tw.cfg之中。
3) 利用site密钥对默认策略文件twcfg.txt进行签名,并将签名(而非被签名的文件twcfg.txt)存放于文件tw.pol之中。
此外,您还可以手工方式来安装,尤其是在由于某种原因,您的系统没带twinstall.sh文件等情况下则必须手工完成这项工作:
设置常见的变量:
DIR=/etc/tripwire
SITE_KEY=$DIR/site.key
LOCAL_KEY=$DIR/`hostname`-local.key |
创建site密钥
# twadmin --generate-keys --site-keyfile $SITE_KEY |
生成local密钥
# twadmin --generate-keys --local-keyfile $LOCAL_KEY |
为配置文件签名
# twadmin --create-cfgfile --cfgfile $DIR/tw.cfg --site-keyfile $SITE_KEY $DIR/twcfg.txt |
为策略文签名
# twadmin --create-polfile --cfgfile $DIR/tw.cfg --site-keyfile $SITE_KEY $DIR/twpol.txt |
设置权限
# cd $DIR
# chown root:root $SITE_KEY $LOCAL_KEY tw.cfg tw.pol
# chmod 600 $SITE_KEY $LOCAL_KEY tw.cfg tw.pol |
需要说明的是,上述配置是以您的默认配置和策略文件已经存在并分别为twcfg.txt 和 twpol.txt为前提的。一般情况下,为了使这两个文件能更好的满足我们的系统要求,还必须对其进行相应的修改(见下文)。此外,策略和配置文件的名称必须为twcfg.txt 和 twpol.txt,因为脚本代码就是用的这两个名称。
然后,为tripwire建立数据库并用local进行签名,命令如下所示:
需要说明的是,完成此项操作,需要输入local密钥的口令;如果tripwire出现类似"Warning: File System Error"之类的错误消息的话,那么可能是由于默认策略引用了并不存在的文件所引起的。
为了安全起见,我们还需要删除明文形式的策略和配置文件,命令如下所示:
现在,Tripwire自身已经完全就绪,接下来我们要做的事就是用它来执行完整性检查。
四、维护策略文件和配置文件
如何查看策略和配置
如果您想浏览一下Tripwire的策略和配置情况,但他们是以二进制的形式存放或当前缺失,请用下列命令:
生成有效配置文件
# cd /etc/tripwire
# twadmin --print-cfgfile > twcfg.txt |
生成有效策略文件
# cd /etc/tripwire
# twadmin --print-polfile > twpol.txt |
因为有效配置文件和策略文件已经加密和签名,所以他们是以密文的形式存放。如果想浏览他们的话,需要先解密:将其转换成明文的形式。为安全起见,一般建议在对他们重新进行签名之后将明文形式的配置和策略文件删除。
需要注意的是,尽管我们可以将twadmin的输出重定向到任何文件当中,但安装脚本twinstall.sh却要求明文形式的策略和配置文件名为twcfg.txt和twpol.txt。
修改策略文件和配置文件 如果想改变Tripwire所检查文件和目录的话,或者想改变Tripwire的默认行为,那该怎么办呢?请按如下所示来进行:
首先,从明文文件中提取出策略和配置:
# cd /etc/tripwire
# twadmin --print-polfile > twpol.txt
# twadmin --print-cfgfile > twcfg.txt |
策略文件twpol.txt和配置文件twcfg.txt的修改可以利用常见的文本编辑器来完成。对于修改过的策略文件twpol.txt和配置文件twcfg.txt文件,需要对他们进行再次签名:
# twadmin --create-cfgfile --cfgfile /etc/tripwire/tw.cfg \
--site-keyfile site_key etc/tripwire/twcfg.txt
# twadmin --create-polfile --cfgfile /etc/tripwire/tw.cfg --site-keyfile site_key etc/tripwire/twpol.txt |
然后,我们需要重新初始化数据库:
# tripwire --init
# rm twcfg.txt twpol.txt |
需要注意的是,我们只能对明文形式的策略和配置文件进行编辑,所以除非已有明文文件,否则必须先将加密签名的策略和配置文件转换成明文形式。另外,当在修改文件时,可能会遇到以下消息:
### Error: File could not be opened |
这说明Tripwire没有找到目标文件,如果是该文件的确不存在的话,我们就需要从策略和配置文件中去掉对该文件的引用(或将其注释出来也可以),并对策略文件重新签名。如果只是在完整性检查之后简单地更新一下数据库的话,那完全没必要严格按上述步骤来处理;但是对策略或配置文件作了修改后却必须这样处理。
五、配置完整性检测 基本的完整性检测配置 完整性检验的目的在于检查一下自从上次Tripwire对文件作了快照以后,我们的文件是否发生了变动,我们可以简单通过以下命令来达到此目的:
这是一条最基本的命令,它能告诉我们系统是否被修改了。它根据在策略文件中规定的规则,利用Tripwire数据库跟文件系统当前状态加以对比,之后将比较结果写入标准输出,并将其加盖时间戳、签名,然后作为一份Tripwire报告存放起来。另外,我们还可以针对数据库中的单个或多个文件进行完整性检查。若Tripwire的策略中包括以下规则:
(
rulename = "My funky files",
severity = 50
)
{
/sbin/e2fsck -> $(SEC_CRIT) ;
/bin/cp -> $(SEC_CRIT) ;
/usr/tmp -> $(SEC_INVARIANT) ;
/etc/csh.cshrc -> $(SEC_CONFIG) ;
} |
那么您就可以用以下命令来查看选中的文件和目录:
# tripwire --check /bin/cp /usr/tmp |
若要查看一条规则所对应的所有文件,用以下命令:
# tripwire --check --rule-name "My funky files" |
也可以查看严重性大于等于特定值的所有规则,如下所示:
# tripwire --check --severity 40 |
关于策略文件的有关语法,请参阅有关手册或查看联机帮助:
$ tripwire --check --help |
更高安全级别的完整性检测 为了获得更高的安全性,我们可以将Tripwire最关键的文件存放到诸如CD-ROM之类的只读介质或有写保护的上磁盘上,这样能防止它们被篡改。步骤如下:
1.把 site密钥、local密钥以及tripwire可执行文件本身复制到合适的磁盘上,打开写保护后再装载,比如将其安装在目录/mnt/cdrom。
# mount /mnt/cdrom
# ls -l /mnt/cdrom
total 2564
-r--r----- 1 root root 931 Jan 21 10:20 site.key
-r--r----- 1 root root 931 Jan 21 10:20 myhost-local.key
-r-xr-xr-x 1 root root 2612200 Jan 21 10:19 tripwire |
2.生成明文形式的配置文件
# DIR=/etc/tripwire
# cd $DIR
# twadmin --print-cfgfile > twcfg.txt |
3.编辑配置文件以使之指向这些拷贝
/etc/tripwire/twcfg.txt:
ROOT=/mnt/cdrom
SITEKEYFILE=/mnt/cdrom/site.key
LOCALKEYFILE=/mnt/cdrom/myhost-local.key |
4.对修改后的配置文件进行签名
# SITE_KEY=/mnt/cdrom/site.key
# twadmin --create-cfgfile --cfgfile $DIR/tw.cfg --site-keyfile $SITE_KEY $DIR/twcfg.txt
5.更新数据库并卸载CD-ROM
# /mnt/cdrom/tripwire --init
# umount /mnt/cdrom
现在,已经万事具备,如果要进行完整性检验的话,只要插入光盘并输入命令就可以了:
# mount /mnt/cdrom
# /mnt/cdrom/tripwire --check
# umount /mnt/cdrom |
site密钥、local密钥以及tripwire可执行文件之所以要加以保护,是因为它们极为重要并且可能受到攻击。Tripwire的其他文件,如数据库、策略和配置等需要用这两个密钥和程序来签名,如果site密钥、local密钥以及tripwire可执行文件是安全的,那么用它们签过名的文件发生的任何变化都能被发现。另外,将/usr/sbin/tripwire拷贝到光盘之前,一定要确保它是静态链接的,也就是说该程序的执行不依赖任何动态共享库,因为应用动态共享库时,动态库调用更容易被攻击者所劫持。
$ ldd /usr/sbin/tripwire
not a dynamic executable |
除了上面的方法外,我们还可以利用远程进行完整性检验来提高安全强度。
为了提高检验的安全性,关键的Tripwire文件最好不要存放在被检验的机器上面。为此,我们在此引入两台机器untrusty和trusty。前者是一台想要用Tripwire来检查其完整性的"不可信"机器;后者是一台安全的机器,理想的情况下只能由它访问网络,而其他机器这不能访问它。此外,为了使其他机器不能访问存放site密钥、local密钥以及tripwire可执行文件的远程机器,通常使用rsync(SSH下的安全隧道技术)来验证原件和拷贝的一致性从而触发完整性检验。远程机器trusty上的原始配置如下所示:
#!/bin/sh
REMOTE_MACHINE=untrusty
RSYNC='/usr/bin/rsync -a --progress --rsh=/usr/bin/ssh'
SAFE_DIR=/usr/local/tripwire/$
VITAL_FILES="/usr/sbin/tripwire
/etc/tripwire/site.key
/etc/tripwire/$-local.key"
mkdir $SAFE_DIR
for file in $VITAL_FILES
do
$RSYNC $:$file $SAFE_DIR/
done |
在检验本地机器之前,需要首先将site密钥、local密钥以及tripwire可执行文件与它们在远程机器上的拷贝比较一番,以确定这三个文件的完整性。然后在trusty上运行下列代码(需要注意,这里的各个变量如REMOTE_MACHINE要与前面脚本中的保持一致):
#!/bin/sh
cd $SAFE_DIR
rm -f log
for file in $VITAL_FILES
do
base=`basename $file`
$RSYNC -n $:$file . | fgrep -x "$base" >> log
done
if [ -s log ] ; then
echo 'Security alert!'
else
ssh $ -l root /usr/sbin/tripwire --check
fi |
rsync是一个常用来同步两台机器上的文件的实用程序。它实际上通过SSH建立了一条安全隧道,来为我们在两台机器之间提供安全的鉴别功能,并为两者之间的通信提供加密服务,但前提是您已经在两台机器之间设置了SSH设施,否则,rsync就不能提供上述的安全功能。
这里有几个常用的选项需要介绍一下:-progress通知rsync只有当本地和远程文件不同时才产生输出;-n选项的作用在于让rsync不拷贝文件。
对于fgrep命令,主要用于删除所有输出,但可疑的文件名除外。它的特点是用固定的字符串而非正则表达式进行匹配,而文件名中恰恰又包含常见于正则表达式的一些特殊字符,如"."等。fgrep -x对整行(即文件名)进行匹配,因此,当且仅当本地文件和远程文件完全一致时,log文件才为空,从而触发完整性检验。
那么是否要远程存储数据库呢?实际上是没有必要的,因为数据库是用local密钥来签名的,而该密钥又是"离机的",因此如果数据库发生意外变化的话,Tripwire就会发出警报。
Trusty不仅要检查这些重要的Tripwire文件,同时还必须赶在untrusty进行完整性检查之前将他们拷贝给untrusty:
# scp -p tripwire untrusty:/usr/sbin/tripwire
# scp -p site.key untrusty-local.key untrusty:/etc/tripwire/
# ssh untrusty -l root /usr/sbin/tripwire --check |
高强度完整性检测 上面介绍的是常规强度的完整性检测,但我们还可以继续提高检验强度,但天下没有免费的午餐,这需要付出速度与方便性为代价的。
因此,我们可以创建一个可引导的CD-ROM,并在其中放上一个微型的Linux系统、Tripwire程序以及您的local和site密钥。然后,将您的机器与所有网络断开,从上面制作的可引导光盘引导系统,接着利用光盘上的(而不是硬盘上的)可执行程序来检查机器磁盘的完整性。之后还要经常备份您的Tripwire的数据库、配置和策略,以备万一它们被攻击者删除时之用。
这种方法至少需要两台机器,其中一个必须是安全可信的机器(称为trusty),另一个是被检测的机器(称为untrusty)。我们的目的是为后者进行安全的Tripwire检测。
第一步是安全创建可引导CD-ROM,这要求:
在trusty上创建CD-ROM,trusty必须是一个洁净的Linux系统,它可以是由可信的源或二进制软件包构建而成,从来没有连入网络或被第三方访问过,此外还要为其打上最新的安全补丁。
配置CD-ROM的启动脚本使其禁用所有网络。
直接用可信的源或二进制软件包来烧制光盘。
在trusty上建立site和local密钥。
然后,从CD-ROM引导untrusty,装上本地磁盘并利用CD-ROM上的程序和密钥来创建untrusty的Tripwire数据库。因为数据库、策略和配置文件已经用CD-ROM的密钥签过了名,所以这些文件在untrusty上的安全性是可信的。接着,您就可以在执行完整性检查之前从光盘上引导untrusty。另外,若只是从untrusty上加载光盘并从光盘上运行untrusty的话,则会出现以下情况:
如果untrusty是动态链接的话,很难保证共享库的安全性;
难以保证系统内核的安全性;
难以保证untrusty上挂载点的正确性;
虽然这种方法提供了非常高的安全级别,但做起来非常麻烦,所以只有有特殊安全需求的情况下才采取该措施。为方便起见,我们可以安排一个cron任务,使其在每晚规定的时间从光盘上重引导untrusty,来进行Tripwire检验,之后再重引导untrusty。然而,不要让untrusty本身来执行该任务,因为untrusty是不安全的,所以在其上运行的cron也是不可靠的;相反,应将其安排给trusty来执行,如利用SSH批处理任务来触发重引导,因为这样作更为合理一些。(详情如下文所示)
六、完整性检测的自动化
如果您想让Tripwire在特定的时刻或每隔一段时间就自动进行检测的话,可以按照下列提示来完成。例如我们要他每天的下午2点进行一次检测,那该如何做呢?我们可以利用cron来来协助我们完成此项任务。我们可以在root用户的 crontab文件中添加以下一项:
0 2 * * * /usr/sbin/tripwire --check |
需要注意的是,cron本身也可能受到攻击,因而可能出现不执行等意外情况。所以我们最好在一个可信的远程机器上来执行cron任务。在trusty上的crontab中添加如下一个远程检测项:
0 2 * * * ssh -n -l root untrusty /usr/sbin/tripwire --check |
但是如果入侵者攻破了untrusty上的sshd的话,那么覆巢之下,焉有完卵--您的安全性也必将受到威胁!此外,某些rootkits能够颠覆对Tripwire的远程exec调用。为了获取最大的安全性,只是执行cron任务是远远不够的,还得在可信机器上进行完整性检验。
Red Hat Linux预配置情况下,会在每晚通过cron任务/etc/cron.daily/tripwire-check来运行Tripwire程序。但是,Tripwire数据库不是由操作系统来提供的,而是由用户自己来提供一个原件,否则,cron只是定时向超级用户发送一封Tripwire调用失败的的电子邮件。
七、生成Tripwire报告
上面介绍了如何配置Tripwire来进行完整性检测。但这并不是使用Tripwire的目的所在,我们需要的是完整性检测的结果,换句话说还得要Tripwire将结果以报告的形式提交给管理人员,这样我们才能以此判断系统是否遭到破。具体操作如下所示:
#!/bin/sh
DIR=/var/lib/tripwire/report
HOST=`hostname -s`
LAST_REPORT=`ls -1t $DIR/$HOST-*.twr | head -1`
twprint --print-report --twrfile "$LAST_REPORT" |
一般情况下,Tripwire报告存放在什么地方是由Tripwire配置文件中的REPORTFILE变量来决定,其常见值为:
REPORTFILE = /var/lib/tripwire/report/$(HOSTNAME)-$(DATE).twr
变量HOSTNAME存放的是机器的主机名,变量DATE存放的是时间戳,如。所以,主机untrusty的报告文件名应当为:
/var/lib/tripwire/report/untrusty-20040130-030518.twr
虽然tripwire可以通过电子邮件发送报告,但不要太信赖电子邮件,因为它很可能被截获并被篡改后重发。所以,最好由您直接检查报告为上,要Twprin打印报告,可以按如下操作进行:
# twprint --print-dbfile --dbfile /var/lib/tripwire/`hostname -s`.twd
Tripwire(R) 4.0 Database
Database generated by: root
Database generated on: Mon Jan 1 22:33:55 2004
Database last updated on: Never
... contents follow ... |
八、Tripwire数据库的维护
对于Tripwire数据库的维护工作,主要包括数据库的更新、添加和删除操作,下面我们将分别介绍。
更新数据库
有时候,我们会对程序作一些正常的修改,这些改动也会反映在最新的Tripwire报告中,但问题是,我们使用Tripwire很大程度上只想让它报告那些"非法的"修改。那么,这时我们就需要利用最新的报告来更新一下我们的Tripwier数据库,具体操作如下所示:
#!/bin/sh
DIR=/var/lib/tripwire/report
HOST=`hostname -s`
LAST_REPORT=`ls -1t $DIR/$HOST-*.twr | head -1`
tripwire --update --twrfile "$LAST_REPORT" |
这里有一点必须注意,那就是如果你已经修改了某些文件的话,您不能只是简单的运行更新就算了事:您必须在此之前首先进行完整性检验。进行更新的好处是它比初始化数据库要快得多!
向数据库中添加文件
为了向Tripwire的数据库中添加文件和目录,请执行以下操作:
向有效策略文件中添加指定的文件,如/bin/ls:
向有效策略文件中添加整个目录树,比如/etc:
向有效策略文件中添加目录如/etc及其下的文件,但不包括其子目录:
/etc --> $(SEC_BIN) (recurse=1) ; |
向有效策略文件中添加目录如/etc,但不包括其下的文件以及其子目录:
/etc --> $(SEC_BIN) (recurse=0); |
然后初始化数据库。
策略实际上就是存放在策略文件中的规则表,规则的一般形式如下所示:
它的基本含义就是,如果给定的规则被违反的话,那么对应的文件或目录就被认为是到了安全侵害。例如:
上面这条规则的含义是:如果自从上次快照之后,如果/bin/login的文件权限(p)、inode号(i)、 尺寸 (s),、用户(u)或组 (g)发生了变化的话,那么就应当引起我们的关注。如果想全面深入的了解Tripwire语法的话,请参阅Tripwire手册。在这里,我们使用了一个预定义的全局变量SEC_BIN来指出二进制文件不得修改。recurse= n的作用在于通知Tripwire在文件系统中的递归深度;当n为零时,其含义为只测试到目录文件本身这一层次。
很多时候我们需要修改默认策略文件,因为它们所提供的策略未必完全适合我们的系统,所以我们需要针对不同的Linux类型和版本,对Tripwire所提供的默认策略进行适当的剪裁,从而满足我们的要求。
从数据库中删减文件
我们不仅根据需要向数据库中添加文件,有时我们还需要对数据库中的文件加以删减。具体操作如下所示:
例如首先向数据库中添加一个目录:
然后排除掉其中的一些文件:
!/etc/not.me
!/etc/not.me.either |
如果我们想去掉一个子目录的话:
这里,感叹号!的作用在于将给定的文件或子目录排除掉。
九、小结
Tripwire是现实中最为常见的一种开源完整性检测工具,我们对实际工作中的一些常见操作进行了较为全面而不失侧重的介绍,如果读者要想更深入的了解本软件的话,请参阅其使用手册。
需要注意的是,Tripwire是进行周期性检测的,因此在两次检测间隔内的修改对它来说就显得有些鞭长莫及了,但我们还可以缩短其周期间隔,使其几乎以实时的方式运行,但这时的开销将明显增加,所以我们要在安全性和系统开销之间加以权衡,实际工作中可以视具体情况来加以定夺。
原文转自:http://www.ltesting.net
|