• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • sniffer技術原理及應用,包括編程方法和工具使用

    發表于:2007-05-26來源:作者:點擊數: 標簽:
    kingzai: sniffer中文翻譯過來就是嗅探器,在當前網絡技術中使用得非常得廣泛。sniffer既可以做為網絡故 障的診斷工具,也可以作為黑客嗅探和監聽的工具。最近兩年,網絡監聽(sniffer)技術出現了新的 重要特征。傳統的sniffer技術是被動地監聽網絡通信、用戶
    kingzai:
    sniffer中文翻譯過來就是嗅探器,在當前網絡技術中使用得非常得廣泛。sniffer既可以做為網絡故
    障的診斷工具,也可以作為黑客嗅探和監聽的工具。最近兩年,網絡監聽(sniffer)技術出現了新的
    重要特征。傳統的sniffer技術是被動地監聽網絡通信、用戶名和口令。而新的sniffer技術出現了主
    動地控制通信數據的特點,把sniffer技術擴展到了一個新的領域。Sniffer 技術除了目前在傳統的
    網絡偵測管理外,也開始被應用在資訊保全的領域??梢赃@樣說,sniffer技術是一把雙刃劍,如何
    更好的利用它,了解它的一些特性,將能使這項技術更好的為我們帶來便利。
    sniffer的編程方法比較通用的有以下幾種,1.winpcap 這是一個比較通用的庫,相信做過抓包的
    工具大多數人都不會太陌生 2.raw socket 在2000以后的版本都支持此項功能,2000 server有個網絡監視器就是基于raw socket 3.tdi,ndis,spi,hook socket技術,這種技術比較大的不同是可以將包截取而不是僅僅獲得包的一份拷貝??偟恼f來,一般以前兩者居多。
    我這里提的都還比較片面,更多的需要大家來補充。我辦這個專題的目的是希望大家共同來了解,討論sniffer技術,讓更多的人參與進來,讓大家知道,這個板塊能夠給大家帶來真正想要的東西。
    warton:
    libpcap是個好東西,linux,windows下都能用,很多入侵檢測之類的安全系統都是以這為核心。不
    過我一直沒用過它,不知道它的跨平臺性如何?
    要用spi的話,看看xfilter的代碼和書,特別是那本書上講得不錯,可惜一直沒用它做出什么東西來。
    raw socket寫的sniffer比較多,網上代碼也很多!
    昨天見csdn首頁有幾篇關于sniffer的文章,保存了,還沒來得及看...
    俺明天來說說目前常用的sniffer類工具和它們的技術實現!

    csdn首頁的兩篇文章,大家可以看看,里面好像還有幾篇,暫時找不到了
    http://www.csdn.net/develop/article/21/21363.shtm
    http://www.csdn.net/develop/article/21/21352.shtm
    http://www.csdn.net/develop/article/15/15919.shtm

    netsys2:

    一)winpcap驅動簡介
      winpcap(windows packet capture)是windows平臺下一個免費,公共的網絡訪問系統。開

    發winpcap這個項目的目的在于為win32應用程序提供訪問網絡底層的能力。它提供了以下的各項

    功能:
      1> 捕獲原始數據報,包括在共享網絡上各主機發送/接收的以及相互之間交換的數據報;
      2> 在數據報發往應用程序之前,按照自定義的規則將某些特殊的數據報過濾掉;
      3> 在網絡上發送原始的數據報;
      4> 收集網絡通信過程中的統計信息。

     

    winpcap的主要功能在于獨立于主機協議(如TCP-IP)而發送和接收原始數據報。也就是說,winp

    cap不能阻塞,過濾或控制其他應用程序數據報的發收,它僅僅只是監聽共享網絡上傳送的數據報。因此,它不能用于QoS調度程序或個人防火墻。

      目前,winpcap開發的主要對象是windows NT/2000/XP,這主要是因為在使用winpcap的

    用戶中只有一小部分是僅使用windows 95/98/Me,并且M$也已經放棄了對win9x的開發。因

    此本文相關的程序T-ARP也是面向NT/2000/XP用戶的。其實winpcap中的面向9x系統的概念和

    NT系統的非常相似,只是在某些實現上有點差異,比如說9x只支持ANSI編碼,而NT系統則提倡使

    用Unicode編碼。

    zzhong2:
    有個軟件叫sniffer pro.可以作網管軟件用,有很多功能,可監視網絡運行情況,每臺網內機器的數據

    流量,實時反映每臺機器所訪問IP以及它們之間的數據流通情況,可以抓包,可對過濾器進行設置,以便

    只抓取想要的包,比如POP3包,smtp包,ftp包等,并可從中找到郵箱用戶名和密碼,還有ftp用戶名和

    密碼.它還可以在使用交換機的網絡上監聽,不過要在交換機上裝它的一個軟件.
    還有一個簡單的監聽軟件叫 Passwordsniffer,可截獲郵箱用戶名和密碼,還有ftp用戶名和密碼,它

    只能用在用HUB網絡上
    以上兩個軟件都可在小鳳居上下載到:
    http://www.chinesehack.org/


    warton:
    libpcap的最新版本是0.7.2,下載很多(基于linux/unix
    winpcap的最新版本是3.0
    這里有winpcap的源代碼:
    http://download.pchome.net/php/dl.php?sid=11474
    著名軟件tcpdump及ids snort都是基于libpcap編寫的,此外Nmap掃描器也是基于libpcap來捕

    獲目標主機返回的數據包的。
    winpcap提供給用戶兩個不同級別的編程接口:一個基于libpcap的wpcap.dl,另一個是較底層的

    packet.dll。對于一般的要與unix平臺上libpcap兼容的開發來說,使用pacap.dll是當然的選擇。
    下面幾個庫是與lipcap相關的:
    libnet1.0.2:數據包的發送個構造過程
    libnids:實現了ids的一些 框架
    libicmp:icmp數據包處理




    一些著名的嗅探器:
    tcpdump/windump:支持多種unix,后者支持windows?;趌ibpcap
    Sniffit:unix,windows,libpcap
    Ngrep:libpcap,unixwindows.可以用規則表達式,識別PPP,SLIP及FDDI數據包
    Sniffer pro/NetXray:專業的協議分析工具,是NAI提供的網絡分析方案中的一部分
    其它:
    Iris
    LanExplorer
    NetMOnitor
    CommView

    單一用途的噢探器
    口令嗅:winsniffer,典型的黑客工具,嗅探并解析ftp,pop3,http,icq,smtp,telnet,IMAP,NNTP

    等口令
    password sniffer for NetHackerIII

    專用 嗅探器:
    SMB嗅探器:L0phtcrack,SMPRelay
    TCP連接會話嗅探器:CommView ,Iris,Juggernaut
    SSL嗅探器:SSLDump--sslv3/tls網絡協議分析工具
    RIDIUS嗅控器:一個基于udp的論證記賬協議,Radiusniff是其代表
    PPTP嗅 控器:Anger,PPTP-sniff(solaris)
    SNMP嗅探器:Snmpsniff

    交換網絡嗅探器:Ettercap
    綜合:Dsniff
    其它交換網絡嗅探器:
    snarp,parasite

    嗅探對策.........

    netsys2:

    網絡上流傳的GUNIFFER是個基本的原型:

    http://asp.6to23.com/nowcan/code/guniffer.zip

    void main(int argc, char ** argv)

    {

    int iErrorCode;

    char RecvBuf[MAX_PACK_LEN] = {0};

    usage();

    if(GetCmdLine(argc, argv)==CMD_PARAM_HELP) exit(0);

    //初始化SOCKET

    WSADATA wsaData;

    iErrorCode = WSAStartup(MAKEWORD(2,1),&wsaData);

    CheckSockError(iErrorCode, "WSAStartup");

    SockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP);

    CheckSockError(SockRaw, "socket");

    //獲取本機IP地址

    char FAR name[MAX_HOSTNAME_LAN];

    iErrorCode = gethostname(name, MAX_HOSTNAME_LAN);

    CheckSockError(iErrorCode, "gethostname");

    struct hostent FAR * pHostent; //注意下面這三句,這里先對pHostent分配了一塊

    pHostent = (struct hostent * )malloc(sizeof(struct hostent));

    //內存,然后有讓它等于gethostbyname函數的返回

    pHostent = gethostbyname(name); //值,但gethostbyname函數是自己在函數內部分配內

    存的,因此上一句根本就是多余,把上一句刪除后一切正常。但此程序用VC6編譯運行都沒有問題

    ,不知為何?也許是VC6的編譯器優化在起作用。

    SOCKADDR_IN sa;

    sa.sin_family = AF_INET;

    sa.sin_port = htons(6000);

    memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length);

    free(pHostent); //由于前面分配內存的語句已經刪除,所以這一句也要去掉,否則出錯。感謝網

    友 Heyuming 發現這個問題。

    iErrorCode = bind(SockRaw, (PSOCKADDR)&sa, sizeof(sa));

    CheckSockError(iErrorCode, "bind");

    //設置SOCK_RAW為SIO_RCVALL,以便接收所有的IP包

    DWORD dwBufferLen[10] ;

    DWORD dwBufferInLen = 1 ;

    DWORD dwBytesReturned = 0 ;

    iErrorCode=WSAIoctl(SockRaw, SIO_RCVALL,&dwBufferInLen,

    sizeof(dwBufferInLen),

    &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );

    CheckSockError(iErrorCode, "Ioctl");

    //偵聽IP報文

    while(1)

    {

    memset(RecvBuf, 0, sizeof(RecvBuf));

    iErrorCode = recv(SockRaw, RecvBuf, sizeof(RecvBuf), 0);

    CheckSockError(iErrorCode, "recv");

    iErrorCode = DecodeIpPack(RecvBuf, iErrorCode);

    CheckSockError(iErrorCode, "Decode");

    }

    }

    它有2個不方便之處:
    1)不能選擇網卡
    2)采用死循環方式讀數據,改編到WINDOWS窗口模式下時有死機的感覺。

    sevencat():
    上次找了一些資料整理了一下,不過人氣不旺,而且最近比較忙,暫時還沒繼續下去。
    http://expert.csdn.net/Expert/topic/2299/2299615.xml?temp=.2761499
    WINDOWS網絡包過濾技術
                        (原文:
    http://www.ndis.com/papers/winpktfilter.htm
    一、user-mode網絡包過濾
    1、winsock分層service provider
    參照Microsoft Platform SDK上有關文檔和例子
    http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
    這里有好幾個microsoft lsp 例子,最新(可能最bug-free)的經常在這里能找到。需要知道的是

    可以通過TDI調用核心TCPIP驅動,而且可以完全繞開WINSOCK,在大多數情況下這不是一個問

    題。例如:QOS的實現可以在WINSOCK LSP上。
    然而,這樣做的話,程序必須察看和操作每個包,而不能依靠WINSOCK LSP,他們要以一種接

    近核心態的方法來實現。
    2、win2000包過濾接口
      WIN2000包過濾接口提供了一種機制,這種機制允許用戶態程序或者服務指定一系列的"過濾

    原則",這些過濾原則會被低層的TCPIP實現用來過濾包。這種過濾工主要是對IP原地址、目標地址、端口號(或者端口號范圍)進行pass或者drop操作。
    Windows Developer's Journal
    《用iphlpapi.dll進行包過濾》作者:Ton plooy,October,2000,Volume 11, Number 10。
      WIN2000提供了一個較好對TCPIP的可編程控制,其中包括包過濾。不幸的是,有關這個新

    的API的文檔并不是很容易能找到。這篇文章向你演示了怎樣對特定IP地址或者特定TCP端口的包

    進行阻塞的編程。
    鏈接:
    www.wdj.com
    上面這個例子的下載:ftp://ftp.wdj.com/pub/webzip/1110/plooy.zip
    Hollis 的解決方案
      HTS W2K IpHook例子演示了IP過濾和它的HOOK API,包含原文件,而且是免費的,

    需要HtsCpp運行時庫(免費),下載地址:
    http://www.hollistech.com/
    3、winsock替代DLL
      在使用WINSOCK LSP之前,唯一的辦法是用自己的DLL取代微軟的WINSOCK DLL,假

    如實現順利的話,自己的DLL會接收用戶的WINSOCK調用請求,然后還可以調用原來的WINSOC

    K DLL來處理。
      不過這樣的實現是比較費力的,其中有個困難就是微軟的WINSOCK DLL里面經常有一些未

    公開的內部使用的函數,一個WINSOCK代替DLL至少要處理其中的一些未公開函數。
      隨著WINDOWS系統結構的變化,有些方面得到了加強,比如系統文件保護,這使得這種技術

    變得不太可行??偟恼f來,使用WINSOCK DLL替換不是一個壞主意。(Xfilter就是用的這種技

    術,原代碼可能在網上有流傳,我以前看到過的)
    二、kernel-mode網絡包過濾
    1、Transport Data Interface (TDI)
      這主要是一個直接在核心TCPIP驅動上面的一層過濾驅動。在WINXP上TDI驅動是一種傳統的

    NT風格的驅動,使用了基于IRP的API,這里有兩種方法來實現。
    A、使用核心模式服務的IoAttachDeviceXYZ函數族在TDI上實現一個過濾。
    B、對TDI驅動IRP DISPATCH表進行過濾。
      IoAttachDeviceXYZ函數在許多WINNT驅動開發的書上提到。這兩種技術都需要對WINNT驅

    動開發編程技術十分了解,對TDI函數也要相當的了解。
    2、NDIS中間層(IM)
    具體請看NDIS IM FAQ:
    http://www.pcausa.com/resources/ndisimfaq.htm
    3、WIN2000 FILTER-HOOK
      請參照有關DDK文檔,系統中只能有一個活動的Filter-Hook存在,這點使這種技術的使用有

    嚴重的限制。(平時所見的drvipflt就是用的這個)
    4、WIN2000 FIREWALL-HOOK 
      Firewall-Hook Driver函數在文檔里介紹得很少,而且在有些win2000版本中不可用。請參

    照微軟有關文檔:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us

    /network/hh/network/firewall_3wfb.asp
    5、NDIS-HOOKING  (費爾防火墻就是用的這種技術吧,據我所知,雖然我沒看過原碼。)
    NDIS-Hooking驅動攔截或者叫"HOOK"一些由NDIS封裝程序導出的函數。雖然從實現手段上來

    說有些不正規,但一個有系統的NDIS-Hooking過濾會非常有效。
    另外:NDIS-Hooking過濾驅動有下面的好處:
    A、容易安裝(可以動態裝卸,不過有時候會出問題,里面有些情況現在還未知。)
    B、支持撥號-ppp適配器。
      Ndis-Hooking技術在98和ME系統下非常有效和實用。在這些平臺上,DDK文檔和provide

    d services都能很有用的幫你HOOK由Ndis wrapper導出的函數。
      Ndis-Hooking技術在NT,2000和XP上同樣有效和實用。這種技術很像核心模式的調試器。

    文檔支持較少,而且基本上不會被WHQL認證。
    PCAUSA提供了一套NDIS PIM驅動例子,這些例子能在現有的WIN平臺上運行成功(從95到X

    P)。地址:
    http://www.pcausa.com/ndispim/Default.htm

    其他:
    Network操作和進程信息:
      有許多人想知道網絡上的操作和WIN進程(就是應用程序啦)之間怎樣聯系起來,舉例來說,

    可能會想知道是哪個進程在一個特定的IP端口上發送或接收數據。
      先不考慮這種技術是否有用,或者是否可靠,我們認為核心模式TCPIP驅動上層的過濾程序可

    以處理這個問題。而TCPIP驅動下層的過濾程序根本看不到進程信息。特別要注意的是有些網絡服

    務操作生成一個新的進程attach到系統進程上的。在這種情況下進程信息并不能告訴我們原先是哪

    個進程生成的。特別是單獨在核心模式下的WIN服務(TDI客戶)
      最后,有必要看看下面的資料United States Patent 5,987,611; "System and

    methodology for managing internet aclearcase/" target="_blank" >ccess on a per application basis for client

    computers connected to the internet "
      我們并不知道這項專利的價值,也不知道他是否能用在包過濾上。詳情請參閱:
    http://www.

    uspto.gov/patft/index.html
    www.pcausa.com

    ============================================
    drvipflt具體解析,就是上面所提到的吧(2-3就是說的這東東)。
    假定大家對驅動框架已經有了一定的理解。IRP分配程序如下:
    NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    {
    ...
      switch (irpStack->MajorFunction)
      {
    ...
      case IRP_MJ_DEVICE_CONTROL:
        ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

        switch (ioControlCode)
        {
      // ioctl code to start filtering
      //這里可以從用戶模式程序發送這樣的請求。
      //直接用DeviceIoControl這個函數,就像下面這樣調用就可

    以了吧,我想。
     

    //DeviceIoControl(drivehandle,START_IP_HOOK,NULL,0,NULL,0,&bytereturned,NU

    LL)
      case START_IP_HOOK:
      {
      //這個應該是最主要的函數了。
            SetFilterFunction(cbFilterFunction);

      break;
      }

      // ioctl to stop filtering
      case STOP_IP_HOOK:
      {
      SetFilterFunction(NULL);
           
      break;
      }

            // ioctl to add a filter rule
      case ADD_FILTER:
      {
      if(inputBufferLength == sizeof(IPFilter))
      {
      IPFilter *nf;

      nf = (IPFilter *)ioBuffer;
     
      AddFilterToList(nf);
      }

      break;
      }

      // ioctl to free filter rule list
      case CLEAR_FILTER:
      {
      ClearFilterList();

      break;
      }

      default:
      Irp->IoStatus.Status =

    STATUS_INVALID_PARAMETER;


      break;
        }

        break;
    ...
    }
    SetFilterFunction(cbFilterFunction)可能是最重要的一個程序了。具體如下:
    實際上這個做法相當在系統中注冊了一個回調函數。
    NTSTATUS SetFilterFunction(PacketFilterExtensionPtr filterFunction)
    {
    NTSTATUS status = STATUS_SUCCESS, waitStatus=STATUS_SUCCESS;
    UNICODE_STRING filterName;
    PDEVICE_OBJECT ipDeviceObject=NULL;
    PFILE_OBJECT ipFileObject=NULL;

    PF_SET_EXTENSION_HOOK_INFO filterData;

    KEVENT event;
    IO_STATUS_BLOCK ioStatus;
    PIRP irp;

    //首先獲得一個設備指針。
    //first of all, we have to get a pointer to IpFilterDriver Device
    RtlInitUnicodeString(&filterName, DD_IPFLTRDRVR_DEVICE_NAME);
    status = IoGetDeviceObjectPointer(&filterName,STANDARD_RIGHTS_ALL,

    &ipFileObject, &ipDeviceObject);
    if(NT_SUCCESS(status))
    {
    //一些初始化工作,填充filterData。
    //initialize the struct with functions parameters
    filterData.ExtensionPointer = filterFunction;

    //we need initialize the event used later by the IpFilterDriver to

    signal us
    //when it finished its work
    KeInitializeEvent(&event, NotificationEvent, FALSE);

    //這個就是最重要的注冊回調函數過程。DDK中具體講述是這樣的
    //IOCTL_PF_SET_EXTENSION_POINTER registers filter-hook callback functions to

    the IP filter driver
    //to inform the IP filter driver to call those filter hook callbacks for every IP packet
    //that is received or transmitted. Also, IOCTL_PF_SET_EXTENSION_POINTER

    clears filter-hook
    //callback functions from the IP filter driver. (看到了吧,最后一句話,注冊新的回調函

    數,就將原先的清除掉了,
    //所以說系統中只存在一個這樣的驅動有用。)
    //we build the irp needed to establish fitler function這個地方僅

    僅是生成這樣的IRP,并沒有注冊
    irp =

    IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER,
         

      ipDeviceObject,
         

    (PVOID) &filterData,
         

    sizeof(PF_SET_EXTENSION_HOOK_INFO),
         

    NULL,
         

    0,
         

    FALSE,
         

    &event,
         

    &ioStatus);


    if(irp != NULL)
    {
      // we send the IRP
      //這個地方才是真正的注冊呀。
      status = IoCallDriver(ipDeviceObject, irp);

      //and finally, we wait for "acknowledge" of

    IpDriverFilter
      if (status == STATUS_PENDING)
      {
      waitStatus = KeWaitForSingleObject(&event,

    Executive, KernelMode, FALSE, NULL);

      if (waitStatus != STATUS_SUCCESS )

    {}
      }

      status = ioStatus.Status;

      if(!NT_SUCCESS(status)){}
    }

    else
    {
      //if we cant allocate the space, we return the

    corresponding code error
      status = STATUS_INSUFFICIENT_RESOURCES;

    }

    if(ipFileObject != NULL)
      ObDereferenceObject(ipFileObject);

    ipFileObject = NULL;
    ipDeviceObject = NULL;
    }

    else

    return status;
    }
    //真正的過濾函數是這個,在最早的IRPdispatch里面傳遞的這個函數。
    //這個函數就是系統傳遞了一個包頭和包內容和包長度之類的東西,你可以在里面進行一些處理,
    //假如你想讓這個包通過的話,就返回PF_FORWARD,或者你不想讓包通過的話,就返回PF_D

    ROP就攔住了。是不是
    //聽起來很簡單,
    PF_FORWARD_ACTION cbFilterFunction(IN unsigned char *PacketHeader,IN

    unsigned char *Packet, IN unsigned int PacketLength, IN unsigned int

    RecvInterfaceIndex, IN unsigned int SendInterfaceIndex, IN unsigned long

    RecvLinkNextHop, IN unsigned long SendLinkNextHop)
    {
    IPPacket *ipp;
    TCPHeader *tcph;
    UDPHeader *udph;

    int countRule=0;

    struct filterList *aux = first;

    //we "extract" the ip Header
    ipp=(IPPacket *)PacketHeader;

    // dprintf("Source: %x\nDestination: %x\nProtocol: %d", ipp->ipSource,

    ipp->ipDestination, ipp->ipProtocol);

    //TCP -> protocol = 6
    //we accept all packets of established connections
    if(ipp->ipProtocol == 6)
    {
    tcph=(TCPHeader *)Packet;

    // dprintf("FLAGS: %x\n", tcph->flags);

    //if we havent the bit SYN activate, we pass the packets
    if(!(tcph->flags & 0x02))
      return PF_FORWARD;
    }

    //otherwise, we compare the packet with our rules
    while(aux != NULL)
    {
    // dprintf("Comparing with Rule %d", countRule);

    //if protocol is the same....
    if(aux->ipf.protocol == 0 || ipp->ipProtocol ==

    aux->ipf.protocol)
    {
      //we look in source Address
      if(aux->ipf.sourceIp != 0 && (ipp->ipSource &

    aux->ipf.sourceMask) != aux->ipf.sourceIp)
      {
      aux=aux->next;
     
      countRule++;
      continue;
      }
         
      // we look in destination address
      if(aux->ipf.destinationIp != 0 && (ipp->ipDestination

    & aux->ipf.destinationMask) != aux->ipf.destinationIp)
      {
      aux=aux->next;

      countRule++;
      continue;
      }
     
      //if we have a tcp packet, we look in ports
      //tcp, protocol = 6
      if(ipp->ipProtocol == 6)
      {
      if(aux->ipf.sourcePort == 0 ||

    tcph->sourcePort == aux->ipf.sourcePort)
      {
      if(aux->ipf.destinationPort == 0

    || tcph->destinationPort == aux->ipf.destinationPort) //puerto tcp destino
      {
        //now we decided what

    to do with the packet
        if(aux->ipf.drop)
         

    return PF_DROP;
        else
       

    return PF_FORWARD;
      }
      }
      }
     
      //udp, protocol = 17
      else if(ipp->ipProtocol == 17)
      {
      udph=(UDPHeader *)Packet;

      if(aux->ipf.sourcePort == 0 ||

    udph->sourcePort == aux->ipf.sourcePort)
      {
      if(aux->ipf.destinationPort == 0

    || udph->destinationPort == aux->ipf.destinationPort)
      {
        //now we decided what

    to do with the packet
        if(aux->ipf.drop)
        return

    PF_DROP;
       
        else
        return

    PF_FORWARD;
      }
      }
      }
     
      else
      {
      //for other packet we dont look more and

    ....
      //now we decided what to do with the

    packet
      if(aux->ipf.drop)
      return PF_DROP;
      else
      return PF_FORWARD;
      }
    }

    //compare with the next rule
    countRule++;
    aux=aux->next;
    }

    //we accept all not registered
    return PF_FORWARD;
    }

    winpcap也是用的NDIS,將自己注冊為一個協議處理驅動。(在原代碼的driverentry里面能看到)

    又:上面這個drvipflt這個代碼的過濾部分不知道大家是不是看起來很熟悉,是的,是抄的那個nu

    mege的驅動開發包里面的一個包過濾程序里的,看來老外也是喜歡到處抄的。

    ruike:
    讀研的時候專門搞過nids,因此對winpcap可以說是情有獨鐘,這個東東確實好用,但也確實很煩

    人,它有一個致命的缺陷就是只適用于共享式以太網絡,對于交換式網絡下的數據則無能為力,我

    專門做過測試,在使用交換機連接的局域網下,只能監聽到本網段內的數據,而對于來自其他網段

    的數據則無法監聽,除非你把probe接到交換機之前或者接到交換機的console口上,不過那樣的

    弊端是顯而易見的。
    所以,winpcap的應用還是很有局限性的!

    kingzai:
    實現交換網絡的嗅探也有不少方法的
    1.將你的抓包程序放在網關或代理服務器上,這樣抓到整個局域網的包。
    2.對交換機實行端口映射,將該端口的數據包全部映射到某個監控機器上。
    3.在交換機和路由器之間連接一個HUB,這樣數據將以廣播的方式發送。
    4.實行ARP欺騙,即在你的機器上實現整個包的轉發,不過會降低整個局域網的效率。

    warton:
    嗅探對策:
    光說嗅探了,我說說反嗅探吧:)
    1.檢查網內的主機上是否將網卡設置為混合模式(有很多工具可以做到,AntiSniff,Promiscan,S

    entinel等)
    2.對EtterCap這樣的交換網絡嗅探器(進行ARP欺騙),可以采用防止ARP欺騙的方法來對待
    3.SSH加密通道
    4.SSL
    5.VPN
    6.PGP等

    目前這用利用網卡混合模式來進行sniffer的軟件看來作用不太大了,所以應該多考慮交換網絡的可

    行辦法:

    MAC Flooding,MAC Duplicating,ARP欺騙等等
    這些方法實現起來就不怎么容易了,歡迎有興趣的朋友提供相關的資料,呵呵!

    netsys:
    難道沒人用過RAW SOCKET 嗎?
    雖然WINPCP功能很大,但RAW SOCKET可以讓你直接了SOCKET的原生機制。
    實際上我提的那兩個問題是很容易解決的。。

    netsys2:
    對于一些混合模式的SNIFFER,大多采用發送特殊ARP包的方式,正確的網卡不會響應,而處于

    混合模式的網卡則會響應。

    當然,ARP與IP處于同層,因此你不能用RAW SOCKET完成,你需WinPcap支持工作。

    下面是部分代碼

    AnsiString msgStatus;
    extern TArpFuncParam wParams;

    int BuildARPPacket(PArpPacket ArpPacket, unsigned char *dst_etheraddr,
      unsigned char *src_etheraddr, int ar_op, unsigned

    char *ar_sha,
      unsigned char *ar_sip, unsigned char *ar_tha,
                    unsigned char *ar_tip,unsigned short int ar_hw)
    {
    memcpy(&(ArpPacket->eth_dst_addr), dst_etheraddr, ETH_ADD_LEN);
    memcpy(&(ArpPacket->eth_src_addr), src_etheraddr, ETH_ADD_LEN);
    ArpPacket->eth_type = htons(ETH_TYPE_ARP);
    ArpPacket->ar_hrd = htons(ar_hw);
    ArpPacket->ar_pro = htons(ARP_PRO_IP);
    ArpPacket->ar_hln = ARP_ETH_ADD_SPACE;
    ArpPacket->ar_pln = ARP_IP_ADD_SPACE;
    ArpPacket->ar_op = htons(ar_op);
    memcpy(&(ArpPacket->ar_sha), ar_sha, ARP_ETH_ADD_SPACE);
    memcpy(&(ArpPacket->ar_spa), ar_sip, ARP_IP_ADD_SPACE);
    memcpy(&(ArpPacket->ar_tha), ar_tha, ARP_ETH_ADD_SPACE);
    memcpy(&(ArpPacket->ar_tpa), ar_tip, ARP_IP_ADD_SPACE);
    memset(ArpPacket->eth_pad, 32, ETH_PADDING_ARP);
    return(EXIT_SUCCESS);
    }
    int OpenAdapter(LPADAPTER *lpAdapter)
    {
    *lpAdapter =

    PacketOpenAdapter(wParams.AdapterList[wParams.SelectedAdapter]);

    if(!(*lpAdapter) || ((*lpAdapter)->hFile == INVALID_HANDLE_VALUE))
    {
      msgStatus = "Error : unable to open the driver.";
      SHOWSTAT(msgStatus);
      return(EXIT_FAILURE);
    }
    return(EXIT_SUCCESS);
    }
    void CloseAdapter(LPADAPTER lpAdapter)
    {
    PacketCloseAdapter(lpAdapter);

    }
    void GetLocalMAC(LPADAPTER lpAdapter, unsigned char *ether_addr)
    {

    ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA) + sizeof(ULONG) - 1);
    PPACKET_OID_DATA OidData;

    OidData = (struct _PACKET_OID_DATA *)malloc(IoCtlBufferLength);
    OidData->Oid = OID_802_3_CURRENT_ADDRESS;
    OidData->Length = 6;
    if(PacketRequest(lpAdapter, FALSE, OidData) == FALSE)
        memcpy(ether_addr, 0, 6);
    else
        memcpy(ether_addr, OidData->Data, 6);
    free(OidData);
    }
    int GetARPReply(LPPACKET lpPacket, unsigned char *iptarget, unsigned char

    *result)
    {
    unsigned short int ether_type;
    unsigned char     ipsender[4];  
    unsigned int     off=0;
    unsigned int     tlen;
    struct bpf_hdr   *hdr;
    char         *pChar;
    char         *buf;

    buf = (char *)lpPacket->Buffer;
    hdr = (struct bpf_hdr *)(buf + off);
    tlen = hdr->bh_caplen;
    off += hdr->bh_hdrlen;  
    pChar = (char*)(buf + off);
    off = Packet_WORDALIGN(off + tlen);
    memcpy(ðer_type, pChar + 12, 2);
    ether_type = ntohs(ether_type);
    if(ether_type == ETH_TYPE_ARP)
    {
      memcpy(ipsender, pChar + 28, 4);
      if((iptarget[0] == ipsender[0])&&(iptarget[1] == ipsender[1])&&
        (iptarget[2] == ipsender[2])&&(iptarget[3] == ipsender[3]))
        memcpy(result, pChar + 22, 6);
      else
        return(EXIT_FAILURE);
    }
    else
        return(EXIT_FAILURE);
    return(EXIT_SUCCESS);
    }
    int CheckPROMode(LPADAPTER lpAdapter, unsigned char *iptarget, unsigned char

    *remotemac)
    {

    LPPACKET lpPacketRequest;
    LPPACKET lpPacketReply;
    char   buffer[256000];

    TArpPacket ArpPacket;
    unsigned char magicpack[ETH_ADD_LEN]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFE};
    unsigned char mactarget[ARP_ETH_ADD_SPACE];

    DWORD timestamp = 0;
    int numPacks = 0;
    /* Init fields */
    memset(mactarget, 0, 6);
    /* Allocate PACKET structure for ARP Request packet */
    if((lpPacketRequest = PacketAllocatePacket()) == NULL)
    {
      msgStatus = "Error : failed to allocate the LPPACKET structure..";
      SHOWSTAT(msgStatus);
      return(EXIT_FAILURE);
    }

    /* Init packet structure */
    memset(&ArpPacket, 0, sizeof(TArpPacket));

    /* Build ARP Request packet */
    BuildARPPacket(&ArpPacket, magicpack, wParams.srcMAC, ARP_OP_REQUEST,

    wParams.srcMAC, wParams.srcIPAdd, mactarget, iptarget,wParams.ar_hw);

    /* Init ARP Request packet */
    PacketInitPacket(lpPacketRequest, &ArpPacket, sizeof(ArpPacket));

    /* Set number of ARP Request packets to send */
    if(PacketSetNumWrites(lpAdapter, 1) == FALSE)
    {
      msgStatus = "Warning : unable to send more than one packet in a single write..";
      SHOWSTAT(msgStatus);
    }
    /* Set hardware filter to directed mode */
    if(PacketSetHwFilter(lpAdapter, NDIS_PACKET_TYPE_DIRECTED) == FALSE)
    {
      msgStatus ="Warning: unable to set directed mode..";
      SHOWSTAT(msgStatus);
    }
    /* Set a 512K buffer in the driver */
    if(PacketSetBuff(lpAdapter, 512000) == FALSE)
    {
      msgStatus = "Error: unable to set the kernel buffer..";
      SHOWSTAT(msgStatus);
      PacketFreePacket(lpPacketRequest);
      return(EXIT_FAILURE);
    }
    /* Set a 1 second read timeout */
    if(PacketSetReadTimeout(lpAdapter, -1) == FALSE)
    {
      msgStatus = "Warning: unable to set the read tiemout..";
      SHOWSTAT(msgStatus);
    }

    /* Allocate PACKET structure for ARP Reply packet */
    if((lpPacketReply = PacketAllocatePacket()) == NULL)
    {
      msgStatus = "Error: failed to allocate the LPPACKET structure..";
      SHOWSTAT(msgStatus);
      PacketFreePacket(lpPacketRequest);
      return(EXIT_FAILURE);
    }
    /* Init ARP Reply packet */
    PacketInitPacket(lpPacketReply, (char*)buffer, 256000);
    /* Allocate memory for remote MAC address */
    timestamp = GetTickCount();

    /* Main capture loop */
    for(;;)
    {
      if(numPacks < wParams.numPacks)
      {
      /* Send packet */
        if(PacketSendPacket(lpAdapter, lpPacketRequest, TRUE) == FALSE)
        {
        msgStatus ="Error : unable to send the packets..";
        SHOWSTAT(msgStatus);
        PacketFreePacket(lpPacketRequest);
        PacketFreePacket(lpPacketReply);
        return(EXIT_FAILURE);
        }
        /* Free packet */
        PacketFreePacket(lpPacketRequest);
        numPacks += 1;
      }
      /* Capture the packets */
      if(PacketReceivePacket(lpAdapter, lpPacketReply, TRUE) == FALSE)
      {
        msgStatus = "Error: PacketReceivePacket failed..";
        SHOWSTAT(msgStatus);
    PacketFreePacket(lpPacketReply);
      return(EXIT_FAILURE);
      }
      if(lpPacketReply->ulBytesReceived > 0)
      if(GetARPReply(lpPacketReply, iptarget, remotemac) == EXIT_SUCCESS)
          break;
      if((GetTickCount() - timestamp) > wParams.delay)
      {
        PacketFreePacket(lpPacketReply);
        return(EXIT_FAILURE);
      }
    }
    /* Free packet */
    PacketFreePacket(lpPacketReply);
    return(EXIT_SUCCESS);
    }
    sunxufei:
    哦,交換機是以MAC地址進行交換的,不是IP那一層的,要IP已經路由器了
    現在交換機便宜了,因此以后你想用sniffer抓密碼概率不大了,不過還能多公司仍然是交換機和H

    UB一起用的,這樣小范圍內是有效地,至于ADSL CABLE FTTB,我的FTTB是用華為設計的設備

    ,呵呵,不僅僅工網IP,只有我和交換機兩個MAC(這次中國人干的不錯),沒希望找到第三者,很安全,但

    不都這樣安全,很多人的網絡還是很糟糕的.
    很多加密協議可以用來提高安全性,但老的POP3,SMTP,HTTP,FTP這種協議應用廣泛,不可能在短

    時間內完全取代,而且加密也是有待價的,所以對于要求較高的場合,才會加密.
    不過sniffer不是給大家偷密碼用的,我當初用來學習網絡,看看包的樣子,后來就用來當作網管工具,

    分析網絡的健康與否,其實這樣的話,你知道,很有可能sniffer就是接在我需要探測的網絡上,聽診器

    嗎,到處都聽聽,呵呵,因此即使用了交換機,sniffer仍然是有用處的,但不是抓密碼!!
    Wincap很簡單,大3的學生不要怕,去他的網站看看,有例子的,VC6編譯,BCB也行的,把lib的格式轉

    換一下,不過寫這種程序,你最好先熟悉協議,很多協議在linux里有現成的源代碼,主要是一些struct

    吧,移植時注意VC可不是gcc,有些c的高級語法,編譯選項要注意,否則差一個byte你就得不到正確的

    結果.
    如果你搞不到sniffer,Win2000 Server也有網絡包查看器的,不比sniffer強大,但簡單的東西入手


    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>