Discuz!官方免费开源建站系统

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

Apache性能优化技巧

[复制链接]
alect 发表于 2004-4-3 22:23:05 | 显示全部楼层 |阅读模式
本文简要介绍了几个优化 Apache 的技巧,在实战中十分有用。

升级 Apache 到最新版本,新版本往往包含性能提升和安全更新。

在 httpd.conf 中设置 "HostNameLookups off" 能避免针对每个访问者的 DNS 域名的反向查询。

对于繁忙的网站,在 httpd.conf 中设置 "MaxClients 230" 或者更高。这项设置让更多的 httpd 进程同时响应请求,并避免了处理器排队的情况发生。

采用另外一台服务器处理图片文件。

缺保您的 Web 页面和 CGI 页面采用了浏览器缓冲技术。具体的文章可以参考本站:采用 mod_gzip 加速 Zope 和 Apache

保持您的 Apache 苗条,编译那些仅仅需要的模块,在编译之前,修改 src/Configuration 文件,在那些不需要的模块之前用 # 号注释掉。

如果不需要流量日志,那么把 httpd.conf 中的 TransferLog 指向到 /dev/null/

除非你确定使用 .htaccess 文件来控制一些目录的权限,否则设置 "AllowOverride None" ,这样就免去 Apache 在每个目录搜索 .htaccess 文件的劳役之苦。

不要让不需要的后台进程运行。

千万不要把页面或者日志文件写到网络磁盘上,例如 NFS。

不要让 Apache (httpd) 运行于 inetd 模式。

不要让 X Windows 运行在你的 Web 服务器上,用 Ctrl-Alt-Backspace 关闭 X 。

避免使用 SSI tag。

在 CGI 脚本中:
文件 I/O:打开的文件数目越少越好。
Shell 命令:采用全路径来调用 shell 命令。
如果你的网站主要以 CGI 来驱动,那么请使用 mod_perl。
在你的 Web 页面目录中,不要让文件数超过 1000 个,文件越多花费在定位上的时间也越多。

在 Web 服务器上的图片越少越好,保证每个图片都经由图片压缩器运行。

对你的网站做压力测试,建议采用 Apache 自带的 ab 命令来测试。

为了最好的性能,最好把网线拔掉,这样你的 Web 服务器就十分安全,而且负载马上降为 0,:-)
 楼主| alect 发表于 2004-4-3 22:25:58 | 显示全部楼层

2.ext2文件系统下恢复误删除的文件

摘要

ext2文件系统下恢复误删除的文件

---------------------------------------------------------------------

因为我的疏忽,这几日系统时间不正确,造成许多人的 ID 被误砍后,又一次因系统设定上的问题,将 BBS 的重要备份档给杀了。这件事是学弟发现后告诉我的,当我上站来一见到他的 mail, 当真是欲哭无泪,差点没去撞墙。

  那时已是周六晚 11:00 左右,我一边想着要编一套说辞向大家解释无法替大家恢复旧信件与设定了,一边还在想是否能够挽回局面。大家知道, UNIX like 的系统是很难像 M$ 的系统一样,做到 undelete 的,所有网管前辈都曾再三警告我们,要小心! 小心! 砍档之前三思而后行,砍了之后再后悔也没用。虽然我已渐渐做到砍档三思而后行,但之次误砍事件是系统在背景中定时执行的,等到我找出原因时已是档案被砍后一个多小时。我凭着一点点的印象,想起在网络上,有人讨论过在 Linux ext2 filesystem中 undelete 的可能性,但我所见到的多半是负面的答案,但好象真的有人做过这件事,于是我第一个所做的,就是马上将该档案原来所在的 partition mount成 read-only, 禁止任何的写入动作,不是怕再有档案被误砍 (因为已没什么可砍的了) ,而是怕有新档案写进来,新资料可能会覆盖到旧资料原本存在的磁区 (block) 。我们现在唯一个指望,就是企图将档案原来存在的磁区一个个找回来,并且「希望」这些磁区上的旧资料都还在,然后将这些磁区串成一个档案。终于被我找到了!! 原来这方面的技术文件就存在我自己的系统中 :-))


