简介: 漏洞扫描器是一种自动检测远程或本地主机安全性弱点的程序。通过使用漏洞扫描器,系统管理员能够发现所维护的Web服务器的各种TCP端口的分配、提供的服务、Web服务软件版本和这些服务及软件呈现在Internet上的安全漏洞。从而在计算机网络系统安全保卫战中做到“有的放矢”,及时修补漏洞,构筑坚固的安全长城。

引言

随着科学技术的飞速发展,21世纪的地球人已经生活在信息时代。20世纪人类两大科学技术成果--计算机技术和网络技术,均已深入到人类社会的各个领域,Internet把"地球村"的居民紧密联系在一起,"天涯若比邻"已然成为现实。互联网之所以能这样迅速蔓延,被世人接受,是因为它具备特有的信息资源。无论对商人、学者,还是对社会生活中的普通老百姓,只要你进入网络的世界,就能找到其隐藏的奥妙,就能得到你所需要的价值,而这其中种种的人类社会活动,它们的影响又是相互的。近年来Internet的迅速发展,给人们的日常生活带来了全新的感受,"网络生存"已经成为时尚,同时人类社会诸如政治、科研、经济、军事等各种活动对信息网络的依赖程度已经越来越强,"网络经济"时代已初露端倪。

然而,网络技术的发展在给我们带来便利的同时也带来了巨大的安全隐患,尤其是Internet和Intranet的飞速发展对网络安全提出了前所未有的挑战。技术是一把双刃剑,不法分子试图不断利用新的技术伺机攻入他人的网络系统,而肩负保护网络安全重任的系统管理员则要利用最新的网络技术来防范各种各样的非法网络入侵行为。事实已经表明,随着互连网的日趋普及,在互连网上的犯罪活动也越来越多,特别是Internet大范围的开放以及金融领域网络的接入,使得越来越多的系统遭到入侵攻击的威胁。但是,不管入侵者是从外部还是从内部攻击某一网络系统,攻击机会都是通过挖掘操作系统和应用服务程序的弱点或者缺陷来实现的,1988年的"蠕虫事件" 就是一个很好的实例。目前,对付破坏系统企图的理想方法是建立一个完全安全的没有漏洞的系统。但从实际上看,这根本是不可能的。美国Wisconsin大学的Miller给出一份有关现今流行操作系统和应用程序的研究报告,指出软件中不可能没有漏洞和缺陷。因此,一个实用的方法是,建立比较容易实现的安全系统,同时按照一定的安全策略建立相应的安全辅助系统,漏洞扫描器就是这样一类系统。就目前系统的安全状况而言,系统中存在着一定的漏洞,因此也就存在着潜在的安全威胁,但是,如果我们能够根据具体的应用环境,尽可能地早地通过网络扫描来发现这些漏洞,并及时采取适当的处理措施进行修补,就可以有效地阻止入侵事件的发生。因此,网络扫描非常重要和必要。

漏洞扫描器概述

漏洞扫描器是一种自动检测远程或本地主机安全性弱点的程序。通过使用漏洞扫描器,系统管理员能够发现所维护的Web服务器的各种TCP端口的分配、提供的服务、Web服务软件版本和这些服务及软件呈现在Internet上的安全漏洞。从而在计算机网络系统安全保卫战中做到"有的放矢",及时修补漏洞,构筑坚固的安全长城。

按常规标准,可以将漏洞扫描器分为两种类型:主机漏洞扫描器(Host Scanner)和网络漏洞扫描器(Network Scanner)。主机漏洞扫描器是指在系统本地运行检测系统漏洞的程序,如著名的COPS、tripewire、tiger等自由软件。网络漏洞扫描器是指基于Internet远程检测目标网络和主机系统漏洞的程序,如Satan、ISS Internet Scanner等。

本文针对目前TCP/IP网络和各种网络主机的安全现状,设计并实现了一个网络漏洞扫描器,在实际使用中取得了很好的效果。

网络漏洞扫描器的设计

网络漏洞扫描器的总体结构

