dns 쿼리 캡쳐-네트워크 보안 수업 17일차 - 코리아 정보보안 IT학원

2016. 5. 31. 16:48네트워크 보안 수업/네트워크 취약점 분석

반응형

#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[20];

        unsigned short type;

        unsigned short class;


} __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 recv_sock = 0;

        int size = 0;

        int count1 = 0;

        int count2 = 0;

        int count3 = 0;

        int count4 = 0;

        int i=0;

        int j=1;

        char src[9] = {0,};

        char dst[9] = {0,};


        char src_port[2] = {0,};

        char dst_port[2] = {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 data[sizeof( eth ) + sizeof( ip ) + sizeof( udp )] = {0,};


        unsigned char *ptr = data;


        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)){


                                        printf("DNS packet ");


                                        count1 = pudp->domain[0];

                                        count2 = pudp->domain[count1+1];

                                        count3 = pudp->domain[count1+count2+2];

                                        count4 = pudp->domain[count1+count2+count3+3];

/*

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

                                                printf("%2x ",pudp->domain[i]);

                                        }

                                        printf("\n");


                                        printf("%d,%d,%d,%d\n",count1,count2,count3,count4);

*/

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

                                                printf("%c",pudp->domain[j]);

                                                j=j+1;

                                        }

                                        printf(".");

                                        j=j+1;

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

                                                printf("%c",pudp->domain[j]);

                                                j=j+1;

                                        }

                                        printf(".");

                                        j=j+1;

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

                                                printf("%c",pudp->domain[j]);

                                                j=j+1;

                                        }

                                        if(count4==0){

                                                printf("\n");

                                        } else if(count4!=0){

                                                printf(".");

                                                j=j+1;

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

                                                        printf("%c",pudp->domain[j]);

                                                        j=j+1;

                                                }

                                                printf("\n");

                                        }

                                        ptr = data;

                                        j=1;

                                        printf("\n");

                                }

                        }

                }

        }


        return 0;

}


반응형