/usr/doc/HOWTO/mini/Ext2fs-Undeletion.gz



  于是我就按照这份文件的指示一步步来,总算将一个长达 8MB 的压缩档救回了 99%, 还有一个长达 1.1 MB 的压缩档完整无缺地救了回来。感谢上帝、 Linux 的设计者、写那篇文件的作者、曾经讨论过此技术的人、以及 Linux 如此优秀的 ext2 filesystem, 让我有机会抢救过去。现在,我将我的抢救步骤做一个整理让大家参考,希望有派得上用场的时候 (喔! 不,最好是希望大家永远不要有机会用到以下的步数 :-)))

   写这篇文章的目的,是给那些处于万不得已情况下的人们,有一个挽回的机会,并不意味着从此我们就可以大意,砍档不需要三思。前面提到,我有一个档案无法 100% 救回,事实上,长达 8MB 的档案能救回 99% 已是幸运中的幸运,一般的情况下若能救回 70% - 80% 已经要愉笑了。所以,不要指望 undelete 能救回一切。预防胜于治疗! 请大家平时就养成好习惯,砍档前请三思!!!

  理论分析

  我们能救回的机会有多大? 在 kernel-2.0.X 系列中 (本站所用的 kernel 是 2.0.33) ,取决以下两点:

  档案原来所在的磁区是否没有被覆写?

  档案是否完全连续?

  第一点我们可以与时间竞赛,就是当一发现档案误砍时,要以最快的速度 umount 该 filesystem, 或将该 filesystem remount 成唯读。就这次的情况而言,档案误砍是在事发一个小时后才发现的,但由于该 filesystem 写入的机会很少 (我几乎可确定一天才只有一次,做 backup),所以第一点算是过关了。

  第二点真的是要听天由命了,就本站所使用的 kernel, 必须要在假设「长档案」所占的 block 完全连续的情况下,才有可能完全救回来! 一个 block 是 1024 bytes,长达 8 MB 的档案就有超过 8000 个 block。在经常读写的 filesystem 中,可以想见长档案很难完全连续,但在我们的系统中,这一点似乎又多了几分指望。同时,Linux ext2 如此精良的 filesystem, 能做到前 7950 多个 block 都连续,这一点也功不可没。

  好了,以下我就讲一下我的步骤。

  抢救步骤 I - mount filesystem readonly

  该档案的位置原来是在 /var/hda/backup/home/bbs 下,我们系统的 filesystem 组态是:


root@bbs:/home/ftp/rescue# df
Filesystem 1024-blocks Used Available Capacity Mounted on
/dev/sda1 396500 312769 63250 83% /
/dev/sda3 777410 537633 199615 73% /home
/dev/hda1 199047 36927 151840 20% /var/hda
/dev/hda2 1029023 490998 485710 50% /home/ftp



  因此 /var/hda 这个 filesystem 要马上 mount 成 readonly (以下请用 root 身份):


mount -o remount,ro /var/hda



  当然也可以直接 umount 它,但有时候可能有某些 process 正在此 filesystem下运作,您可能无法直接 umount 它。因此我选择 mount readonly。但您也可以用:


fuser -v -m /usr



  看一下目前是那些 process 在用这个 filesystem, 然后一一砍掉,再 umount。

  抢救步骤 II

  执行


echo lsdel | debugfs /dev/hda1 | less



  看一下该 filesystem 最近被砍的 inode (档案) 有那些 (为什么是 /dev/hda1? 请见上头的 df 列表)? 在这奶F档案的重要资讯,如大小、时间、属性等等。就我们的系统而言,其列示如下:


debugfs: 92 deleted inodes found.
Inode Owner Mode Size Blocks Time deleted
....................................................................
29771 0 100644 1255337 14/14 Sat Jan 30 22:37:10 1999
29772 0 100644 5161017 14/14 Sat Jan 30 22:37:10 1999
29773 0 100644 8220922 14/14 Sat Jan 30 22:37:10 1999
29774 0 100644 5431 6/6 Sat Jan 30 22:37:10 1999



  请注意!我们必须要在档案大小、被砍时间等资讯中判断出要救回的档案是那一个。在此,我们要救回 29773 这个 inode。

  抢救步骤 III

  执行


echo "stat <29773>" | debugfs /dev/hda1



  列出该 inode 的所有资讯,如下:


