2017-05-06 12 views
0

私はWDDの初心者です。プログラムの脆弱性からシステムを保護するために、シグネチャに基づいて特定のパケットを廃棄するネットワークドライバフィルタを作成する必要があります。 今、私は必要なパケットを手に入れようとしているだけで、自分の署名を見つけようとしています。 Metasploit Frameworkを使用してこの脆弱性を悪用し、Wiresharkを使用してトラフィックを追跡します。 Wiresharkでは、宛先ポートが8000の4つのパケットが次のように表示されます。パケットがない(Windows NDISドライバフィルタ)

Traffic picture しかし、私はそれらを取得しようとしていますが、SYNとACKでは2つしかありません。
私のコードはNDIS driver filter sampleに基づいています。私はFilterReceiveNetBufferLists関数の中に書いています。ここでは、コードがあります:

_Use_decl_annotations_ 
VOID 
FilterReceiveNetBufferLists(
    NDIS_HANDLE   FilterModuleContext, 
    PNET_BUFFER_LIST NetBufferLists, 
    NDIS_PORT_NUMBER PortNumber, 
    ULONG    NumberOfNetBufferLists, 
    ULONG    ReceiveFlags 
) 
/*++ 

Routine Description: 

    FilerReceiveNetBufferLists is an optional function for filter drivers. 
    If provided, this function processes receive indications made by underlying 
    NIC or lower level filter drivers. This function can also be called as a 
    result of loopback. If this handler is NULL, NDIS will skip calling this 
    filter when processing a receive indication and will call the next higher 
    driver in the stack. A filter that doesn't provide a 
    FilterReceiveNetBufferLists handler cannot provide a 
    FilterReturnNetBufferLists handler and cannot a initiate an original receive 
    indication on its own. 

Arguments: 

    FilterModuleContext  - our filter context area. 
    NetBufferLists   - a linked list of NetBufferLists 
    PortNumber    - Port on which the receive is indicated 
    ReceiveFlags    - 

N.B.: It is important to check the ReceiveFlags in NDIS_TEST_RECEIVE_CANNOT_PEND. 
    This controls whether the receive indication is an synchronous or 
    asynchronous function call. 

--*/ 
{ 

    PMS_FILTER   pFilter = (PMS_FILTER)FilterModuleContext; 
    BOOLEAN    DispatchLevel; 
    ULONG    Ref; 
    BOOLEAN    bFalse = FALSE; 
#if DBG 
    ULONG    ReturnFlags; 
#endif 

    DEBUGP(DL_TRACE, "===>ReceiveNetBufferList: NetBufferLists = %p.\n", NetBufferLists); 
    do 
    { 

     DispatchLevel = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags); 
#if DBG 
     FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); 

     if (pFilter->State != FilterRunning) 
     { 
      FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); 

      if (NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags)) 
      { 
       ReturnFlags = 0; 
       if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags)) 
       { 
        NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL); 
       } 

       NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags); 
      } 
      break; 
     } 
     FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); 