我们设计的漏洞扫描器基于浏览器/服务器(B/S)结构,整个扫描器实现于一个Linux、UNIX和Windows操作系统相混合的TCP/IP网络环境中,其总体结构如图1所示,其中运行Linux的工作站作为发起扫描的主机(称为扫描主机),在其上运行扫描模块和控制平台,并建有漏洞库。扫描模块直接从扫描主机上通过网络以其他机器为对象(称为目标主机,其上运行的操作系统可以是UNIX、Linux、Windows 2000/NT等)进行扫描。而控制平台则提供一个人机交互的界面。


网络漏洞扫描器的设计与实现_设计与实现

网络漏洞扫描器的扫描原理和工作原理

网络漏洞扫描器通过远程检测目标主机TCP/IP不同端口的服务,记录目标给予的回答。通过这种方法,可以搜集到很多目标主机的各种信息(例如:是否能用匿名登陆,是否有可写的FTP目录,是否能用Telnet,httpd是否是用root在运行)。在获得目标主机TCP/IP端口和其对应的网络访问服务的相关信息后,与网络漏洞扫描系统提供的漏洞库进行匹配,如果满足匹配条件,则视为漏洞存在。此外,通过模拟黑客的进攻手法,对目标主机系统进行攻击性的安全漏洞扫描,如测试弱势口令等,也是扫描模块的实现方法之一。如果模拟攻击成功,则视为漏洞存在。

在匹配原理上,该网络漏洞扫描器采用的是基于规则的匹配技术,即根据安全专家对网络系统安全漏洞、黑客攻击案例的分析和系统管理员关于网络系统安全配置的实际经验,形成一套标准的系统漏洞库,然后再在此基础之上构成相应的匹配规则,由程序自动进行系统漏洞扫描的分析工作。

所谓基于规则是基于一套由专家经验事先定义的规则的匹配系统。例如,在对TCP 80端口的扫描中,如果发现/cgi-bin/phf或/cgi-bin/Count.cgi,根据专家经验以及CGI程序的共享性和标准化,可以推知该WWW服务存在两个CGI漏洞。同时应当说明的是,基于规则的匹配系统也有其局限性,因为作为这类系统的基础的推理规则一般都是根据已知的安全漏洞进行安排和策划的,而对网络系统的很多危险的威胁是来自未知的安全漏洞,这一点和PC杀毒很相似。

实现一个基于规则的匹配系统本质上是一个知识工程问题,而且其功能应当能够随着经验的积累而利用,其自学习能力能够进行规则的扩充和修正,即是系统漏洞库的扩充和修正。当然这样的能力目前还需要在专家的指导和参与下才能实现。但是,也应该看到,受漏洞库覆盖范围的限制,部分系统漏洞也可能不会触发任何一个规则,从而不被检测到。

整个网络扫描器的工作原理是:当用户通过控制平台发出了扫描命令之后,控制平台即向扫描模块发出相应的扫描请求,扫描模块在接到请求之后立即启动相应的子功能模块,对被扫描主机进行扫描。通过对从被扫描主机返回的信息进行分析判断,扫描模块将扫描结果返回给控制平台,再由控制平台最终呈现给用户。

CGI的应用

整个漏洞扫描系统利用了浏览器/服务器(B/S)架构,目的是为了消除由于操作系统平台的不同而给程序的运行带来的差异,还为了能利用HTML提供的一系列功能,如超文本功能、灵活的版面编辑功能来构建一个美观灵活的人机接口。在该网络漏洞扫描器的实现中,我们通过CGI技术来连接前台的浏览器和后台的扫描程序。

CGI是通用网关接口,作为一种规范,它允许Web服务器执行其他程序并将它们的输出以相应的方式储存在发给浏览器的文本、图形和音频中。CGI程序能够提供从简单的表单处理到复杂的数据库查询等各种功能,这大大增强了Web的动态处理能力和交互能力。服务器和CGI程序相结合能够扩充和自定义World Wide Web的能力。

CGI过程的主要步骤如下:

  • 浏览器将URL的第一部分解码并联系服务器;

  • 浏览器将URL的其余部分提供给服务器;

  • 服务器将URL转换成路径和文件名;

  • 服务器意识到URL指向一个程序,而非一个静态的文件;

  • 服务器准备环境变量,执行CGI程序;

  • 程序执行,读取环境变量和STDIN;

  • 程序为将来的内容向STDOUT发送正确的MIME头信息;

  • 程序向STDOUT发送其输出的其余部分,然后终止;

  • 服务器发现程序终止,关闭与浏览器的连接;

  • 浏览器从程序中显示输出。