debugfs: stat <29773>
Inode: 29773 Type: regular Mode: 0644 Flags: 0x0 Version: 1
User: 0 Group: 0 Size: 8220922
File ACL: 0 Directory ACL: 0
Links: 0 Blockcount: 16124
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x36b31916 -- Sat Jan 30 22:37:10 1999
atime: 0x36aebee4 -- Wed Jan 27 15:23:16 1999
mtime: 0x36adec25 -- Wed Jan 27 00:24:05 1999
dtime: 0x36b31916 -- Sat Jan 30 22:37:10 1999
BLOCKS:
123134 123136 123137 123138 123140 131404 131405 131406
131407 131408 131409 131 410 131411 131668
TOTAL: 14



  现在的重点是,必须将该 inode 所指的档案,所指的 block 全部找回来。在这它?14 个 block? 不对啊! 应该要有 8000 多个 block 才对啊! 在这卯ilesystem 的「奥密」了。上头所列的前 12 个 block 是真正指到档案资料的 block, 称之为 direct block 。第 13 个称为第一阶 indirect block, 第 14 个称为第二阶 indirect block 。什么意思? 该档的资料所在的 block 位置如下:

  各位明白吗? 第 13 个 (131411) 与第 14 个 block 其实不是 data, 而是 index,它指出接下来的 block 的位置。由于一个 block 的大小是 1024 bytes, 一个 int 在 32 位系统中是 4 bytes, 故一个 block 可以记录 256 笔资料。以 131411 block 为例,它所记录的资料即为 (在档案未砍前):


131412 131413 131414 .... 131667 (共 256 笔)



  而这 256 个 block 就真正记录了档案资料,所以我们称为第一阶。同理,第二阶就有两个层 index, 以 131668 来说,它可能记录了:


131669 131926 132182 .... (最多有 256 笔)



  而 131669 的 block 记录为:


131670 131671 131672 .... 131925 (共 256 笔)



  而这 256 个 block 才是真正储存档案资料的。而我们要的,就是这些真正储存档案资料的 block 。 理论上,我们只要将这些 index block 的内容全部读出来,然后照这些 index 把所有的 block 全部读到手,就能 100% 救回档案 (假设这些 block 全部没有被新档案覆写的话)。工程很大,但是可行。不幸的是,在 kernel-2.0.33, 其设计是,如果该档案被砍了,则这些 index block 全部会规零,因此我所读到的是


0 0 0 0 0 ..... (共 256 笔)



  哇! 没办法知道这些 data block 真正所在的位置。所以,在此我们做了一个很大的假设: 整个档案所在的 block 是连续的! 也就是我上头的例子。这也就是为什么说,只有连续 block (是指后头的 indirect block) 的档案才能完整救回,而这一点就要听天由命了。

  抢救步骤 IV

  好了,现在我们只好假设所有的档案处于连续的 block 上,现在请用http://archie.ncu.edu.tw/去找这个工具: fsgrab-1.2.tar.gz, 并将它安装起来。因为步骤很简单,故在此我就不多谈。我们要用它将所需的 block 全部抓出来。它的用法如下:


fsgrab -c count -s skip device



  其中 count 是只要 (连续) 读几个, skip 是指要从第几个开始读,例如我要从 131670 开始连续读 256 个,就这样下指令:


fsgrab -c 256 -s 131670 /dev/hda1 > recover



  现在我们就开始救档案吧! 以上头的资料,我们必须用以下的指令来救: (注意到头开的 12 个 block 并没有完全连续!!!)


fsgrab -c 1 -s 123134 /dev/hda1 > recover
fsgrab -c 3 -s 123136 /dev/hda1 >> recover
fsgrab -c 1 -s 123140 /dev/hda1 >> recover
fsgrab -c 7 -s 131404 /dev/hda1 >> recover



  这是开头的 12 个 block, 对于第一阶 indirect, 就资料来看好象是连续的 :-))


fsgrab -c 256 -s 131412 /dev/hda1 >> recover



  注意要跳过 131411, 因为它是 index block。对于第二阶 indirect, 我们 *假设* 它们都是连续的:


