暈ip欺騙難道大呀,建議看看ip欺騙原理

解决方案 »

  1.   

    IP欺骗的技术比较复杂,不是简单地照猫画老虎就能掌握,但作为常规攻击手段,有必要理解其原理,至少有利于自己的安全防范,易守难攻嘛。 
      假设B上的客户运行rlogin与A上的rlogind通信: 
    1. B发送带有SYN标志的数据段通知A需要建立TCP连接。并将TCP报头中的sequence number设置成自己本次连接的初始值ISN。 
    2. A回传给B一个带有SYS+ACK标志的数据段,告之自己的ISN,并确认B发送来的第一个数据段,将acknowledge number设置成B的ISN+1。 
    3. B确认收到的A的数据段,将acknowledge number设置成A的ISN+1。 
    B ---- SYN ----> A 
    B <---- SYN+ACK ---- A 
    B ---- ACK ----> A 
      TCP使用的sequence number是一个32位的计数器,从0-4294967295。 TCP为每一个连接选择一个初始序号ISN,为了防止因为延迟、重传等扰乱三次握手,ISN不能随便选取,不同系统有不同算法。理解TCP如何分配ISN以及ISN随时间变化的规律,对于成功地进行IP欺骗攻击很重要。 
      基于远程过程调用RPC的命令,比如rlogin、rcp、rsh等等,根据/etc/hosts.equiv以及$HOME/.rhosts文件进行安全校验,其实质是仅仅根据信源IP地址进行用户身份确认,以便允许或拒绝用户RPC。 
      IP欺骗攻击的描述: 
    1. 假设Z企图攻击A,而A信任B,所谓信任指/etc/hosts.equiv和$HOME/.rhosts中有相关设置。注意,如何才能知道A信任B呢?没有什么确切的办法。我的建议就是平时注意搜集蛛丝马迹,厚积薄发。一次成功的攻击其实主要不是因为技术上的高明,而是因为信息搜集的广泛翔实。动用了自以为很有成就感的技术,却不比人家酒桌上的巧妙提问,攻击只以成功为终极目标,不在乎手段。 
    2. 假设Z已经知道了被信任的B,应该想办法使B的网络功能暂时瘫痪,以免对攻击造成干扰。著名的SYN flood常常是一次IP欺骗攻击的前奏。请看一个并发服务器的框架: 
    int initsockid, newsockid; 
    if ((initsockid = socket(...)) < 0) { 
    error("can create socket"); 

    if (bind(initsockid, ...) < 0) { 
    error("bind error"); 

    if (listen(initsockid, 5) < 0) { 
    error("listen error"); 

    for (;{ 
    newsockid = accept(initsockid, ...); /* 阻塞 */ 
    if (newsockid < 0) { 
    error("accept error"); 

    if (fork() == 0) { /* 子进程 */ 
    close(initsockid); 
    do(newsockid); /* 处理客户方请求 */ 
    exit(0); 

    close(newsockid); 

    listen函数中第二个参数是5,意思是在initsockid上允许的最大连接请求数目。如果某个时刻initsockid上的连接请求数目已经达到5,后续到达initsockid的连接请求将被TCP丢弃。注意一旦连接通过三次握手建立完成,accept调用已经处理这个连接,则TCP连接请求队列空出一个位置。所以这个5不是指initsockid上只能接受5个连接请求。SYN flood正是一种 Denial of Service,导致B的网络功能暂时中断 
    Z向B发送多个带有SYN标志的数据段请求连接,注意将信源IP 地址换成一个不存在的主机X;B向子虚乌有的X发送SYN+ACK数据段,但没有任何来自X的ACK出现。B的IP层会报告B的TCP层,X不可达,但B的TCP层对此不予理睬,认为只是暂时的。于是B在这个initsockid上再也不能接收正常的连接请求。 
    Z(X) ---- SYN ----> B 
    Z(X) ---- SYN ----> B 
    Z(X) ---- SYN ----> B 
    Z(X) ---- SYN ----> B 
    Z(X) ---- SYN ----> B 
    ...... 
    X <---- SYN+ACK ---- B 
    X <---- SYN+ACK ---- B 
    X <---- SYN+ACK ---- B 
    X <---- SYN+ACK ---- B 
    X <---- SYN+ACK ---- B 
    ...... 
    我认为这样就使得B网络功能暂时瘫痪,可我总觉得好象不对头。 
      因为B虽然在initsockid上无法接收TCP连接请求,但可以在another initsockid上接收,这种SYN flood应该只对特定的服务(端口),不应该影响到全局。当然如果不断地发送连接请求,就和用ping发洪水包一个道理,使得B的TCP/IP忙于处理负载增大。至于SYN flood,回头有机会我单独灌一瓢有关DoS的。如何使B的网络功能暂 碧被居 很多办法,根据具体情况而定,不再赘述。 
    3. Z必须确定A当前的ISN。首先连向25端口(SMTP是没有安全校验机制的),与1中类似,不过这次需要记录A的ISN,以及Z到A的大致的RTT(round trip time)。这个步骤要重复多次以便求出RTT的平均值。现在Z知道了A的ISN基值和增加规律(比如每秒增 加128000,每次连接增加64000),也知道了从Z到A需要RTT/2 的时间。必须立即进入攻击,否则在这之间有其他主机与A连接, ISN将比预料的多出64000。 
    4. Z向A发送带有SYN标志的数据段请求连接,只是信源IP改成了B,注意是针对TCP513端口(rlogin)。A向B回送SYN+ACK数据段,B已经无法响应,B的TCP层只是简单地丢弃A的回送数据段。 
    5. Z暂停一小会儿,让A有足够时间发送SYN+ACK,因为Z看不到这个包。然后Z再次伪装成B向A发送ACK,此时发送的数据段带有Z预测的A的ISN+1。如果预测准确,连接建立,数据传送开始。问题在于即使连接建立,A仍然会向B发送数据,而不是Z,Z 仍然无法看到A发往B的数据段,Z必须蒙着头按照rlogin协议标准假冒B向A发送类似 "cat + + >> ~/.rhosts" 这样的命令,于是攻击完成。如果预测不准确,A将发送一个带有RST标志的数据段异常终止连接,Z只有从头再来。 
    Z(B) ---- SYN ----> A 
    B <---- SYN+ACK ---- A 
    Z(B) ---- ACK ----> A 
    Z(B) ---- PSH ----> A 
    ...... 
    6. IP欺骗攻击利用了RPC服务器仅仅依赖于信源IP地址进行安全校验的特性,建议阅读rlogind的源代码。攻击最困难的地方在于预测A的ISN。我认为攻击难度虽然大,但成功的可能性也很大,不是很理解,似乎有点矛盾。考虑这种情况,入侵者控制了一台由A到B之间的路由器,假设Z就是这台路由器,那么A回送到B的数据段,现在Z是可以看到的,显然攻击难度骤然下降了许多。否则Z必须精确地预见可能从A发往B的信息,以及A期待来自B的什么应答信息,这要求攻击者对协议本身相当熟悉。同时需要明白,这种攻击根本不可能在交互状态下完成,必须写程序完成。当然在准备阶段可以用netxray之类的工具进行协议分析。 
    7. 如果Z不是路由器,能否考虑组合使用ICMP重定向以及ARP欺骗等技术?没有仔细分析过,只是随便猜测而已。并且与A、B、 
    Z之间具体的网络拓扑有密切关系,在某些情况下显然大幅度降低了攻击难度。注意IP欺骗攻击理论上是从广域网上发起的,不局限于局域网,这也正是这种攻击的魅力所在。利用IP欺骗攻击得到一个A上的shell,对于许多高级入侵者,得到目标主机的shell,离root权限就不远了,最容易想到的当然是接下来进行buffer overflow攻击。 
    8. 也许有人要问,为什么Z不能直接把自己的IP设置成B的?这个问题很不好回答,要具体分析网络拓扑,当然也存在ARP冲突、出不了网关等问题。那么在IP欺骗攻击过程中是否存在ARP冲突问题。回想我前面贴过的ARP欺骗攻击,如果B的ARP Cache没有受到影响,就不会出现ARP冲突。如果Z向A发送数据段时,企图解析A的MAC地址或者路由器的MAC地址,必然会发送ARP请求包,但这个ARP请求包中源IP以及源MAC都是Z的,自然不会引起ARP冲突。而ARP Cache只会被ARP包改变,不受IP包的影响,所以可以肯定地说,IP欺骗攻击过程中不存在ARP冲突。相反,如果Z修改了自己的IP,这种ARP冲突就有可能出现,示具体情况而言。攻击中连带B一起攻击了,其目的无非是防止B干扰了攻击过程, 如果B本身已经down掉,那是再好不过。 
    9. fakeip曾经沸沸扬扬了一下,我对之进行端口扫描,发现其tcp端口113是接收入连接的。和IP欺骗等没有直接联系,和安全校验是有关系的。当然,这个东西并不如其名所暗示,对IP层没有任何动作。 
    10. 关于预测ISN,我想到另一个问题。就是如何以第三方身份切断 A与B之间的TCP连接,实际上也是预测sequence number的问题。尝试过,也很困难。如果Z是A与B之间的路由器,就不用说了; 或者Z动用了别的技术可以监听到A与B之间的通信,也容易些; 否则预测太难。作者在3中提到连接A的25端口,可我想不明白的 是513端口的ISN和25端口有什么关系?看来需要看看TCP/IP内部实现的源代码。 
    未雨绸缪 
    虽然IP欺骗攻击有着相当难度,但我们应该清醒地意识到,这种攻击非常广泛,入侵往往由这里开始。预防这种攻击还是比较容易的, 比如删除所有的/etc/hosts.equiv、$HOME/.rhosts文件,修改/etc/ inetd.conf文件,使得RPC机制无法运做,还可以杀掉portmapper等等。设置路由器,过滤来自外部而信源地址却是内部IP的报文。cisio公司的产品就有这种功能。不过路由器只防得了外部入侵,内部入侵呢? 
    TCP的ISN选择不是随机的,增加也不是随机的,这使攻击者有规可循,可以修改与ISN相关的代码,选择好的算法,使得攻击者难以找到规律。估计Linux下容易做到,那solaris、irix、hp-unix还有aix呢?sigh 
    虽然写的不怎么,但总算让大家了解了一下IP欺骗攻击,我实验过预测sequence number,不是ISN,企图切断一个TCP连接,感觉难度很大。作者建议要找到规律,不要盲目预测,这需要时间和耐心。现在越发明白什么是那种锲而不舍永远追求的精神,我们所向往的传奇故事背后有着如此沉默的艰辛和毅力,但愿我们学会的是这个,而不是浮华与喧嚣。一个现成的bug足以让你取得root权限,可你在做什么,你是否明白?我们太肤浅了...... 
      

  2.   

    给你一些提示吧:传说大多IP欺骗工具都是更改注册表的IP和MAC的,而网络收发数据都是通过它来发的.因此只要更改这个地址即可达到欺骗的效果..
      

  3.   

    aderly(俺一直在努力@_@) 的方法理论上是可行,可实际上行不通,碰上的几率微乎其微目前所有的IP隐藏是通过使用超级代理来实现的,你要实现自动IP隐藏,就要先实现两个:1、超代的自动搜索;2、代理的自动使用
    显示IP是指显示本机IP么?这个代码到处有的
      

  4.   

    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;
    interfaceuses
    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;typeTPacketBuffer = Array[0..Max_Packet-1] of byte;
      

  5.   

    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 IncludeSOCK_RAW = 3; // raw-protocol interfaceIPPROTO_IP = 0; // dummy for IP
    IPPROTO_TCP = 6; // tcp
    IPPROTO_UDP = 17; // user datagram protocol
    IPPROTO_RAW = 255; // raw IP packetINVALID_SOCKET = TSocket(NOT(0));
    SOCKET_ERROR = -1;var
    Form1: TForm1;implementation// Import Winsock 2 functions
    const WinSocket = 'WS2_32.DLL';
      

  6.   

    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)[i];
    inc(i);
    Size := Size - SizeOf(Word);
    end;if Size=1 then ChkSum := ChkSum + Byte(TWordArray(Buffer)[i]);ChkSum := (ChkSum shr 16) + (ChkSum and $FFFF);
    ChkSum := ChkSum + (Chksum shr 16);Result := Word( not ChkSum);
    end; 
    procedure BuildHeaders(
    FromIP : String;
    iFromPort : Word;
    ToIP : String;
    iToPort : Word;
    StrMessage : String;
    Var Buf : TPacketBuffer;
    Var remote : TSockAddr;
    Var iTotalSize : Word
    );
    Var
    dwFromIP : LongWord;
    dwToIP : LongWord;iIPVersion : Word;
    iIPSize : Word;
    ipHdr : T_IP_Header;
    udpHdr : T_UDP_Header;iUdpSize : Word;
    iUdpChecksumSize : Word;
    cksum : Word;Ptr : ^Byte;procedure IncPtr(Value : Integer);
    begin
    ptr := pointer(integer(ptr) + Value);
    end;begin
    // Convert ip address'ssdwFromIP := inet_Addr(PChar(FromIP));
    dwToIP := inet_Addr(PChar(ToIP));// 初始化 IP 头
    //
    iTotalSize := sizeof(ipHdr) + sizeof(udpHdr) + length(strMessage);iIPVersion := 4;
    iIPSize := sizeof(ipHdr) div sizeof(LongWord);ipHdr.ip_verlen := (iIPVersion shl 4) or iIPSize;
    ipHdr.ip_tos := 0; // IP type of service
    ipHdr.ip_totallength := htons(iTotalSize); // Total packet len
    ipHdr.ip_id := 0; // Unique identifier: set to 0
    ipHdr.ip_offset := 0; // Fragment offset field
    ipHdr.ip_ttl := 128; // Time to live
    ipHdr.ip_protocol := $11; // Protocol(UDP)
    ipHdr.ip_checksum := 0 ; // IP checksum
    ipHdr.ip_srcaddr := dwFromIP; // Source address
    ipHdr.ip_destaddr := dwToIP; // Destination address
      

  7.   

    http://www.codesky.net/article/list.asp?id=1275
      

  8.   

    DELPHI?
    不会,VC倒是可以提供开发成动态库的代码!