熟悉SOCKET的朋友都知道,在WIN 95/98下对原始套接字来说,我们只能对 定义好的协议进行操作,不能对如象UDP,TCP头进行操作。因为系统限制他门不支持IP_HDRINCL选项。如果要达到此目的则必须写DRIVE来实现。相对来说UNIX系统下就方便很多。直到现在的WIN2000出台才允许此机制,这样我们就可以制构造自己的IP头。这意味着什么?精通网络编程的朋友非常清楚。只要你喜欢你可以把IP伪装成被攻击着的IP。象什么防火墙之类想追踪IP来源?几乎是不可能,据我了解现有防火墙还没有针对此机制给出相应措施。
下面以UDP协议为列说下原理及实现方法:
SOCKET sock; BOOL bop;
sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_UDP,NULL,0,WSA_FLAG_OVERLAPPED); setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(TCHAR)&bop),sizeof(bop));
这样我们就已创建好了一个原始套接字,并设置了IP_HDRINCL标志。
设置好后每次发送调用都需要向IP头内自行填充内容,同时还要填写封状在 其中的其他协议头,这样才能达到我们的目的。为了让大家清楚了解以下 给出IP头结构描述。
typedef struct ip_hdr { unsigned char ip_verlen; // IP头长度 unsigned char ip_tos; // IP服务类型 unsigned short ip_totallength; // 数据包长度 unsigned short ip_id; // 标识段 unsigned short ip_offset; // 标志段 unsigned char ip_ttl; // 包生存时间 unsigned char ip_protocol; // 协议类型 unsigned short ip_checksum; // IP头校验和 unsigned int ip_srcaddr; // 源地址 unsigned int ip_destaddr; // 目标地址 } IP_HDR, *PIP_HDR, FAR* LPIP_HDR;
与IP头相比UDP头要简单多,长度仅为8个字节,且只包含了4个16位的字段 源端口,目标端口,UDP长度,UDP校验和,下面给出UDP头的结构描述
typedef struct udp_hdr { unsigned short src_portno; // 源端口好 unsigned short dst_portno; // 目标端口好 unsigned short udp_length; // UDP包长度 unsigned short udp_checksum; // UDP校验和 } UDP_HDR, *PUDP_HDR
清楚了以上这些下面就可以认由你发挥,如ip_protocol=0x11;它对应与UDP。 ip_srcaddr这里就任凭你来填写想让接受者认为的任何地址。
|