fsgrab -c 256 -s 131670 /dev/hda1 >> recover
fsgrab -c 256 -s 131927 /dev/hda1 >> recover
fsgrab -c 256 -s 132184 /dev/hda1 >> recover
............................................



  要一直做,直到 recover 的大小超过我们所要救回的档案大小 (8220922) 为止。要注意在这市 p心地跳过那些 index block (如 131668, 131669, 131926, 132183, ....) 了。

  抢救步骤 V

  最后一步,就是把档案「剪」出来,并看看我们救回多少了。在这戊]我们重复上述步骤,弄出来的 recover 档大小为 8294400,而我们要的大小是 8220922, 那就这样下指令:


split -b 8220922 recover rec



  则会做出两个档,一个是 recaa, 大小是 8220922, 另一个是 recab 则是剩下的大小,后者是垃圾,扔了即可。现在我们可以检查这个档案是不是「完整」的那个被误砍的档案了。由于我们的那个档案是 .tar.gz 的格式,于是我们这个方法来检查:


mv recaa recaa.tar.gz
zcat recaa.tar.gz > recaa.tar



  如果没有错误讯息,那表示成功了! 完全救回来了。但不幸的是,我们没有成功,将弄出的 recaa.tar 改名再 gzip 之后,与原来的 recaa.tar.gz 比一下大小,发现少了 1%, 表示说该档原来所在的 block 中最后有 1% 是不连续的 (或者被新写入的档案覆写了),但这已是不幸中的大幸了。

  后记

  对于在 undelete 时 *必需* 假设所有 block 连续的问题,那份 HOWTO 文件说 Linus 与其它 kernel 设计者正着手研究,看能否克服这个困难,也就是在档案砍掉时,不要将 index block 规零。我刚刚试一下 kenrel-2.2.0 的环境,发现已做到了!! 以下是一个已砍的档案的 inode data (由 debugfs 所读出):

   
debugfs: Inode: 36154 Type: regular Mode: 0600 Flags: 0x0 Version: 1
User: 0 Group: 0 Size: 2165945
File ACL: 0 Directory ACL: 0
Links: 0 Blockcount: 4252
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x36b54c3b -- Mon Feb 1 14:39:55 1999
atime: 0x36b54c30 -- Mon Feb 1 14:39:44 1999
mtime: 0x36b54c30 -- Mon Feb 1 14:39:44 1999
dtime: 0x36b54c3b -- Mon Feb 1 14:39:55 1999
BLOCKS:
147740 147741 147742 147743 147744 147745 147746 147747 147748 147769
147770 157642 157643 157644 157645 157646 157647 157648 157649 157650
157651 157652 157653 157654 157655 157656 157657 157658 157659 157660
157661 157662 157663 157664 157665 157666 157667 157668 157669 157670
157671 157672 157673 157674 157675 157676 157677 157678 157679 157680
157681 157682 157683 157684 157685 157686 157687 1...................
.........9745 159746 159747 159748 159749 159750 159751 159752 159753
159754 159755 159756
TOTAL: 2126



  真是太完美了!! 这意味着在 kernel-2.2.X 的环境下,我们不必假设所有的 block 都连续,而且可以百分之百找回所有砍掉的 block! 因此上述的第二个风险就不存在了。

  以上资料,谨供参考。
回复

使用道具 举报

 楼主| alect 发表于 2004-4-3 22:27:33 | 显示全部楼层

3.IDS逃避技术和对策

文摘内容:
--------------------------------------------------------------------------------
http://www.linuxaid.com.cn

1.字符串匹配的弱点
2.多变shell代码(polymorphic shell code)
3.会话拼接(session splicing,叫会话分割更合适一些)
4.碎片攻击
4.1.碎片覆盖
4.2.碎片数据覆盖
4.3.碎片超时
5.碎片和snort特征码
6.拒绝服务
结论

在网络蓬勃发展的几天,网络安全问题日益突出。网络上的黑、白两道在网络安全的各个领域都展开了激烈的竞争。黑帽社团不断推 出躲避或者越过网络入侵检测系统(Network Intrusion Detection System,NIDS)的新技术,而NIDS的开发者不断地在自己的产品中加入 对这些技术的检测。但是,由于NIDS本身的局限性,胜利的天平正在向黑帽子倾斜。本文将讨论一些基本的IDS躲避技术,以及如何 识破这些技术。

