【内容摘要】一、前言本文主要介绍如何在程序中实现ip地址的隐藏。其实这篇东西不算我写的。其中《ip头结构》部分我懒得打字,故复制、粘贴了孤独剑客的文章,先说声谢谢!代码部分参考了外国程序xes写的一个程序。所以这只是学习过程中的一个副产品。既然程序已经做好了,就顺便放上来跟大家一起交流,共同提高吧。本文只不过想说明一下ip数据的结构和发送机制。如果有人把它改为恶意ip…… -----------------------------------------------------------------------------
一、前言 本文主要介绍如何在程序中实现ip地址的隐藏。其实这篇东西不算我写的。其中《ip头结构》部分我懒得打字,故复制、粘贴了孤独剑客的文章,先说声谢谢!代码部分参考了外国程序xes写的一个程序。所以这只是学习过程中的一个副产品。既然程序已经做好了,就顺便放上来跟大家一起交流,共同提高吧。本文只不过想说明一下ip数据的结构和发送机制。如果有人把它改为恶意ip攻击工具,后果自负。 二、ip头结构 我们知道,tcp/ip网络数据全部是通过封装在ip数据包中在internet网上传送的,也就是封装建立起一个包含ip头和数据的ip数据报。一般来说,网络软件总是以多个32位字产生ip头,即使必须用附加的0填充ip头。ip头包含了传输ip数据包中封装数据的所有必要信息。ip头的数据结构和描述如下: 成员 长度(bit) 描述 version 4 ip头的版本号,目前是ipv4,最新是ipv6 header length 4 ip头的长度,若没有特殊选择,ip头总是20字节长 type of service 8 服务类型,定义了数据传输的优先级、延迟、吞吐量和可靠性等特性 total packet length 16 ip包的长度,若没有特殊选项,一般为20字节长 identification 16 ip包标识,主机使用它唯一确定每个发送的数据报 flag 3 ip数据分割标志 fragment offset 13 ip数据分割偏移 time to live 8 数据报在网络上的存活时间,每通过一个路由器,该数值减一 protocol 8 tcp/ip协议类型,比如:icmp为1,igmp为2,tcp为6,udp为17等 header checksum 16 头部检验和 source ip address 32 源ip地址 destination ip address 32 目的ip地址 other ? 其他选项 data ? 数据 实现自己定义的ip头是一件非常有意义的事情,比如,通过改变ip头里的tos的优先级和ttl,你可以使自己的数据包有更强的传输能力和寿命,通过修改ip头里的源ip地址就可以隐藏自己机器的ip地址等等。象著名攻击程序“泪滴teardrop”就是通过故意制造系统不能处理的分片ip包而实现的,还有syn flooder和udp flooder就是通过产生随机源ip实现欺骗的。 三、实现原理 一般来说,自定义ip头是通过使用socket的库函数setsockopt()的选项ip_hdrincl来实现的,尽管这在unix和linux平台上很容易实现,但遗憾的是在windows平台的winsock1.1和winsock2.0函数库里setsockopt()不支持ip_hdrincl选项,所以在windows 9x/nt里是无法通过winsock函数库来实现ip头自定义的,当然可以通过编写虚拟设备驱动程序来实现,不过比较复杂,但windows 2000的出现打破了这种局面,windows2000的winsock2.2函数库里全面支持setsockopt()的选项ip_hdrincl,使得我们轻松就可以实现自定义的ip头。实现方法如下: 四、代码部分 { 1. 本程序只能运行于 window 2000. 2. 你必须有 administrator 权限. 3. 程序需要用到一个 button 和一个 memo. ---------------------------------------------------------------------- 运行程序前,请根据自己的需要改变 srcip、srcport、destip和destport的值 ---------------------------------------------------------------------- 如果你看不懂以下代码,最好不要去运行它。 ---------------------------------------------------------------------- } unit unit1; interface uses windows, messages, sysutils, classes, graphics, controls, forms, dialogs, stdctrls, olectrls, registry; const srcip = '123.123.123.1';//发送方ip地址 srcport = 1234; //发送方端口 destip = '127.0.0.2'; //目的ip地址 destport = 4321; //目的端口 max_message = 4068; max_packet = 4096; type tpacketbuffer = array[0..max_packet-1] of byte; tform1 = class(tform) button1: tbutton; memo1: tmemo; procedure button1click(sender: tobject); private { private declarations } public { public declarations } procedure sendit; end; // ip 头 type t_ip_header = record ip_verlen : byte; ip_tos : byte; ip_totallength : word; ip_id : word; ip_offset : word; ip_ttl : byte; ip_protocol : byte; ip_checksum : word; ip_srcaddr : longword; ip_destaddr : longword; end; // udp 头 type t_udp_header = record src_portno : word; dst_portno : word; udp_length : word; udp_checksum : word; end; // 一些 winsock 2 的类型声明 u_char = char; u_short = word; u_int = integer; u_long = longint; sunb = packed record s_b1, s_b2, s_b3, s_b4: u_char; end; sunw = packed record s_w1, s_w2: u_short; end; in_addr = record case integer of 0: (s_un_b: sunb); 1: (s_un_w: sunw); 2: (s_addr: u_long); end; tinaddr = in_addr; sockaddr_in = record case integer of 0: (sin_family: u_short; sin_port: u_short; sin_addr: tinaddr; sin_zero: array[0..7] of char); 1: (sa_family: u_short; sa_data: array[0..13] of char) end; tsockaddr = sockaddr_in; tsocket = u_int; const wsadescription_len = 256; wsasys_status_len = 128; type pwsadata = ^twsadata; wsadata = record // wsdata wversion: word; whighversion: word; szdescription: array[0..wsadescription_len] of char; szsystemstatus: array[0..wsasys_status_len] of char; imaxsockets: word; imaxudpdg: word; lpvendorinfo: pchar; end; twsadata = wsadata; //定义一些 winsock 2 函数 function closesocket(s: tsocket): integer; stdcall; function socket(af, struct, protocol: integer): tsocket; stdcall; function sendto(s: tsocket; var buf; len, flags: integer; var addrto: tsockaddr; tolen: integer): integer; stdcall;{} function setsockopt(s: tsocket; level, optname: integer; optval: pchar; optlen: integer): integer; stdcall; function inet_addr(cp: pchar): u_long; stdcall; {pinaddr;} { tinaddr } function htons(hostshort: u_short): u_short; stdcall; function wsagetlasterror: integer; stdcall; function wsastartup(wversionrequired: word; var wsdata: twsadata): integer; stdcall; function wsacleanup: integer; stdcall; const af_inet = 2; // internetwork: udp, tcp, etc. ip_hdrincl = 2; // ip header include sock_raw = 3; // raw-protocol interface ipproto_ip = 0; // dummy for ip ipproto_tcp = 6; // tcp ipproto_udp = 17; // user datagram protocol ipproto_raw = 255; // raw ip packet invalid_socket = tsocket(not(0)); socket_error = -1; var form1: tform1; implementation // import winsock 2 functions const winsocket = 'ws2_32.dll'; function closesocket; external winsocket name 'closesocket'; function socket; external winsocket name 'socket'; function sendto; external winsocket name 'sendto'; function setsockopt; external winsocket name 'setsockopt'; function inet_addr; external winsocket name 'inet_addr'; function htons; external winsocket name 'htons'; function wsagetlasterror; external winsocket name 'wsagetlasterror'; function wsastartup; external winsocket name 'wsastartup'; function wsacleanup; external winsocket name 'wsacleanup'; {$r *.dfm} function checksum(var buffer; size : integer) : word; type twordarray = array[0..1] of word; var chksum : longword; i : integer; begin chksum := 0; i := 0; while size > 1 do begin chksum := chksum + twordarray(buffer); inc(i); size := size - sizeof(word); end; if size=1 then chksum := chksum + byte(twordarray(buffer)); c 本贴来自天极网群乐社区--http://q.yesky.com/group/review-17620469.html