STDIN和STDOUT是标准输入和标准输出的助记符。对Web服务器,STDOUT送至CGI程序的STDIN,程序的STDOUT反馈回服务器的STDIN。在激活具有POST方法的CGI程序时,服务器使用它的STDOUT;对于GET方法,服务器不使用STDOUT。两种情况下,服务器都要求CGI程序通过STDOUT返回信息。在我们的程序中选择了POST方法。

   转载:http://www.ibm.com/developerworks/cn/security/se-cgiscaner/part1/

第二部分

本文的第一部分分析了当前网络巨大的安全隐患,概述漏洞扫描器原理并针对目前TCP/IP网络和各种网络主机的安全现状,设计了一个网络漏洞扫描器。本部分将具体阐述了这个网络漏洞扫描器的实现。

网络漏洞扫描器的实现

扫描模块的实现

整个网络漏洞扫描器的核心部分是扫描模块,它是由很多子模块组成的,其结构如图2所示。

基本信息探测子模块的实现
在设计时加入该模块的目的是在调用扫描主模块之前探测主机是否在线,以避免不必要的空扫描。该模块的实现原理和常用的ping命令相似,方法是向目标主机发送ICMP回显报文请求,根据返回值来分析判断主机是否在线。所有安装了TCP/IP协议的在线网络主机,都会对这样的ICMP回显报文请求给与答复。虽然现在有些主机装了个人防火墙,可以屏蔽掉这样的ICMP回显报文请求,但是我们这个扫描系统的对象是提供网络服务的网络主机,而这样的主机是不应该屏蔽掉ICMP回显报文请求的,因为这样会让一些用户误认为该主机不在线,从而丧失了作为网络服务器的意义。为了降低网络拥塞导致丢包的可能性,在实现中重复四次向目标主机发送ICMP回显请求包。

该模块不只探测主机是否在线,而且能根据ICMP回显应答报文的TTL(TTL是位于IP首部中的生存时间字段)值来粗略分辨出目标主机操作系统,为下一步的扫描提供依据,特别是在扫描模块的调用和漏洞库的选择上。

该模块在实现中和其他模块不同的一个最大特点是:其他扫描模块是针对应用层的,用一般的套接字即能完成网络连接;而该模块是针对于网络层的,使用一种叫原始套接字的技术来实现。原始套接字(raw socket)提供了一些使用TCP和UDP套接字不能实现的功能:可以访问ICMP和IGMP等协议的数据包,可以读写内核不处理的IP数据包,可以创建自定义的IP数据首部。使用原始套接字可以编写基于IP协议的高层网络协议。

端口扫描子模块的实现
当基本信息探测子模块得知目标主机在线时,端口扫描子模块即被调用。该模块将根据传来的参数相应的扫描TCP的1~1024或者1~65535端口。扫描方式是利用TCP的完全连接方式,即利用TCP connect 扫描技术来设计扫描模块,这是最基本的TCP扫描。通常通过调用套接口函数connect()连接到目标计算机上,完成一次完整的三次握手过程。如果端口处于侦听状态,那么connect()就能成功返回。否则,这个端口不可用,即没有提供服务。这个技术的一个最大的优点是不需要任何权限。系统中的任何用户都有权利使用这个调用。另外的一个优点就是比其他扫描方式(如SYN扫描和FIN扫描等等)更稳定可靠。但这种方法的一个缺陷是:扫描方式不隐蔽。通常作为一个扫描器软件的应用,TCP的connect会重复且大量地被集中使用,在被扫描的一端则会很容易发现这种扫描行为,目标计算机的log文件会显示一连串的连接和连接是否出错的服务消息,并且能很快地使它关闭;而且大多数防火墙也能屏蔽这种扫描,随着防火墙技术的快速发展,其他的一些曾经被认为是很隐蔽的扫描方式也可能被防火墙发现并屏蔽掉。所以相对而言,TCP connect扫描方式的这个缺陷已经被淡化了。而且,我们开发的扫描系统是从系统管理员的角度出发,因此上述的问题都是不存在的,除非他/她非法扫描他人网站主机。