1.字符串匹配的弱点

针对基本字符串匹配弱点的IDS躲避技术是最早被提出和实现的。一些基于特征码的入侵检测设备几乎完全依赖于字符串匹配算法, 而对于一个编写很差的特征码,攻击者可以轻松地破坏对其的字符串匹配。虽然不是所有的入侵检测系统都是纯粹基于特征码检测 的,但是绝大多数对字符串匹配算法有很大的依赖。这里,我们将使用开放源码工具snort的特征码来进行讨论。

在UNIX系统中,/etc/passwd是一个重要的文件,它包含用户名、组成员关系和为用户分配的shell等信息。我们就从监视对/etc/passwd 文件的访问开始,下面是用于检测的snort检测规则:

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS 80 (msg:"WEB-MISC /etc/passwd";
flags: A+; content:"/etc/passwd"; nocase; classtype:attempted-recon; sid:1122;rev:1)

snort使用字符串匹配算法对包含特征码(/etc/passwd)的HTTP请求进行检测。但是,这个规则的特征码过于简单了,攻击者修改攻击字 符串可以很轻松地逃过检测(我们暂时不考虑攻击请求是通过HTTP发出的)。例如,把攻击请求由GET /etc/passwd改为GET /etc//\// passwd,或者GET /etc/rc.d/.././\passwd,修改方式简直不计其数。这是最基本的娶亲检测逃避技术,对这种技术的检测也相对容易一 些,只要在编写特征码时能够仔细考虑一下攻击可能出现的变体。目前大多数流行入侵检测系统都有非常强大的字符串匹配能力,足 以检测此类攻击的大多数变体。不过,仍然有些编写不太好的特征码可以给攻击者以可乘之机。

攻击者还可以在此基础上再加以变化,几乎不费吹灰之力就可以加大入侵检测系统的防御难度。例如在telnet之类的交互会话中,攻击 者企图读取/etc/passwd文件。通常,入侵检测系统中存在很多特征码一些误用操作和后门等,但是这些特征码一般只包含黑客工具 名、文件名和程序名。在获得/etc/passwd文件的内容时,我们不直接输入cat /etc/passwd等命令行,而是通过一个命令解释器(例 如:perl)来实现我们的目的:

badguy@host$ perl -e
   ‘$foo=pack(“C11”,47,101,116,99,47,112,97,115,115,119,100);
   @bam=`/bin/cat/ $foo`; print”@bam\n”;’

从这个命令中,入侵检测系统根本就不会重组出/etc/passwd这些字符。显然,防御这种攻击就很困难了,因为这要求入侵检测系统必 须能够理解这种解释器如何收到的命令,这恐怕不太现实。当然,入侵检测系统也可以对使用解释器的可疑行为进行报警,但是它很 难对攻击行为进行精确的监视。

通过把字符串处理技术和字符替换技术结合到一起,我们可疑实现更复杂的字符串伪装。对于WEB请求,我们不必使用命令解释器, 在我们的请求中使用16进制的URL即可,以下的请求可以被目标WEB服务器解释为/etc/passwd:

GET %65%74%63/%70%61%73%73%77%64
或者
GET %65%74%63/%70a%73%73%77d

为了捕获这一个字符串的所有变体,你可能需要1000个以上的特征码进行字符串匹配,这还没有考虑UNICODE。UNICODE提供了另一 种字符表达方式。有关UNICODE的IDS欺骗技术细节,本文将不多做讨论。如果想了解更多细节请参考SecurityFocus的IDS Evasion with Unicode。除此之外,RainForestPuppy在他的HTTP扫描工具Whisker中采用了另外一些IDS欺骗技术:

-I 1 IDS-evasive mode 1 (URL编码)
-I 2 IDS-evasive mode 2 (/./目录插入)
-I 3 IDS-evasive mode 3 (过早结束URL)
-I 4 IDS-evasive mode 4 (长URL)
-I 5 IDS-evasive mode 5 (伪造参数)
-I 6 IDS-evasive mode 6 (TAB分割) (not NT/IIS)
-I 7 IDS-evasive mode 7 (大小写敏感)
-I 8 IDS-evasive mode 8 (Windows分割符)
-I 9 IDS-evasive mode 9 (会话拼接) (slow)
-I 0 IDS-evasive mode 0 (NULL方法)

