【内容摘要】一、前言本文主要介绍如何在程序中实现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