How can I do infection to captured Packet in linux

0

I have a local server and client.Its ok.My goal is infection to captured packet for example: server send:"hello world" client recv:"hello word"

instead of server send:"hello world" and I want to change packets data or modify data like this >>>
client recv:"another sentences"

I wrote a sniffer in C(Not at all ı am new this world.) CODE:

   #include<stdio.h> 
#include<string.h> 
#include<sys/socket.h>    
#include<stdlib.h> 
#include<errno.h> /
#include<netinet/tcp.h>   
#include<netinet/ip.h>    
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/filter.h>
void PrintData (unsigned char* , int);

FILE *logfile;
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
/* 
   96 bit (12 bytes) pseudo header needed for tcp header checksum calculation 
*/
struct pseudo_header
{
    u_int32_t source_address;
    u_int32_t dest_address;
    u_int8_t placeholder;
    u_int8_t protocol;
    u_int16_t tcp_length;
};


unsigned short csum(unsigned short *ptr,int nbytes) 
{
    register long sum;
    unsigned short oddbyte;
    register short answer;

    sum=0;
    while(nbytes>1) {
        sum+=*ptr++;
        nbytes-=2;
    }
    if(nbytes==1) {
        oddbyte=0;
        *((u_char*)&oddbyte)=*(u_char*)ptr;
        sum+=oddbyte;
    }

    sum = (sum>>16)+(sum & 0xffff);
    sum = sum + (sum>>16);
    answer=(short)~sum;

    return(answer);
}

int main (void)
{
    struct sock_filter code[] = {

    { 0x30,  0,  0, 0x00000009 },
    { 0x15,  0,  7, 0x00000006 },
    { 0x28,  0,  0, 0x00000014 },
    { 0x45,  4,  0, 0x00001fff },
    { 0xb1,  0,  0, 0x0000000e },
    { 0x50,  0,  0, 0x00000013 },
    { 0x15,  0,  2, 0x00000050 },
    { 0x06,  0,  0, 0xffffffff },
    { 0x06,  0,  0, 0xffffffff },
    { 0x06,  0,  0, 0000000000 },


};
     char datagram[4096]  , *data , *pseudogram;
    struct iphdr *iph = (struct iphdr *) datagram;

//TCP header
    struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip));
    struct sockaddr_in sin,sender;
    struct pseudo_header psh;
    int s = socket (AF_INET, SOCK_RAW, IPPROTO_TCP);
    if(s == -1)
    {
        //socket creation failed, may be because of non-root privileges
        perror("Failed to create socket");
        exit(1);
    }

    char messg[500],source_ip[32];
    //some address resolution
    strcpy(source_ip , "127.0.0.1");
    sin.sin_family = AF_INET;
    sin.sin_port = 13;
    sin.sin_addr.s_addr = inet_addr ("127.0.0.1");
    sender.sin_family = AF_INET;
    sender.sin_port = ;
    sender.sin_addr.s_addr = inet_addr ("127.0.0.1");

    struct sock_fprog bpf;
//    bpf.len = ARRAY_SIZE(code);
    bpf.len = 10;
    bpf.filter = code;


    logfile=fopen("log.txt","w");
    if(logfile==NULL) printf("Unable to create file.");
//Create a raw socke

    setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
    perror("setsockopt");
//Datagram to represent the packet


//zero out the packet buffer
    memset (datagram, 0, 4096);

//

//Data part
    data = datagram + sizeof(struct iphdr) + sizeof(struct tcphdr);
    strcpy(data , messg);



    bind(s, (struct sockaddr *)&sin, sizeof(sin));
    perror("bind");

//Fill in the IP Header
    iph->ihl = 5;
    iph->version = 4;
    iph->tos = 0;
    iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr) + strlen(data);
    iph->id = htonl (54321); //Id of this packet
    iph->frag_off = 0;
    iph->ttl = 255;
    iph->protocol = IPPROTO_TCP;
    iph->check = 0;      //Set to 0 before calculating checksum
    iph->saddr = inet_addr ( source_ip );    //Spoof the source ip address
    iph->daddr = sin.sin_addr.s_addr;

//Ip checksum
    iph->check = csum ((unsigned short *) datagram, iph->tot_len);
    unsigned short iphdrlen;
     iphdrlen =iph->ihl*4;