如果想了解上面这些方法的技术细节,可以参考A Look At Whisker's Anti-IDS Tactics。需要特别说明的是,rfp把whisker采用的anti-ids技术 单独放到了libwhisker(使用perl编写的)库中,为其它的程序采用这些技术提供了很大的便利。另外,nessus和babelweb等扫描工具都 有自己的应用层入侵检测躲避技术。

现在,IDS开发人员对各种网络协议有了更深入的理解,并且入侵检测设备在对数据包的负载进行字符串匹配之前会进行必要的协议 分析,因此现在的IDS已经能够很好地处理上述的欺骗技术了。但是多余的字符转换又提高了入侵检测系统的负载,有时是得不偿 失。为了减小这个跗面影响,开发人员可以使入侵检测系统只在特定的端口进行字符转换。

2.多变shell代码(polymorphic shell code)

多变shell代码(polymorphic shell code)技术由K2开发的,设计思想来源于病毒逃避(virus evasion)技术。使用这种技术重新构造的shell代 码更为危险,入侵检测设备非常难以检测到。这种技术只用于缓冲区溢出攻击,对付基于特征码的检测系统非常有效,而对于智能化 的或者基于协议分析的检测系统的效果要差很多。为了便于讨论,我们以SSH CRC32缓冲区为例。我们先看以下snort检测规则:

alert tcp $EXTERNAL_NET any -> $HOME_NET 22 (msg:"EXPLOIT ssh CRC32
overflow /bin/sh"; flags:A+; content:"/bin/sh"; reference:bugtraq,2347;
reference:cve,CVE-2001-0144; classtype:shellcode-detect; sid:1324; rev:1;)

alert tcp $EXTERNAL_NET any -> $HOME_NET 22 (msg:"EXPLOIT ssh CRC32
overflow NOOP"; flags:A+; content:"|90 90 90 90 90 90 90 90 90 90 90 90 90 90 90)

上面的第一条规则简单地检查从外部到$HOME_NET,目标端口是22的数据包,搜索里面是否包含字符串/bin/sh。第二条规则是检查是否 包含x86空操作字符(0x90)。多变shell代码(polymorphic shell code)使用很多方法逃避字符串匹配系统的检测。首先(以x86架构为例), 使用其它的字符代替0x90执行无操作(no-op)指令。对于X86架构,有55种替代方式,其它的要少一些。这些替代方式以一种伪随机的 方式结合到一块,建立缓冲区溢出shell代码包含无操作(no-op)指令的部分。想了解无操作(no-op)指令的所有替代字符可以参考http:// cansecwest.com/noplist-v1-1.txt。除此之外,shell代码本身也采用XOR机制编码。通过这种方式建立的缓冲区溢出shell代码被重组后不会包 含以上的特征码,从而能够逃过字符串匹配检测。

多变shell代码检测对基于特征码检测的IDS是一个很大的挑战。Next Generation Security Technologie公司的技术白皮书Polymorphic Shellcodes vs. Application IDSs中提出了一些检测多变shell代码的设想。通过搜索无操作(no-op)字符的一个特定长度的正则表达式,可以实现对多变 shell代码的精确检测。最近,Dragos Ruiu发布了一个用于检测多变shell代码的snort预处理插件spp_fnord,这个插件采用了和上面相似的 检测技术。这个预处理插件有端口和长度两个配置选项。例如,如果某个人在配置时设置了80、21、23和53等端口,它就只对这几个 端口的数据流量进行多变shell代码的检测,而不会对其它端口(例如:22)进行检测。

3.会话拼接(session splicing,叫会话分割更合适一些)

上面讨论的这些方法都是属于攻击数据在一个数据包中的情况,没有涉及攻击数据和会话通过多个数据包投递的情况。RFP在Whisker 中实现了一种IDS逃避技术叫作会话拼接(session splicing),就是把会话数据放到多个数据包中发出,例如:

