Wireshark Причина повторной передачи TCP (сокет, netfilter - PullRequest
0 голосов
/ 13 июля 2020

Цель этого исследования - обойти блокировку вредоносных сайтов. Поэтому я выбрал метод сегментации пакетов.

p c пытается разделить и отправить пакет с портом назначения 80 443. Проблема возникает после разделения и передачи. Вот как.

  1. используйте iptables для обнаружения выходных пакетов и управления ими с помощью netfilter_queue.
#iptables
iptables -A OUTPUT -p tcp --dport 443 -j NFQUEUE --queue-num 0
iptables -A OUTPUT -p tcp --dport 80 -j NFQUEUE --queue-num 0 
Он управляется с помощью nfqnl_test. c. В nfqnl_test. c исходные пакеты разделяются с использованием сырого сокета, и выполняется вывод (raw socket: sendto ()). [проблемы] [1]: https://i.stack.imgur.com/t9boJ.png
  • Разделение прошло успешно. Однако генерируются пакеты повторной передачи TCP.

На текущем этапе тестирования проблем нет, но когда я начал доступ к вредоносному сайту, повторная передача TCP заблокировала доступ к вредоносному сайту.

  • Какие сетевые знания вам нужны? Помощь не терпится.

деление. cpp

      void division_packet(u_char *packet)
      {
          struct iphdr * iphdr = reinterpret_cast<struct iphdr*>(packet);
          struct tcphdr * tcphdr = reinterpret_cast<struct tcphdr*>(packet+(iphdr->ihl*4));

         int iptcp_len = (iphdr->ihl*4) + (tcphdr->doff*4);
         u_char *iptcp_temp = static_cast<u_char*>(malloc(static_cast<size_t>(iptcp_len)));
         iptcp_temp = packet;
         int tcp_segment_len = ntohs(iphdr->tot_len) - iptcp_len;

         int i=0;
         bool fst=true;
         bool send=true;
         int remainter_segment=tcp_segment_len -1; 
         while(send)
         {
         cout<<"#################        [+] error checking               #################\n";
         u_char *assemble;
         if(fst)     
             assemble=static_cast<u_char*>(malloc(static_cast<size_t>(iptcp_len+1)));
         else
            assemble=static_cast<u_char*>(malloc(static_cast<size_t>(iptcp_len+remainter_segment)));
        //        printf("%02x\n",static_cast<u_char>(packet[i]));

         while(true)
         {
             if(i<iptcp_len){
                 assemble[i]=packet[i];
             }
             else if(tcp_segment_len >0)
             {
                 if(fst){        
                     assemble[i]=packet[i];
                     //                    remainter_segment = tcp_segment_len -1;         
                     cout<<'\n'<<"[#]first division  ------\n";
                     cout<<"[#]Segment full len: "<<tcp_segment_len<<'\n';
                     cout<<"[#]remainter len: "<<remainter_segment<<'\n';
                     struct sockaddr_in sock,sock2;
                     sock.sin_addr.s_addr =iphdr->saddr;
                     sock2.sin_addr.s_addr =iphdr->daddr;
                     cout<<"[#]Source IP: "<<inet_ntoa(sock.sin_addr)<<'\n';
                     cout<<"[#]Destination IP: "<<inet_ntoa(sock2.sin_addr)<<'\n';
                     cout<<"[#]Sport: "<<dec<<ntohs(tcphdr->source)<<'\n';
                     cout<<"[#]Dport: "<<dec<<ntohs(tcphdr->dest)<<'\n';
                     sendto_packet(assemble,iptcp_len+1);
                     i=0;
                     fst=false;
                     break;
                 }
                 else{   
                     if((i-iptcp_len) < remainter_segment)   
                         assemble[i]=packet[i+1];        
                     else{
                         cout<<'\n'<<"[#]second division ------\n";
                         struct iphdr * as_ip = reinterpret_cast<struct iphdr*>(assemble);
                         as_ip->id=htons(ntohs(as_ip->id)+1);
                         struct tcphdr * as_tcphdr = reinterpret_cast<struct tcphdr*>(assemble+(iphdr->ihl*4));
                         as_tcphdr->seq = htonl(ntohl(as_tcphdr->seq) + 1);  
                         sendto_packet(assemble,iptcp_len+remainter_segment);
                         send=false;
                         break;
                     }

                 }
             }
             i++;
         }
         free(assemble);
         }
        cout<<"[#] sendto division end\n";
        cout<<"\n";
        }
    void sendto_packet(u_char *packet,int packet_len)
    {
        cout<<"[##] Packet Len: "<<packet_len<<"[sendto packet func]"<<'\n';
        struct iphdr * iphdr = reinterpret_cast<struct iphdr*>(packet);
        struct tcphdr * tcphdr = reinterpret_cast<struct tcphdr*>(packet+(iphdr->ihl*4));
        //    uint16_t tcp_len= (ntohs(iphdr->tot_len)-(iphdr->ihl*4));



        //    tcphdr->check = calTCPChecksum(packet,ntohs(iphdr->tot_len));
        /*
            cout<<"PROTOCOL: "<<dec<<iphdr->protocol<<'\n';
            cout<<"Source IP: "<<hex<<iphdr->saddr<<'\n';
            cout<<"Destination IP: "<<hex<<iphdr->daddr<<'\n';
            cout<<"Sport: "<<tcphdr->source<<'\n';
            cout<<"Dport: "<<tcphdr->dest<<'\n';
    */
        struct sockaddr_in mysocket;
        struct in_addr daddr;
    
        int sockd = socket(AF_INET,SOCK_RAW,IPPROTO_TCP);   
        if(sockd<0)
        {
            perror("error socket\n");
            exit(1);
        }
        int on=1;
        if(setsockopt(sockd,IPPROTO_IP,IP_HDRINCL,reinterpret_cast<char*>(&on),sizeof(on)) < 0)
        {
            perror("error setsockopt\n");
        }


        daddr.s_addr = iphdr->daddr;    
        mysocket.sin_addr = daddr;
        mysocket.sin_family=AF_INET;
        mysocket.sin_port = tcphdr->dest;


        ssize_t res = sendto(sockd,packet,static_cast<size_t>(packet_len),0x0,
                             reinterpret_cast<struct sockaddr*>(&mysocket),sizeof(mysocket));

        if(res != static_cast<ssize_t>(packet_len)){
            perror("error sendto\n");
            exit(1);
        }
        int c = close(sockd);
        if(c<0)
        {
            perror("error close socket\n");
            exit(1);
        }

    }
...