网络漏洞扫描器的设计与实现_设计与实现_02
图2 扫描模块的结构

网络扫描是个集中的、重复的行为,显而易见,它也是个比较耗资源的行为--不光是耗费扫描主机的资源,也耗费被扫描主机的资源;不光占用主机的资源,同时也占用网络相当多的资源。总体上看是个特别耗时的过程。在该网络扫描器的设计和实现的过程中,我们从两方面进行了优化:利用非阻塞连接技术和多进程技术。其结果是,首先,这两种技术的运用明显地加快了扫描的速度;而且,用多进程来实现高效率的利用了资源,从而达到了节省资源的功效。

网络漏洞扫描是建立在端口扫描的基础之上的。从黑客攻击行为的分析和收集的漏洞来看,绝大多数都是针对某一个网络服务,也就是针对某一个特定的端口的。所以漏洞扫描也是以同样的思路来进行的。而如今大多数国内国外的扫描器把端口扫描和具体的漏洞扫描分开来,相互之间几乎没有什么联系:端口扫描的目的就是为了向用户报出当前所开的端口和网络服务,以及看是否有些特定的后门存在;漏洞扫描则完全是另外一个独立的流程,不管目标主机的相应端口及服务是否打开,都要做一系列的扫描。这样看起来好像扫得很全面很彻底,但很明显的一点是,如果在对目标主机毫无了解的情况下,比如说是一台最普通的、几乎没有提供任何网络服务的机器,此时对它也进行彻底的漏洞扫描可以说是意义甚微的,甚至可以说在某些时候会对系统及网络有些反面的影响。

而我们在设计实现该漏洞扫描系统时则从另一个角度出发,保证在达到同等目的的前提下,尽量少占用网络、主机以及时间资源,提高资源的利用率和扫描系统的效率。基本思想是:避免不必要的模块调用,根据不同的实际情况来调用相应的扫描子模块。

在实现中,所有子模块的运行都是和端口扫描的主流程同时进行的。在此,我们利用了多进程技术来实现并发。进程是具有一定功能的程序,是关于一个数据集合的一次运行活动,它是程序运行的基本单位。在传统的UNIX模型中,当一个进程需要由另一个实体执行某些操作时,该进程派生(fork)一个子进程,让子进程去进行处理。此时子进程与父进程是完全独立的两个运行实体,以这样的方式可以实现并行。现在在UNIX/Linux系统中也可以用线程来实现程序的并行执行。和线程比起来,fork子进程存在以下两个问题:

  1. fork的代价是昂贵的:内存映像要从父进程拷贝到子进程,所有描述字要在子进程中复制等等。目前的实现使用一种称为写时拷贝(copy-on-write)的技术,可避免父进程数据空间向子进程的拷贝,除非子进程需要自己的拷贝。尽管有这种优化技术,fork仍然是很昂贵的。

  2. fork子进程执行后,需要用进程间通信(IPC)在父子进程之间传递信息。fork之前的信息容易传递,因为子进程从一开始就有父进程数据空间以及所有描述字的拷贝。从子进程返回信息给父进程则需要做更多的工作。

在我们的扫描系统的设计中,所需要的并发执行模块数并不是很多,对于现有的硬件设备来讲,创建十来个子进程的代价根本算不上什么,这样fork子进程的第一种缺陷的影响几乎就不存在了; 关于它的第二种问题其实对我们的实现也没有影响,因为这些扫描子模块之间以及子模块和主模块之间的交流除了共享文件之外,避免了其它的通信。而且从实现上来说,线程使用比较复杂,采用fork子进程会使开发和调试相对简单易行些。

入侵扫描的实现
从图2中可以看出,由于扫描方式的不同,可以将端口扫描子模块分为两大类:网络扫描和入侵扫描。与网络扫描不同,入侵扫描没有对应的漏洞库,本节简单介绍三类入侵扫描子模块的实现方式。