+-------------------------+
| packet number | content |
|---------------+---------|
| 1 | G |
|---------------+---------|
| 2 | E |
|---------------+---------|
| 3 | T |
|---------------+---------|
| 4 | 20 |
|---------------+---------|
| 5 | / |
|---------------+---------|
| 6 | H |
+---------------+---------+

通过这种方式,每次只投递几个字节的数据,就可能避开字符串匹配入侵检测系统的监视。要监视这种攻击,需要入侵检测系统或者 能够理解、监视网络会话(即使IDS有这种能力,攻击者也可以通过其它的凡是避开监视),或者采用其它的技术监视这种攻击。snort使 用以下规则来监视会话拼接:

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS 80 (msg:"WEB-MISC whisker
space splice attack"; content:"|20|"; flags:A+; dsize:1;
reference:arachnids,296; classtype:attempted-recon; reference)

这条规则使snort检测目标为$HTTP_SERVERS 80端口的ACK报文的负载长度是否等于1以及是否包含空格(16进制的20)。使用这条规则 可以精确地检测出whisker,但是攻击者只要稍加修改就可以避开这个检测。为了能够检测可能出现的会话拼接攻击,可以对上面这条 snort规则进行扩展,使其检查负载很短的HTTP请求。但是,这样做的副作用是提高了误报警数量,而且在某些情况下攻击者还是能 够避开监视。为了真正有效地检测这种攻击,需要入侵检测系统能够完整地理解网络会话,不过这是非常困难的。应该注意的是目前 大多数系统能够重组会话,在所有的会话数据到达之前,它们会等待一些时间。而等待时间的长短与程序有关。例如,Apache/RedHat 的会话超时时间是6分钟,IIS/Win2K等待的时间非常长。因此,攻击者完全可以每15分钟发送一个字节的会话数据,而IIS还会认为是 有效的会话。最新版本的snort能够监视长期的会话和网络层欺骗,例如:小TTL值。

4.碎片攻击

碎片攻击和会话拼接(session splicing)有点类似。直到最近,很多入侵检测系统在进行字符串匹配之前不能准确地重组碎片。现在这种 情况有了改观,所有的入侵检测系统都能够进行某些重组。不过,还是有很多方法可以避开入侵检测系统的监视。碎片重组的问题是 在进行字符串匹配以前,入侵检测系统必须在内存中缓存所有的碎片,然后进行重组。而且,他还需要直到、碎片在目的主机会如何 重组。Thomas Ptacek and Timoth Newsham于1998年写的Insertion,Evasion and Denial of Service: Eluding Network Intrusion Detection描述了许多基于 网络的碎片躲避和其它类型的躲避技术。碎片攻击包括:碎片覆盖、碎片重写、碎片超时和针对网络拓扑的碎片技术(例如使用小的 TTL)等。下面,我们将详细讨论。


4.1.碎片覆盖

所谓碎片覆盖就是发送碎片覆盖先前碎片中的数据。例如:

碎片1 GET x.idd
碎片2 a.?(缓冲区溢出数据)

第二个碎片的第一个字符覆盖第一个碎片最后一个字符,这两个碎片被重组之后就变成了GET x.ida?(缓冲区溢出数据)。实际情况远 非这么简单,更详细的细节请参考烂文IDS欺骗之Fragroute篇(上)。


4.2.碎片数据覆盖

这种方法和上面的碎片覆盖有些类似,只不过是覆盖全部的碎片数据,例如:

碎片1 GET x.id
碎片2 一些随机的字符
碎片3 a.?(缓冲区溢出数据)

这些碎片在经过目标系统的重组之后,碎片3将完全覆盖碎片2,重组之后的数据变成GET x.ida?(缓冲区溢出数据)。如果入侵检测系 统的重组方式和目标系统不同,就无法重组出“GET x.ida?(缓冲区溢出数据)”,因此就检测不出这个攻击。


4.3.碎片超时

这种攻击依赖于入侵检测系统在丢弃碎片之前会保存多少时间。大多数系统会在60秒之后将丢弃不完整的碎片流(从收到第一个碎片开 始计时)。如果入侵检测系统保存碎片的时间小于60秒,就会漏掉某些攻击。例如:

碎片1(设置了MF位) GET foo.id
碎片2(59秒之后发出) a?(缓冲区溢出数据)