#endif 

     ASSERT(NumberOfNetBufferLists >= 1); 

     ////////////////////////////// MY CODE ////////////////////////////////////// 

     FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); 

     PNET_BUFFER_LIST pCurrentNetBufferList = NetBufferLists; 
     PNET_BUFFER pCurrentNetBuffer = NET_BUFFER_LIST_FIRST_NB(pCurrentNetBufferList); 

     while (pCurrentNetBufferList) 
     { 
      while (pCurrentNetBuffer) 
      { 
       ULONG netbuffer_size = NET_BUFFER_DATA_LENGTH(pCurrentNetBuffer); 

       BYTE* buffer = (BYTE*)NdisGetDataBuffer(
        pCurrentNetBuffer, 
        netbuffer_size, 
        NULL, 
        1, 
        0); 

       if (buffer) { 
        ParseBuffer(buffer, netbuffer_size); 
       } 
       else 
       { 
        void* alloc_mem = ExAllocatePoolWithTag(PagedPool, netbuffer_size, 'BteN'); 

        buffer = (BYTE*)NdisGetDataBuffer(
         pCurrentNetBuffer, 
         netbuffer_size, 
         alloc_mem, 
         1, 
         0); 

        if (buffer) { 
         ParseBuffer(buffer, netbuffer_size); 
        } 
        else { 
         DbgPrint("T.T"); 
        } 

        ExFreePoolWithTag(alloc_mem, 'BteN'); 
       } 

       pCurrentNetBuffer = NET_BUFFER_NEXT_NB(pCurrentNetBuffer); 
      } 

      pCurrentNetBufferList = NET_BUFFER_LIST_NEXT_NBL(pCurrentNetBufferList); 
     } 

     FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); 

     //////////////////////////////////////////////////////////////////////////// 

     // 
     // If you would like to drop a received packet, then you must carefully 
     // modify the NBL chain as follows: 
     // 
     //  if NDIS_TEST_RECEIVE_CANNOT_PEND(ReceiveFlags): 
     //   For each NBL that is NOT dropped, temporarily unlink it from 
     //   the linked list, and indicate it up alone with 
     //   NdisFIndicateReceiveNetBufferLists and the 
     //   NDIS_RECEIVE_FLAGS_RESOURCES flag set. Then immediately 
     //   relink the NBL back into the chain. When all NBLs have been 
     //   indicated up, you may return from this function. 
     //  otherwise (NDIS_TEST_RECEIVE_CANNOT_PEND is FALSE): 
     //   Divide the linked list of NBLs into two chains: one chain 
     //   of packets to drop, and everything else in another chain. 
     //   Return the first chain with NdisFReturnNetBufferLists, and 
     //   indicate up the rest with NdisFIndicateReceiveNetBufferLists. 
     // 
     // Note: on the receive path for Ethernet packets, one NBL will have 
     // exactly one NB. So (assuming you are receiving on Ethernet, or are 
     // attached above Native WiFi) you do not need to worry about dropping 
     // one NB, but trying to indicate up the remaining NBs on the same NBL. 
     // In other words, if the first NB should be dropped, drop the whole NBL. 
     // 

     // 
     // If you would like to modify a packet, and can do so quickly, you may 
     // do it here. However, make sure you save enough information to undo 
     // your modification in the FilterReturnNetBufferLists handler. 
     // 

     // 
     // If necessary, queue the NetBufferLists in a local structure for later 
     // processing. However, do not queue them for "too long", or else the 
     // system's performance may be degraded. If you need to hold onto an 
     // NBL for an unbounded amount of time, then allocate memory, perform a 
     // deep copy, and return the original NBL. 
     // 

     if (pFilter->TrackReceives) 
     { 
      FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); 
      pFilter->OutstandingRcvs += NumberOfNetBufferLists; 
      Ref = pFilter->OutstandingRcvs; 

      FILTER_LOG_RCV_REF(1, pFilter, NetBufferLists, Ref); 
      FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); 
     } 

     NdisFIndicateReceiveNetBufferLists(
      pFilter->FilterHandle, 
      NetBufferLists, 
      PortNumber, 
      NumberOfNetBufferLists, 
      ReceiveFlags); 


     if (NDIS_TEST_RECEIVE_CANNOT_PEND(ReceiveFlags) && 
      pFilter->TrackReceives) 
     { 
      FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); 
      pFilter->OutstandingRcvs -= NumberOfNetBufferLists; 
      Ref = pFilter->OutstandingRcvs; 
      FILTER_LOG_RCV_REF(2, pFilter, NetBufferLists, Ref); 
      FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); 
     } 

    } while (bFalse); 

    DEBUGP(DL_TRACE, "<===ReceiveNetBufferList: Flags = %8x.\n", ReceiveFlags); 

} 

ParseBuffer機能:

VOID ParseBuffer(BYTE *buffer, ULONG netbuffer_size) 
{ 
    // parse ethernet 
    eth_header_t* pEthHeader = (eth_header_t*)buffer; 
    ASSERT(pEthHeader); 

    if (pEthHeader->type == RtlUshortByteSwap(EtherType_IPv4)) 
    { 
     // parse ipv4 
     ipv4_header_t* pIpHeader = (ipv4_header_t*)(buffer + sizeof(eth_header_t)); 
     ASSERT(pIpHeader); 
     ASSERT(pIpHeader->version == IPPROTO_IPV4); 

     if (pIpHeader->protocol == IPPROTO_TCP) 
     { 
      // parse tcp 
      tcp_header_t* pTcpHeader = (tcp_header_t*)(buffer + sizeof(eth_header_t) + sizeof(ipv4_header_t)); 
      ASSERT(pTcpHeader); 

      if (pTcpHeader->dst_port == RtlUshortByteSwap(8000)) 
      { 
       if (netbuffer_size) {} 

       DbgPrint("PACKET DUMP:\n"); 
       DbgPrintHexDump(buffer, netbuffer_size); 

       WORD ip_total_length = RtlUshortByteSwap(pIpHeader->total_length); 
       WORD tcp_size = ip_total_length - sizeof(ipv4_header_t); 
       WORD data_size = tcp_size - (pTcpHeader->data_offset << 2); 

       DbgPrint("DATA SIZE: %d \n", data_size); 

       // if there is any data in packet 
       if(data_size) 
       { 
        BYTE* data = (buffer + sizeof(eth_header_t) + sizeof(ipv4_header_t) + (pTcpHeader->data_offset << 2)); 
        ASSERT(data); 

        DbgPrint("Data:\n"); 
        DbgPrintHexDump(data, data_size); 

        const char* signature = "\xEB\x0C/HTTP/1.1 "; 
        const char* pch = strstr((const char*)data, signature); 
        if (pch != NULL) 
        { 
         DbgPrint("Got it!\n"); 
        } 
       } 

       DbgPrint("\n"); 
      } 
     } 
    } 
} 

は、たぶん私はそれらを処理する前にNetBufferListsのクローンを作成する必要があり、私は知りません。そしてもし私がしなければならない時はいつ行うべきですか?

P.S. The full code(必要な場合)

答えて

0

まあ、それは愚かな間違いだった、私はPNET_BUFFER pCurrentNetBuffer = NET_BUFFER_LIST_FIRST_NB(pCurrentNetBufferList)を間違った場所に入れた。それはwhile (pCurrentNetBufferList)の直後でなければなりません。

関連する問題