FTP弱势密码探测子模块主要是对一些可能存在的用户名作弱势密码的探测。其实现方法主要就是模拟客户端的用户协议解释器的功能,和服务器端建立连接并发送一系列命令和处理相应的应答,以此模拟登录,从而判断是否存在有弱势密码的账号。

FTP命令和应答在客户和服务器的控制连接上是以NVT ASCII码形式传送的。这些命令都是3或4个字节的大写ASCII字符,其中一些带选项参数。从客户向服务器发送的FTP命令超过30种,如ABOR(放弃先前的FTP命令和数据传输)、QUIT(从服务器上注销)、SYST(服务器返回系统类型)等。应答都是ASCII码形式的3位数字,并跟有报文选项。其原因是软件系统需要根据数字代码来决定如何应答,而选项是面向人工处理的。在我们的子模块中是根据应答中的数字代码来判断的,如125(数据连接已经打开,传输开始)、331(用户名就绪,要求输入口令)、501(语法错误--无效参数)等。

OPENRelay邮件转发漏洞是针对SMTP网络协议的。用TCP进行的邮件交换是由报文传送代理MTA(Message Transfer Agent)完成的。最普通的Unix系统中的MTA是Sendmail。客户端MTA通过访问服务器端的25号端口来和服务器端的MTA通信。两个MTA之间也用NVT ASCII进行通信。客户向服务器发出命令,服务器用数字应答码和可选的可读字符串进行响应。这与FTP非常类似。关于服务器端的应答也与FTP非常类似,在此就不赘述了。

OPENRelay邮件转发漏洞探测子模块也是通过发送一系列的命令和分析处理一系列的应答,以此模拟客户端MTA的功能来通过服务器连续发送一定数量的邮件,从而判断服务器是否没有屏蔽掉OPENRelay的功能。

Unicode遍历目录漏洞探测子模块是针对80端口的WWW网络服务的。WWW服务遵循的是HTTP协议,所以HTTP协议的一些特点决定了该子模块的实现。Unicode遍历目录漏洞的扫描是对IIS服务器软件的编码机制存在的漏洞进行具体的探测。不同的测试漏洞的特殊编码加上命令后,被封装在HTTP协议的请求中,向目标主机的80端口发送,并靠分析返回的状态码分析这种编码是否绕过了IIS的路径检查,可以执行相应的命令了。在Unicode遍历目录漏洞探测子模块的实现中,所采用的请求方法是GET方法。

扫描模块的流程
扫描模块在工作时,首先进行初始化,在初始化阶段,主要是读取所需的参数。比如从基本信息探测子模块得到操作系统类型,由此来决定在扫描中需要使用的漏洞库;还有一些用户自己配置的参数。除了读取参数外,还要建立一些文件以供以后使用。

初始化后,建立非阻塞socket并连接,然后根据得到的相关端口及对应的服务,来调用相应的漏洞扫描子模块(包括CGI漏洞扫描子模块、POP漏洞扫描子模块、FTP漏洞扫描子模块、SSH漏洞扫描子模块、HTTP漏洞扫描子模块、SMTP漏洞扫描子模块和IMAP漏洞扫描子模块以及三种类型的入侵扫描子模块),当所有的端口都已经扫描完以后,调用后门扫描子模块和其他漏洞扫描子模块。由于这两个扫描子模块并不是针对某一个端口或网络服务的,所以没有像其他的漏洞扫描子模块一样在端口扫描过程中被调用。但有一点是和其他子模块是一致的,即这两个子模块的调用形式也是通过创建子进程来完成的。

3.5 漏洞库的建立

一个网络漏洞扫描系统的灵魂就是它所使用的系统漏洞库,漏洞库信息的完整性和有效性决定了扫描系统的功能,漏洞库的编制方式决定了匹配原则,以及漏洞库的修订、更新的性能,同时影响扫描系统的运行时间。

