| <<返回 |
| 3.2 IP欺骗与防范 |
| 3.2 IP欺骗与防范 TCP/IP协议早期是为了方便地实现网络的连接,本身有着一些不安全的地方,从而使一些别有用心的人可以对TCP/IP网络进行攻击。这些攻击包括序列号欺骗、路由攻击、源地址欺骗等。IP欺骗是利用不同主机之间的信任关系而进行欺骗攻击的一种手段,这种信任关系是以IP地址验证为基础的。 3.2.1 IP欺骗原理 1.信任关系 在Unix 领域中,信任关系能够很容易得到。假如用户在主机A和B上各有一个账户,那么在主机A上使用时需要输入在A上的相应账户,在主机B上使用时必须输入在B上的账户,主机A和B把用户当作两个互不相关的用户,显然有些不便。为了减少这种不便,可以在主机A和主机B中建立起两个账户的相互信任关系。在主机A和主机B上用户的home目录中创建.rhosts 文件。在主机A上,用户的home目录中输入'echo " B username " > ~/.rhosts' ;在主机B上,用户的home目录中输入'echo " A username " > ~/.rhosts'。至此,用户能毫无阻碍地使用任何以r*开头的远程调用命令,如:rlogin、rcall、rsh等,而无口令验证的烦恼。这些信任关系是基于IP地址的。 rlogin 是一个简单的客户机/服务器程序。rlogin 允许用户从一台主机登录到另一台主机上。如果目标主机信任它,rlogin 将允许在不应答口令的情况下使用目标主机上的资源。安全验证完全是基于源主机的IP 地址。因此,我们能利用rlogin 从B远程登录到A,并且不会被提示输入口令。 2.TCP 序列号预测 IP只是发送数据包,并且保证它的完整性。如果不能收到完整的IP数据包,IP会向源地址发送一个ICMP 错误信息,希望重新处理。然而这个ICMP包也可能丢失。由于IP是无连接的,所以不保持任何连接状态的信息。每个IP数据包被发送出去,不关心前一个和后一个数据包的情况。由此看出,可以对IP堆栈进行修改,在源地址和目的地址中放入任意满足要求的IP地址,也就是说,提供虚假的IP地址。 TCP提供可靠传输。可靠性是由数据包中的多位控制字来提供的,其中最重要的是数据序列和数据确认,分别用SYN和ACK来表示。TCP 向每一个数据字节分配一个序列号,并且可以向已成功接收的、源地址所发送的数据包表示确认(目的地址ACK 所确认的数据包序列是源地址的数据包序列,而不是自己发送的数据包序列)。由于TCP是基于可靠性的连接,它能够处理数据包丢失、重复或顺序紊乱数据包等不良情况。实际上,通过向所传送出的所有字节分配序列编号,并且期待接收端对发送端所发出的数据提供收讫确认,TCP 能保证可靠的传送。接收端利用序列号确保数据的先后顺序,除去重复的数据包。TCP 序列编号可以看作是32位的计数器,从0至232-1 排列。每一个TCP连接交换的数据是顺序编号的。确认位(ACK)对所接收的数据进行确认,并且指出下一个期待接收的数据序列号。 TCP通过滑动窗口的概念来进行流量控制。设想在发送端,发送数据的速度很快而接收端接收速度却很慢的情况下,为了保证数据不丢失,显然需要进行流量控制,协调好通信双方的工作节奏。所谓滑动窗口,可以理解成接收端所能提供的缓冲区大小。TCP利用一个滑动的窗口来告诉发送端对它所发送的数据能提供多大的缓冲区。由于窗口由16位Bit所定义,所以接收端TCP 能最大提供65535个字节的缓冲。因此,可以利用窗口大小和第一个数据的序列号计算出最大可接收的数据序列号。 其他TCP标识位有RST(连接复位,Reset the Connection)、PSH(压入功能,Push Function)和FIN(发送者无数据,Finish)。如果RST 被接收,TCP连接将立即断开。RST 通常在接收端接收到一个与当前连接不相关的数据包时被发送。一个高层的进程将会触发在TCP头部的PSH标示,并且告诉TCP模块立即将所有排列好的数据发给数据接收端。FIN 表示一个应用连接结束。当接收端收到FIN并确认后,将断开连接,并接收不到任何数据。 TCP序列号预测的漏洞最早由Morris提出。他使用TCP序列号预测,即使是没有从服务器得到任何响应, 也能够产生一个TCP包序列。使用这种方法他能够欺骗在本地网络上的主机。 通常TCP连接建立一个包括3次握手的序列。客户选择和传输一个初始的序列号(SEQ标志)ISN C,并设置标志位SYN=1,告诉服务器它需要建立连接。服务器确认这个传输,并发送它本身的序列号ISN S,并设置标志位ACK,同时告知下一个期待获得的数据序列号是ISN=1。客户再确认它。经过三次确认后,双方开始传输数据。整个过程如下所示: C*S:SYN(ISN C ) S*C:SYN(ISN S ) ,ACK(ISN C ) C*S:ACK(ISN S ) 三次握手后,双方进行数据传送。 也就是说对一个会话,C必须得到ISN S确认。ISN S可能是一个随机数。 了解序数编号、如何选择初始序列号和如何根据时间变化是很重要的。考虑下列这种情况:当主机启动后序列编号初始化为1,但实际上并非如此。初始序列号是由tcp_init函数确定的。ISN每秒增加128000,如果有连接出现,每次连接将把计数器的数值增加64000。很显然,这使得用于表示ISN的32位计数器在没有连接的情况下每9.32 小时复位一次,从而最大限度地减少原有连接的信息干扰当前连接的机会。如果初始序列号是随意选择的,那么不能保证现有序列号不同于先前的序列号。假设有这样一种情况,在一个路由回路中的数据包最终跳出了循环,回到了"原有"的连接,显然会发生对现有连接的干扰。 假设一个入侵者X有一种方法,能预测ISN S。在这种情况下,入侵者可能将下列序号送给主机T来模拟客户真正的ISN S: X*S:SYN(ISN X ) ,SRC = T S*T:SYN(ISN S ) ,ACK(ISN X ) X*S:ACK(ISN S ) ,SRC =T X*S:ACK(ISN S ) ,SRC = T,无用数据 尽管S*T并不到X,但是X能知道它的内容,因此能发送数据。而X能对一个连接实施攻击。 那么怎样产生随机的ISN?在Berkeley系统中,最初的序列号变量由一个常数每秒加1产生,等到达这个常数的一半时,就开始一次连接。这样,如果开始了一个合法连接,并观察到一个ISN S在使用,便可以计算,得到ISN。ISN S *用在下一个连接企图。 Morris 指出,回复消息: S*T:SYN(ISN S ),ACK(ISN X ) 而该消息事实上并不消失,真正的主机将收到它,并试图重新连接。通过模仿一个在T上的端口,并向那个端口请求一个连接,就能产生序列溢出,从而使S*T消息看上去丢失了。 3.IP欺骗原理 首先我们看一个例子:当一台攻击者机器A要与一台ISP(Internet服务提供商)的主机B建立连接时,它的通信方式是先发一个SYN包告诉对方主机B,说"我要和你通信了",当B收到时,就回复一个ACK/SYN确认请求包给A主机。如果A是合法地址,就会再回复一个ACK包给B主机,然后两台主机就可以建立一个通信渠道了。可是攻击者机器A发出包的源地址是一个虚假的IP地址,或者可以说是实际上不存在的一个地址,ISP主机B发出的那个ACK/SYN包当然就找不到目标地址了。如果这个ACK/SYN包一直没有找到目标地址,那么也就是目标主机无法获得对方回复的ACK包。而在缺省超时的时间范围以内,主机的一部分资源要花在等待这个ACK包的响应上,假如短时间内主机A接到大量来自虚假IP地址的SYN包,它就要占用大量的资源来处理这些错误的等待,最后的结果就是系统资源耗尽以至瘫痪。 下面我们详细地介绍IP欺骗的过程。首先定义: A:目标主机 B:对于A来说,可信任的主机 X:不能到达的主机 Z:进攻主机 1(2):主机1伪装成主机2 IP欺骗由若干步骤组成,首先假定: (1)目标主机已经选定。 (2)信任模式已被发现,并找到了一个被目标主机信任的主机。 攻击者为了进行IP欺骗,采取如下步骤: (1)使得被信任的主机丧失工作能力,同时采样目标主机发出的TCP 序列号,猜测出它的数据序列号。 (2)伪装成被信任的主机,同时建立起与目标主机基于地址验证的应用连接。如果连接成功,攻击者可以使用一种简单的命令放置一个系统后门,以进行非授权操作。 一旦发现被信任的主机,为了伪装成它,往往需要使其丧失工作能力。由于攻击者将要代替真正的被信任主机,他必须确保真正被信任的主机不能接收到任何有效的网络数据,否则将会被发现。有许多方法可以做到这些。这里介绍"TCP SYN 淹没"。 建立TCP连接的第一步就是客户端向服务器发送SYN请求。通常,服务器将向客户端发送SYN/ACK 信号。客户端随后向服务器发送ACK,然后就可以进行数据传输。然而,TCP处理模块有一个处理并行SYN请求的最上限,它可以看作是存放多条连接的队列长度。其中,连接数目包括了那些三步握手法没有最终完成的连接,也包括了那些已成功完成握手,但还没有被应用程序所调用的连接。如果达到队列的最上限,TCP将拒绝所有其后的连接请求,直至处理了部分连接请求。因此,这里是有机可乘的。 攻击者往往向被进攻目标的TCP端口发送大量SYN请求,这些请求的源地址是使用一个合法的但是虚假的IP地址(假设使用该合法IP地址的主机没有开机或者已经被攻击而瘫痪)。受攻击的主机向该IP地址发送响应,但可惜杳无音信。与此同时IP包会通知受攻击主机的TCP:该主机不可到达。但不幸的是TCP会认为这是一种暂时的错误,并继续尝试连接(比如继续对该IP地址进行路由选择,发出SYN/ACK数据包等等),直至在TimeOut时间内确信无法连接。值得注意的是,攻击者是不会使用那些正在工作的IP地址的,因为这样一来,真正IP持有者会收到SYN/ACK响应,而随之发送RST给受攻击主机,从而断开连接。可以表示为如下模式。 时刻1 Z (X) ---SYN ---> B Z (X) ---SYN ---> B Z (X) ---SYN ---> B 时刻2 X <---SYN/ACK-- B X <---SYN/ACK-- B 时刻3 X <--- RST --- B 在时刻1时,攻击者的主机把大批SYN 请求发送到被信任的主机,使其TCP队列充满。在时刻2时,被信任的主机向它所相信的IP地址(虚假的IP)作出SYN/ACK反应。在这一期间,被信任主机的TCP模块会对所有新的请求予以忽视(不同系统的TCP 保持连接队列的长度有所不同。BSD 一般是5,Linux一般是6),被信任主机失去处理新连接的能力,攻击者利用这段时间空隙,冒充被信任的主机,向目标主机发起攻击。 下一步进行序列号取样和猜测。 前面已经提到,要对目标主机进行攻击,必须知道目标主机使用的数据包序列号。现在,我们来讨论攻击者是如何进行预测的。他们先与被攻击主机的一个端口(如SMTP端口)建立起正常的连接。通常,这个过程被重复若干次,并将目标主机最后所发送的ISN存储起来。攻击者还需要估计他的主机与被信任主机之间的RTT时间(往返时间),这个RTT时间是通过多次统计平均求出的。RTT 对于估计下一个ISN非常重要。前面已经提到每秒钟ISN增加128000,每次连接增加64000。现在就不难估计出ISN的大小了,它是128000乘以RTT的一半,如果此时目标主机刚刚建立过一个连接,那么再加上一个64000。估计出ISN大小后,立即就开始进行攻击。当攻击者虚假的TCP数据包进入目标主机时,根据估计的准确度不同,会发生不同的情况: 1. 如果估计的序列号是准确的,进入的数据将被放置在接收缓冲区以供使用。 2. 如果估计的序列号小于期待的数字,那么将被放弃。 3. 如果估计的序列号大于期待的数字,并且在滑动窗口之内,那么,该数据被认为是一个未来的数据,TCP模块将等待后继的数据。如果估计的序列号大于期待的数字,并且不在滑动窗口之内,那么,TCP将会放弃该数据并返回一个期望获得的数据序列号。 但是,攻击者的主机并不能收到返回的数据序列号。为什么呢? 时刻1 Z(B) ---SYN ---> A 时刻2 B <---SYN/ACK--- A 时刻3 Z(B) ---ACK---> A 时刻4 Z(B) ---PSH---> A 攻击者伪装成被信任主机的IP 地址(此时,该主机仍然处在停顿状态),向目标主机的513端口(rlogin的端口号)发送连接请求,如时刻1所示。在时刻2,目标主机对连接请求作出反应,发送SYN/ACK数据包给被信任主机(如果被信任主机处于正常工作状态,那么会认为是错误并立即向目标主机返回RST数据包,不幸的是此时它处于停顿状态)。按照计划,被信任主机会抛弃该SYN/ACK数据包。然后在时刻3,攻击者向目标主机发送ACK数据包,该ACK使用前面估计的序列号加1(因为是在确认)。如果攻击者估计正确的话,目标主机将会接收该ACK 。至此,攻击者主机和被攻击者主机就建立了一条TCP连接。在时刻4,双方开始数据传输。一般地,攻击者将在系统中放置一个后门,为下一次侵入铺平道路。 3.2.2 IP欺骗的防范 1.改变间隔 IP欺骗的关键在于现有系统中初始序列号变量的产生方法相对粗糙,序列号的变化可以预测。在Berkeley 系统中,TCP协议需要这个变量每秒增加25000次,因而改变速度比较慢。但是,最重要的是改变间隔,而不是速度。 我们考虑一下一个计数器工作在250000Hz时是否有帮助。我们先忽略其他发生的连接,仅仅考虑这个计数器以固定的频率改变。 为了知道当前的序列号,发送一个SYN包,收到一个回复: X*S:SYN(ISN X ) S*X:SYN(ISN S ) ,ACK(ISN X ) (1) 第一个欺骗包,它触发下一个序列号,并立即跟随服务器对这个包的反应: X*S:SYN(ISN X ) ,SRC = T (2) 序列号ISN S用于回应: S*T:SYN(ISN S ) ,ACK(ISN X ) 这个号码是X和S的往返精确的时间。这样,如果欺骗能精确地测量和产生这个时间,即使是一个4-U时钟都不能击退这次攻击。 因此,防止IP欺骗的第一个方法是改变序列号变化的间隔,而不是速度。 2.禁止基于IP地址的验证 IP欺骗的原理是冒充被信任的主机,而这种信任是建立在基于IP地址的验证上,因此,阻止这类攻击的办法就是放弃以IP地址为基础的验证。不允许r*类远程调用命令的使用;删除.rhosts文件;清空/etc/hosts.equiv 文件。这将迫使所有用户使用其他远程通信手段,如Telnet、ssh、skey等。 3.使用包过滤 如果用户的网络是通过路由器接入Internet 的,那么可以利用路由器来进行包过滤。确信只有内部LAN可以使用信任关系,而内部LAN上的主机对于LAN以外的主机要慎重处理。路由器可以帮助您过滤掉所有来自于外部而希望与内部建立连接的请求。 4.使用加密方法 还有一种阻止IP欺骗的方法是在通信时要求加密传输和验证。当有多种手段并存时,加密方法比较适用。 5.使用随机化的初始序列号 黑客攻击得以成功实现的一个很重要的因素就是,序列号不是随机选择的或者随机增加的。Bellovin描述了一种弥补TCP不足的方法,就是分割序列号空间。每一个连接将有自己独立的序列号空间。序列号将仍然按照以前的方式增加,但是在这些序列号空间中没有明显的关系。可以通过下列公式来说明: ISN =M+F(localhost,localport ,remotehost ,remoteport ) M:4微秒定时器 F:加密HASH函数。 F产生的序列号,对于外部来说是不应该能够被计算出或者被猜测出的。Bellovin建议F是一个结合连接标识符和特殊矢量(随机数,基于启动时间的密码)的HASH函数。 |
| <<返回 |