如果IDS保存起始碎片的时间不到60秒,就会漏过攻击。幸运的是,如果配置没有错误,现在的网络入侵检测系统能够检测此类攻 击。

这种技术结合其它的网络技术(例如:TTL值)将更有威胁。如果入侵检测系统和被监视的系统不在同一个网段,攻击者就可以在TTL 上做手脚。有的单位由于经费的限制,不能在自己的每个子网都部署IDS节点,只在网络的出入口部署一套IDS,监视所有的网络流 量。这种情况下,如果被攻击的主机在其它的子网,攻击数据包到目标系统的跳数就大于到IDS的跳数。攻击者可以伪造碎片的TTL, 使某些碎片刚好能够到达,而无法到达目标系统,例如:

碎片序号 负载 TTL(假设攻击者到目标的跳数是5,到IDS的跳数是3)
1 GET foo.id 5
2 evasion.html 3
3 a?(缓冲区溢出数据) 5

从这些碎片中,IDS重组的数据是“GET foo.idevasion.html a?(缓冲区溢出数据)”或者“GET foo.idevasion.html”(如果IDS的超时 时间小于60秒)。通过这种方式,攻击者成功地在IDS中插入了垃圾数据。

5.碎片和snort特征码

下面我们把上述攻击和某些snort特征码进行比较。对于.ida缓冲区溢出攻击,默认的snort特征码几乎无法捕获任何通过碎片发动的攻 击(如果使用了frag2预处理模块,snort可以截获碎片超时攻击)。下面是针对.ida缓冲区溢出攻击的snort检测规则:

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS 80 (msg:"WEB-IIS ISAPI
.ida attempt"; uricontent:".ida?"; nocase; dsize:>239; flags:A+;
reference:arachnids,552; classtype:web-application-attack;
reference:cve,CAN-2000-0071; sid:1243; rev:2;)

另外,snort还有一条检测小碎片的规则,一旦发现太小的碎片,就会触发这条规则:

alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:"MISC Tiny
Fragments"; fragbits:M; dsize: < 25; classtype:bad-unknown; sid:522)

但是,这样还是不能检测某些攻击。还是以ida缓冲区溢出为例,这个攻击实际上和请求的URI无关,因此攻击者可以在前面加入一些 垃圾数据以避免触发碎片检测规则。

碎片1 GET reallylongstringtoevadedetect.i
碎片2 da?(缓冲区溢出数据)

这些技术并非只针对snort。Cisco Secure IDS也能够进行碎片重组,并且能够对上述碎片攻击进行报警。

实际上,碎片攻击要复杂的多,尤其是涉及到TTL和碎片覆盖。如果想更为深入地了解这方面技术,请参考Network Intrusion Detection: Evasion, Traffic Normalization, and End-to-End Protocol Semantics。

检测碎片攻击也非常困难。使IDS的碎片超时时间至少为60秒,增加对异常碎片的报警,最重要的是系统管理人员要对碎片攻击的潜 在威胁有清醒的认识。2002年四月,Dug Song发布了Fragroute,引发了不小的震动。很快,snort社团发布了能够对碎片攻击进行更好检 测的snort1.8.6版。

6.拒绝服务

还有一种比较野蛮的方法就是拒绝服务。拒绝服务可以针对检测设备本身和管理设备。Stick、snot和其它一些测试工具能够是入侵检测 设备产生大量的报警。使用这些工具,可以达成如下目标:



消耗检测设备的处理能力,是真正的攻击逃过检测。
塞满硬盘空间,使检测设备无法记录日志。
使检测设备产生超出其处理能力的报警。
使系统管理人员无法研究所有的报警。
挂掉检测设备。

对IDS来说,这类工具无迹可寻,因此非常难以对付。

结论

本文我们讨论了一些常用的IDS躲避技术及其对策。其中有些技术需要攻击者具有熟练的攻击技巧,而有写技术却无需太多的技巧。 而fragroute之类的工具出现,大大降低了攻击者采用某些技术的难度,使防御的一方总是处于被动。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Discuz! 官方站 ( 皖ICP备16010102号 )star

GMT+8, 2024-12-23 01:41 , Processed in 0.022980 second(s), 3 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表