//TCP Header
    tcph->source = htons (1234);
    tcph->dest = htons (80);
    tcph->seq = 0;
    tcph->ack_seq = 0;
    tcph->doff = 5;  //tcp header size
    tcph->fin=0;
    tcph->syn=1;
    tcph->rst=0;
    tcph->psh=0;
    tcph->ack=0;
    tcph->urg=0;
    tcph->window = htons (5840); /* maximum allowed window size */
    tcph->check = 0; //leave checksum 0 now, filled later by pseudo header
    tcph->urg_ptr = 0;

//Now the TCP checksum
    psh.source_address = inet_addr( source_ip );
    psh.dest_address = sin.sin_addr.s_addr;
    psh.placeholder = 0;
    psh.protocol = IPPROTO_TCP;
    psh.tcp_length = htons(sizeof(struct tcphdr) + strlen(data) );

    int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + strlen(data);
    pseudogram = malloc(psize);

    memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header));
    memcpy(pseudogram + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr) + strlen(data));

    tcph->check = csum( (unsigned short*) pseudogram , psize);

//IP_HDRINCL to tell the kernel that headers are included in the packet
    int one = 1;
    const int *val = &one;



    if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
    {
        perror("Error setting IP_HDRINCL");
        exit(0);
    }

//loop if you want to flood :)
    while (1)
    {   sleep(1);
        //Send the packet
        if (sendto (s, datagram, iph->tot_len ,  0, (struct sockaddr *) &sender, sizeof (sender)) < 0)
        {
            perror("sendto failed");
        }
        //Data send successfully
        else
        {
            char bbuf[500]={0};
            int re = 0;
            printf ("Packet Send. Length : %d \n" , iph->tot_len);
            if ( recvfrom(s, bbuf, 500, 0, (struct sockaddr *) &sender, &re)< 0)
                printf("Recv failed\n");

            else
            {
                printf("%x %x %x %x %x \n", bbuf[0], bbuf[1], bbuf[2], bbuf[3], bbuf[4] );
        int numbytes;



            printf("Received in pid=%d, text=: %s \n",getpid(), bbuf);
            sleep(1);
        fprintf(logfile,"TCP Header\n");
      PrintData(bbuf + iphdrlen,tcph->doff*4);

      fprintf(logfile,"Data Payload\n");  
       PrintData(bbuf + iphdrlen + tcph->doff*4 , (500 - tcph->doff*4-iph->ihl*4) );

            }
            if (recvfrom(s, bbuf, 500, 0, (struct sockaddr *) &sin, &re) < 0)
                printf("Recv failed\n");
            else
            {   
                int i;
        for(i=0;i<500;i++)
        {
            printf("%x ",bbuf[i]);      
        }
            }
        }

    }

    return 0;
}
void PrintData (unsigned char* data , int Size)
{
     int i,j;
    for(i=0 ; i < Size ; i++)
    {
        if( i!=0 && i%16==0)   //if one line of hex printing is complete...
        {
            fprintf(logfile,"         ");
            for(j=i-16 ; j<i ; j++)
            {
                if(data[j]>=32 && data[j]<=128)
                    fprintf(logfile,"%c",(unsigned char)data[j]); //if its a number or alphabet

                else fprintf(logfile,"."); //otherwise print a dot
            }
            fprintf(logfile,"\n");
        } 

        if(i%16==0) fprintf(logfile,"   ");
            fprintf(logfile," %02X",(unsigned int)data[i]);

        if( i==Size-1)  //print the last spaces
        {
            for(j=0;j<15-i%16;j++) fprintf(logfile,"   "); //extra spaces

            fprintf(logfile,"         ");

            for(j=i-i%16 ; j<=i ; j++)
            {
                if(data[j]>=32 && data[j]<=128) fprintf(logfile,"%c",(unsigned char)data[j]);
                else fprintf(logfile,".");
            }
            fprintf(logfile,"\n");
        }
    }
}

I know somewhere is missing or mistaken but its not important now(ı am trying another things in this code but its working..). I want to make a filter maybe basic bsf and I want drop to client connect .stop the connection between the server and the client after that changing packets and resume connect.ı dont know how to do this. OR.when client-server connecting is continuing.My code is sniffing and modify to packet.How can I do.thanks and sorry my bad english :)

c
sockets
packet-sniffers
packet-injection
asked on Stack Overflow Nov 8, 2018 by KAAN TOKALI

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0