ip欺骗的技术比较复杂,不是简单地照猫画老虎就能掌握,但作为常规攻击手段,有必要理解其原理,至少有利于自己的安全防范,易守难攻嘛。
假设b上的客户运行rlogin与a上的rlogind通信:
1. b发送带有syn标志的数据段通知a需要建立tcp连接。并将tcp报头中的sequence number设置成自己本次连接的初始值isn。
2. a回传给b一个带有sys+ack标志的数据段,告之自己的isn,并确认b发送来的第一个数据段,将acknowledge number设置成b的isn+1。
3. b确认收到的a的数据段,将acknowledge number设置成a的isn+1。
b —- syn —-> a
b <—- syn+ack a
b —- ack —-> a
tcp使用的sequence number是一个32位的计数器,从0-4294967295。tcp为每一个连接选择一个初始序号isn,为了防止因为延迟、重传等扰乱三次握手,isn不能随便选取,不同系统有不同算法。理解
tcp如何分配isn以及isn随时间变化的规律,对于成功地进行ip欺骗攻击很重要。
基于远程过程调用rpc的命令,比如rlogin、rcp、rsh等等,根据/etc/hosts.equiv以及$home/.rhosts文件进行安全校验,其实质是仅仅根据信源ip地址进行用户身份确认,以便允许或拒绝用户rpc。关于上述两个文件请man,不喜欢看英文就去unix版看看我以前灌过的一瓢水。
ip欺骗攻击的描述:
1. 假设z企图攻击a,而a信任b,所谓信任指/etc/hosts.equiv和$home/.rhosts中有相关设置。注意,如何才能知道a信任b呢?没有什么确切的办法。我的建议就是平时注意搜集蛛丝马迹,厚积薄发。一次成功的攻击其实主要不是因为技术上的高明,而是因为信息搜集的广泛翔实。动用了自以为很有成就感的技术,却不比人家酒桌上的巧妙提问,攻击只以成功为终极目标,不在乎手段。
2. 假设z已经知道了被信任的b,应该想办法使b的网络功能暂时瘫痪,以免对攻击造成干扰。著名的syn flood常常是一次ip欺骗攻击的前奏。请看一个并发服务器的框架:
int initsockid, newsockid;
if ((initsockid = socket(…)) <0) {
error(“cant create socket”);
}
if (bind(initsockid, …) <0) {
error(“bind error”);
}
if (listen(initsockid, 5) <0) {
error(“listen error”);
}
for (;;) {
newsockid = accept(initsockid, …); /* 阻塞 */
if (newsockid <0) {
error(“accept error”);
}
if (fork() == 0) { /* 子进程 */
close(initsockid);
do(newsockid); /* 处理客户方请求 */
exit(0);
}
close(newsockid);
}
listen函数中第二个参数是5,意思是在initsockid上允许的最大连接请求数目。如果某个时刻initsockid上的连接请求数目已经达到5,后续到达initsockid的连接请求将被tcp丢弃。注意一旦连接通过三次握手建立完成,accept调用已经处理这个连接,则tcp连接请求队列空出一个位置。所以这个5不是指
initsockid上只能接受5个连接请求。syn flood正是一种denial of service,导致b的网络功能暂 碧被尽
z向b发送多个带有syn标志的数据段请求连接,注意将信源ip地址换成一个不存在的主机x;b向子虚乌有的x发送syn+ack数据段,但没有任何来自x的ack出现。b的ip层会报告b的tcp层,x不可达,但b的tcp层对此不予理睬,认为只是暂时的。于是b在这个initsockid上再也不能接收正常的连接请求。
z(x) —- syn —-> b
z(x) —- syn —-> b
z(x) —- syn —-> b
z(x) —- syn —-> b
z(x) —- syn —-> b
……
x <—- syn+ack b
x <—- syn+ack b
x <—- syn+ack b
x <—- syn+ack b
x <—- syn+ack b
……
作者认为这样就使得b网络功能暂时瘫痪,可我觉得好象不对头。因为b虽然在initsockid上无法接收tcp连接请求,但可以在another initsockid上接收,这种syn flood应该只对特定的服务(端口),不应该影响到全局。当然如果不断地发送连接请求,就和用ping发洪水包一个道理,使得b的tcp/ip忙于处理
负载增大。至于syn flood,回头有机会我单独灌一瓢有关dos的。如何使b的网络功能暂 碧被居 很多办法,根据具体情况而定,不再赘述。
3. z必须确定a当前的isn。首先连向25端口(smtp是没有安全校验机制的),与1中类似,不过这次需要记录a的isn,以及z到a的大致的rtt(round trip time)。这个步骤要重复多次以便求出rtt的平均值。现在z知道了a的isn基值和增加规律(比如每秒增加128000,每次连接增加64000),也知道了从z到a需要rtt/2的时间。必须立即进入攻击,否则在这之间有其他主机与a连接,isn将比预料的多出64000。
4. z向a发送带有syn标志的数据段请求连接,只是信源ip改成了b,注意是针对tcp513端口(rlogin)。a向b回送syn+ack数据段,b已经无法响应(凭什么?按照作者在2中所说,估计还达不到这个效果,因为z必然要模仿b发起connect调用,connect调用会完成全相关,自动指定本地socket地址和端口,可事实上b很可能并没有这样一个端口等待接收数据。除非z模仿b发起连接请求时打破常规,主动在客户端调用bind函数,明确完成全相关,这样必然知道a会向b的某个端口回送,在2中也针对这个端口攻击b。可是如果这样,完全不用攻击b,bind的时候指定一个b上根本不存在的端口即可。我也是想了又想,还没来得及看看老外的源代码,不妥之处有待商榷。总之,觉得作者好象在蒙我们,他自己也没有实践成功过吧。),b的tcp层只是简单地丢弃a的回送数据段。
5. z暂停一小会儿,让a有足够时间发送syn+ack,因为z看不到这个包。然后z再次伪装成b向a发送ack,此时发送的数据段带有z预测的a的isn+1。如果预测准确,连接建立,数据传送开始。问题在于即使连接建立,a仍然会向b发送数据,而不是z,z仍然无法看到a发往b的数据段,z必须蒙着头按照rlogin协议标准假冒b向a发送类似 “cat + + >> ~/.rhosts” 这样的命令,于是攻击完成。如果预测不准确,a将发送一个带有rst标志的数据段异常终止连接,z只有从头再来。
z(b) —- syn —-> a
b <—- syn+ack a
z(b) —- ack —-> a
z(b) —- psh —-> a
……
6. ip欺骗攻击利用了rpc服务器仅仅依赖于信源ip地址进行安全校验的特性,建议阅读rlogind的源代码。攻击最困难的地方在于预测a的isn。作者认为攻击难度虽然大,但成功的可能性也很大,不是很理解,似乎有点矛盾。考虑这种情况,入侵者控制了一台由a到b之间的路由器,假设z就是这台路由器,那么a回送到b的数据段,现在z是可以看到的,显然攻击难度骤然下降了许多。否则z必须精确地预见可能从a发往b的信息,以及a期待来自b的什么应答信息,这要求攻击者对协议本身相当熟悉。同时需要明白,这种攻击根本不可能在交互状态下完成,必须写程序完成。当然在准备阶段可以用netxray之类的
工具进行协议分析。
7. 如果z不是路由器,能否考虑组合使用icmp重定向以及arp欺骗等技术?没有仔细分析过,只是随便猜测而已。并且与a、b、z之间具体的网络拓扑有密切关系,在某些情况下显然大幅度降低了攻击难度。注意ip欺骗攻击理论上是从广域网上发起的,不局限于局域网,这也正是这种攻击的魅力所在。利用ip欺骗攻击得到一个a上的shell,对于许多高级入侵者,得到目标主机的shell,离root权限就不远了,最容易想到的当然是接下来进行buffer overflow攻击。
8. 也许有人要问,为什么z不能直接把自己的ip设置成b的?这个问题很不好回答,要具体分析网络拓扑,当然也存在arp冲突、出不了网关等问题。那么在ip欺骗攻击过程中是否存在arp冲突问题。回想我前面贴过的arp欺骗攻击,如果b的arp cache没有受到影响,就不会出现arp冲突。如果z向a发送数据段时,企图解析a的mac地址或者路由器的mac地址,必然会发送arp请求包,但这个arp请求包中源ip以及源mac都是z的,自然不会引起arp冲突。而arp cache只会被arp包改变,不受ip包的影响,所以可以肯定地说,ip欺骗攻击过程中不存在arp冲突。相反,如果z修改了自己的ip,这种arp冲突就有可能出现,示具体情况而言。攻击中连带b一起攻击了,其目的无非是防止b干扰了攻击过程,如果b本身已经down掉,那是再好不过(是吗?)。
9. fakeip曾经沸沸扬扬了一下,我对之进行端口扫描,发现其tcp端口113是接收入连接的。和ip欺骗等没有直接联系,和安全校验是有关系的。当然,这个东西并不如其名所暗示,对ip层没有任何动作。
10. 关于预测isn,我想到另一个问题。就是如何以第三方身份切断a与b之间的tcp连接,实际上也是预测sequence number的问题。尝试过,也很困难。如果z是a与b之间的路由器,就不用说了;或者z动用了别的技术可以监听到a与b之间的通信,也容易些;否则预测太难。作者在3中提到连接a的25端口,可我想不明白的是513端口的isn和25端口有什么关系?看来需要看看tcp/ip内部实现的源代码。
未雨绸缪
虽然ip欺骗攻击有着相当难度,但我们应该清醒地意识到,这种攻击非常广泛,入侵往往由这里开始。预防这种攻击还是比较容易的,比如删除所有的/etc/hosts.equiv、$home/.rhosts文件,修改/etc/inetd.conf文件,使得rpc机制无法运做,还可以杀掉portmapper等等。设置路由器,过滤来自外部而信源地址却是内部ip的报文。cisio公司的产品就有这种功能。不过路由器只防得了外部入侵,内部入侵呢?
tcp的isn选择不是随机的,增加也不是随机的,这使攻击者有规可循,可以修改与isn相关的代码,选择好的算法,使得攻击者难以找到规律。估计linux下容易做到,那solaris、irix、hp-unix还有aix呢?sigh虽然作者纸上谈兵,但总算让我们了解了一下ip欺骗攻击,我实验过预测sequence number,不是isn,企图切断一个tcp连接,感觉难度很大。作者建议要找到规律,不要盲目预测,这需要时间和耐心。现在越发明白什么是那种锲而不舍永远追求的精神,我们所向往的传奇故事背后有着如此沉默的艰辛和毅力,但愿我们学会的是这个,而不是浮华与喧嚣。一个现成的bug足以让你取得root权限,可你在做什么,你是否明白?我们太肤浅了……