设计原则
通过比较分析和实验分析,在漏洞库的设计中,我们遵循了以下几条原则:

  1. 从漏洞库的简易性、有效性出发,选择以文本方式记录漏洞。这样易于用户自己对漏洞库进行添加配置。因此在我们提供漏洞库升级的基础上,又多出了一条途径更新漏洞库,以保持漏洞库的实时更新,也使得漏洞库可以根据不同的实际环境而具有相应的特色。

  2. 对每个存在安全隐患的网络服务建立对应的漏洞库文件。一般情况下一个网络服务对应两个漏洞库,一个是针对UNIX的漏洞库,另一个则是针对Windows NT/2000的漏洞库。

  3. 对漏洞危险性进行分级。这有助于系统管理员了解漏洞的危险性,从而决定所要采取的措施。

  4. 提供漏洞危害性描述和建议的解决方案。有些扫描器,虽然扫描漏洞的功能强大,但不提供详细描述和解决方案(如著名的扫描器ISS Internet Scanner)。这往往导致系统管理员对检测出的漏洞没有足够的重视,或不了解它的危害也不知如何修补漏洞而暂置一旁。因此,漏洞扫描器要真正发挥它的预警及预防的作用,真正成为系统管理员的有效助手,就应当提供对漏洞的具体描述和有效的解决方案。

漏洞分级原则
在对黑客攻击行为分析的基础上,又借助了一些资深的系统管理员的经验,我们对漏洞进行了比较粗略的分级。将漏洞按其对目标主机的危险程度分为三级,即A级、B级和C级。A级漏洞是允许恶意入侵者访问并可能会破坏整个目标系统的漏洞,如允许远程用户未经授权访问的漏洞。A级漏洞是威胁最大的一种漏洞,大多数A级漏洞是由于较差的系统管理或配置有误造成的。同时,几乎可以在不同的地方,在任意类型的远程访问软件中都可以找到这样的漏洞。如,FTP、gopher、Telnet、Sendmail、finger等一些网络程序常存在一些严重的A级漏洞。B级漏洞是允许本地用户提高访问权限,并可能允许其获得系统控制的漏洞。例如允许本地用户非法访问的漏洞。网络上大多数B级漏洞是由应用程序中的一些缺陷或代码错误引起的。Sendmail和Telnet都是典型的例子。此外,因编程缺陷或程序设计语言的问题造成的缓冲区溢出问题也是一类典型的B级安全漏洞。C级漏洞是任何允许用户中断、降低或阻碍系统操作的漏洞,如拒绝服务漏洞。最典型的一种拒绝服务攻击是SYNFLOOD,即入侵者将大量的连接请求发往目标服务器,目标主机不得不处理这些"半开"的SYN,然而并不能得到ACK回答,很快服务器将用完所有的内存而挂起,任何用户都不能再从服务器上获得服务。综上所述,对网络主机危害最严重的是A级漏洞,其次是B级漏洞,而C级漏洞是对系统正常工作进行干扰。

漏洞库的实现
通过大量的多方收集,主要是对 www.cert.orgwww.aucert.comwww.securefocus.com及中国绿色联盟等反黑权威网站漏洞信息进行分类整理,我们对存在漏洞的主要的网络服务逐一建立了三级漏洞描述文件,作为各个漏洞扫描子模块的访问库体。

在每个漏洞库文件中,每条漏洞信息占一行,行首用"!"标示漏洞级别,叹号的个数代表漏洞危险级别。A级危害以"!!!"标示,B级以"!!"标示,C级以"!"标示。接下来是漏洞的特征字符串,当特征字符串不止一个时,用一个不容易引起混淆的(~)字符加以隔离。

漏洞形成的原因形形×××、不一而足,在我们设计开发的漏洞库中,主要包含以下类型的漏洞:CGI脚本漏洞、POP3漏洞、FTP漏洞、SSH漏洞、HTTP漏洞、SMTP漏洞、IMAP漏洞、后门漏洞、RPC漏洞、DNS漏洞等。下面我们将以CGI脚本漏洞和SMTP漏洞为例来简单说明漏洞库的编制。

(1)CGI脚本漏洞
CGI脚本是实现Web交互功能的重要手段。Shell 脚本、Perl程序和C可执行程序是CGI脚本最常采用的形式。由于程序编写上的疏忽,很多CGI脚本都存在漏洞,根据我们所收集的漏洞信息,CGI漏洞的危害主要有三种:

  1. 缓冲区溢出攻击
    这种攻击实质是不遵守规则、歪曲或违反页面中建立的某个限制或约束。大部分CGI 脚本是作为HTML表单的后台运行的,负责处理由用户输入的信息并提供某种定制的输出。因为在这种情况下,大部分CGI 脚本编写时都等待某种特定格式的数据。然而,黑客可以有许多方法绕过这些预定义的格式而给脚本发送一些看起来是随机的数据。此时,由于CGI 脚本可能在对输入数据的有效性的判定上存在不足,缺少全面的输入验证和净化,导致攻击者能够将特殊的字符和本地系统命令结合起来,作为参数输入,从而使得Web服务器执行该命令。

    例如: !/cgi-bin/phf
    漏洞描述: Apache httpd服务器程序(1.0.3版本)的PHF脚本由于输入验证中遗失了对换行符("\n",十六进制为0x0a)的检查,从而可用于转义脚本,诱骗Web服务器程序的本地语法运行该转义符后的任何内容。比如,如果受攻击的Web服务器程序的执行用户具有/etc/passwd文件的读权限,那么以下URL将输出该文件的内容: http://www.somedomain.org/cgi-bin/phf?Qalias=x%0a/bin/cat%20/etc/passwd 解决方案:自行修改该脚本,加入对\n的检验,或者暂停使用该脚本。


  2. 数据验证型溢出攻击
    由于CGI程序本身或程序调用的函数缺乏对用户输入数据的合法性检查,未能滤除一些特殊字符,使得入侵者可以通过构造请求来达到入侵的目的。比如,缺乏对"../"的过滤,可能导致入侵者读取系统的任意文件。

    例如: !!/shop.cgi
    漏洞描述:shop.cgi/shop.pl用于网上购物,支持SSL,包含多种验证模块,配置文件是shop.cfg。正常的请求显示商品信息的URL语法是: http://example.com/cgi-bin/shop.cgi/page=products.htm/SID=SHOPPING_ID_HERE ,于是带有客户信息的products.htm文件被显示出来。$page变量的值是通过open()调用打开的,open()调用本身并没有做任何输入/访问验证,也没有任何边界检查,诸如: http://example.com/cgi-bin/shop.cgi/page=../../../../etc/passw 。这样的URL请求是合法的,于是/etc/passwd就会被打开并显示出来。 解决方案:考虑利用正则表达式增加输入验证,过滤诸如../ 和 .\./ . 之类的字符组合,也可以增加一个变量限制目录遍历深度。结合这两种技术,就可以限制来自潜在攻击者的任意目录遍历行为。


  3. 信息泄漏
    一些CGI程序所提供的功能自身违背安全性要求,如损害了信息的保密性,极易被入侵者利用。

    例如: !/webpage.cgi
    漏洞描述:当URL请求的文件不存在时,webpage.cgi会向客户端浏览器返回某些敏感信息,比如脚本所在路径、HTTP根目录所在路径、Perl版本、server_admin、server_name、PATH环境变量等。这就可以为进一步的攻击做准备。 解决方案:在浏览器中禁止java applet。目前,大多数网站均使用免费的公共CGI脚本程序去驱动各自的Web服务,如此导致有缺陷的CGI脚本在Internet上泛滥开来。因此,对CGI脚本的安全性应高度重视。


(2)SMTP漏洞
SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)是用来发送邮件的协议,其服务守护程序是Sendmail。Sendmail因为大而复杂,配置又十分麻烦,所以一度曾是Unix上的漏洞最多的程序,著名的蠕虫病毒就是利用Sendmail旧版本上的一个"DEBUG"命令的漏洞而从一个系统传播到另一个系统的。又如:利用ETRN命令可使Sendmail停止响应(即拒绝服务)。当Sendmail接收到ETRN命令时,它将调用fork()。此时子进程将代替父进程发送响应输出,而父进程将不再响应send()/write()错误。因此攻击者可发送大量ETRN命令,然后中断连接,这会使父进程连续地调用fork()和sleep(5),而无法恢复正常的响应。

攻击者利用这个漏洞可以产生大量的"不可用"Sendmail子进程,导致Sendmail长时间挂起(即使攻击者的网络带宽和资源很少)。直接的后果就是耗尽所有的服务器内存(Linux 2.0内核将崩溃,出错信息为'no memory for Sendmail'、'no memory for klogd'或其它)。

Sendmail服务程序不断的升级,同时新的漏洞也不断的出现。一个不经意的错误,往往成了可怕的隐患。Sendmail高级版本中仍存在着种种漏洞,仅举两例说明:

例1: !!Sendmail~8.7
!!Sendmail~8.8.0
!!Sendmail~8.8.1
!!Sendmail~8.8.2

漏洞描述:Sendmail版本8.7-8.8.2存在一个可获得超级用户权限的漏洞。Sendmail服务一般作为守护进程运行,在标准SMTP端口(通常是25号端口)"监听"连接请求。超级用户是唯一允许以这种方式启动Sendmail服务的,因为Sendmail协议中有代码强制执行这种限制。但由于一个编码错误,任何本地用户都可能绕过检查,以守护进程的方式启动Sendmail。通过改变Sendmail的邮件环境,用户可以以超级用户的权限令Sendmail执行任意程序。
解决方案:升级到Sendmail 8.10以上的版本。

例2: !Sendmail~8.9.3
漏洞描述:mail.local是Sendmail里面的一个程序,它被用作本地邮件的传送代理。mail.local使用LMTP(本地邮件传输协议)接受标准输入并发信给用户。当在LMTP模式下时,mail.local处理的消息以".\n"开始。因此,我们可以发送一个2047字节的,后跟".\n"的字符串。那么这个字符串后面的内容就会被mail.local当做LMTP命令来处理。这样sendmail的日志或者过滤机制就失去了作用。另一个问题是,当LMTP命令被执行的时候,mail.local可能会产生结果输出。但是sendmail并不知道,所以不会去读I/O buffer。这些结果输出如果很多,就会导致sendmail和mail.local死锁,I/O Buffer也会被填满。
解决方法:sendmail 8.10以上版本已经解决了deadlock/LMTP 问题

结束语

我们针对目前TCP/IP网络和各种网络主机的安全现状,设计并实现了一个网络漏洞扫描器,该扫描器基于浏览器/服务器(B/S)结构,可以扫描UNIX、Windows 2000/NT等多种操作系统的安全漏洞。通过试运行,可以看出该扫描器具有如下特点:

  1. 能够多方位、多角度对处于网络环境中的重要网络主机进行安全扫描,可以分别模拟黑客和系统管理员的身份,对处于网络环境中的主机可能面对的安全隐患进行全面的检查。

  2. 扫描覆盖面广:能同时在系统级和应用级上进行隐患扫描。能针对网络主机的主流操作系统包括Unix、Linux和Windows NT/2000进行扫描,能检测出多达1000多种现势漏洞。

  3. 扫描速度快:利用多进程并发和TCP的非阻塞连接等技术加快了扫描的速度。在特定的扫描中根据不同的实际情况运行不同的模块,尽量避免一些没有必要的代码段的运行,进一步提高效率和速度。

  4. 可扩展性强:作为体现整个扫描系统功效的重要组成部分,漏洞库可从多个途径不断扩充、更新。用户可以根据简单的易操作规则把一些最新出现的安全漏洞整理后加入漏洞库。整个操作过程都十分简单友好。

  5. 可移植性强:采用服务器/浏览器结构,浏览器端可放在几乎任何操作系统平台上。目前运行在Linux平台上。

  6. 可配置性好:通过友好的图形化界面,用户可以十分方便的配置本系统的主要参数,以便于灵活的适应各种各样的实际网络应用环境。

  7. 扫描结果详尽:扫描结果包括关于被扫描主机的各方面详尽的信息。其中包括主机的IP地址、操作系统类型及版本号、补丁号、网络主机的三大网络服务的信息描述,以及主机开放的所有网络服务、主机上存在的网络安全漏洞等。另外,系统对扫描出的漏洞根据它的危害程度进行分级分别标示。并提供完整易操作的步骤来帮助用户方便地消除隐患。

  8. 人机界面美观友好:提供了一个全中文化的图形界面,界面赏心悦目,可操作性强,尽量达到简单易用。

http://www.ibm.com/developerworks/cn/security/se-cgiscaner/part2/