본문 바로가기
네트워크 (LAN,WAN)

Winpcap을 사용하여 패킷을 생성하기

by 날으는물고기 2009. 5. 31.

Winpcap을 사용하여 패킷을 생성하기

winpcap developer's packs 인 WpdPack를 다운 받으면 그 안에 샘플들이 많이 있어서....
이런걸 정리할 필요가 있을까 싶지만;;ㅋㅋㅋ 그냥...-;
 
 * 자신의 프로젝트에 winpcap을 사용하고자 할 때 설정 방법은 http://www.winpcap.org/docs/docs_40_2/html/group__wpcapsamps.html 이 페이지를 참조하면 됩니다-..

코드에 주석을 달아놨으니......다른 설명은 패수-ㅋ
바로 코드 보도록 하겠습니다.
 
  1. #include "stdafx.h"   
  2. #include <pcap.h>   
  3.   
  4. /* Ethernet Header Structure */  
  5. #define  ETHER_ADDR_LEN 6   
  6. typedef struct ether_header {   
  7.     unsigned char   ether_dhost[ETHER_ADDR_LEN];   
  8.     unsigned char   ether_shost[ETHER_ADDR_LEN];   
  9.     unsigned short  ether_type;   
  10. } ETHER_HDR;   
  11.   
  12. #define ETHERTYPE_IP            0x0800   /* IP Protocol */   
  13. #define ETHERTYPE_ARP           0x0806   /* Address Resolution Protocol */   
  14. #define ETHERTYPE_REVARP        0x8035   /* reverse Address Resolution Protocol */   
  15.   
  16.   
  17. /* IP Header Structure */  
  18. typedef struct ip_hdr   
  19. {   
  20.     unsigned char  ip_header_len:4;  // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)   
  21.     unsigned char  ip_version   :4;  // 4-bit IPv4 version   
  22.     unsigned char  ip_tos;           // IP type of service   
  23.     unsigned short ip_total_length;  // Total length   
  24.     unsigned short ip_id;            // Unique identifier    
  25.        
  26.     unsigned char  ip_frag_offset   :5;        // Fragment offset field   
  27.        
  28.     unsigned char  ip_more_fragment :1;   
  29.     unsigned char  ip_dont_fragment :1;   
  30.     unsigned char  ip_reserved_zero :1;   
  31.        
  32.     unsigned char  ip_frag_offset1;    //fragment offset   
  33.        
  34.     unsigned char  ip_ttl;           // Time to live   
  35.     unsigned char  ip_protocol;      // Protocol(TCP,UDP etc)   
  36.     unsigned short ip_checksum;      // IP checksum   
  37.     unsigned int   ip_srcaddr;       // Source address   
  38.     unsigned int   ip_destaddr;      // Source address   
  39. } IPV4_HDR;   
  40.   
  41.   
  42. int _tmain(int argc, _TCHAR* argv[])   
  43. {   
  44.     pcap_if_t *alldevs;   
  45.     pcap_if_t *d;   
  46.     int inum;   
  47.     int i=0;   
  48.     pcap_t *fp;   
  49.     char errbuf[PCAP_ERRBUF_SIZE];   
  50.   
  51.   
  52.     unsigned char  packet[1500];   
  53.   
  54.   
  55.     /* Retrieve the device list on the local machine */  
  56.     if (pcap_findalldevs(&alldevs, errbuf) == -1)   
  57.     {   
  58.         fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);   
  59.         exit(1);   
  60.     }   
  61.        
  62.     /* Print the list */  
  63.     for(d=alldevs; d; d=d->next)   
  64.     {   
  65.         printf("%d. %s", ++i, d->name);   
  66.         if (d->description)   
  67.             printf(" (%s)\n", d->description);   
  68.         else  
  69.             printf(" (No description available)\n");   
  70.     }   
  71.        
  72.     if(i==0)   
  73.     {   
  74.         printf("\nNo interfaces found! Make sure WinPcap is installed.\n");   
  75.         return -1;   
  76.     }   
  77.        
  78.     printf("Enter the interface number (1-%d):",i);   
  79.     scanf("%d", &inum);   
  80.        
  81.     if(inum < 1 || inum > i)   
  82.     {   
  83.         printf("\nInterface number out of range.\n");   
  84.         /* Free the device list */  
  85.         pcap_freealldevs(alldevs);   
  86.         return -1;   
  87.     }   
  88.        
  89.     /* Jump to the selected adapter */  
  90.     for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);   
  91.   
  92.     /* Open the output device */  
  93.     if ( (fp= pcap_open_live(d->name,            // name of the device   
  94.         65536,                              // portion of the packet to capture (only the first 100 bytes)   
  95.         0,  // promiscuous mode   
  96.         1000,               // read timeout   
  97.         errbuf              // error buffer   
  98.         ) ) == NULL)   
  99.     {   
  100.         fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", argv[1]);   
  101.         return -1;   
  102.     }   
  103.   
  104.     /**************************************************************************************************
  105.     **   윗 부분은 http://heestory.kr/220 을 참조하기 바람                                          **  
  106.     **************************************************************************************************/  
  107.   
  108.     memset(packet, 0, sizeof(packet));      // 전송할 패킷을 저장할 버퍼의 초기화   
  109.   
  110.     ETHER_HDR eth;                          // Ethernet Header의 구성을 위한 구조체 선언   
  111.     IPV4_HDR ip;                            // IP Header의 구성을 위한 구조체 선언   
  112.     int length = 0;                         // 생성된 Packet의 Length를    
  113.   
  114.   
  115.     ////////////////////// 2계층인 Ethernet Header를 구성   
  116.     // 지금은 테스트를 못해봐서 ... 확인하기는 힘들지만..   
  117.     // 예전에 테스트 할 때.. ethernet header의 source mac address가   
  118.     // 자신의 mac address와 다를 경우   
  119.     // 전송이 막혔던 기억이 있음..(보안상?)   
  120.     // 하지만 wireshark 같은 프로그램에서는 캡쳐됨....   
  121.   
  122.     eth.ether_dhost[0] = 0x00;   
  123.     eth.ether_dhost[1] = 0x01;   
  124.     eth.ether_dhost[2] = 0x02;   
  125.     eth.ether_dhost[3] = 0x03;   
  126.     eth.ether_dhost[4] = 0x04;   
  127.     eth.ether_dhost[5] = 0x05;   
  128.   
  129.     eth.ether_shost[0] = 0x10;   
  130.     eth.ether_shost[1] = 0x11;   
  131.     eth.ether_shost[2] = 0x12;   
  132.     eth.ether_shost[3] = 0x13;   
  133.     eth.ether_shost[4] = 0x14;   
  134.     eth.ether_shost[5] = 0x15;   
  135.   
  136.     eth.ether_type = htons(ETHERTYPE_IP);               // 3계층의 프로토콜을 지정..   
  137.   
  138.     memcpy(packet, ð, sizeof(eth));                 // 패킷 버퍼에 저장한다.   
  139.     length += sizeof(eth);                             
  140.   
  141.     memset(&ip,0x01,sizeof(ip));            // 귀찮아서 다 0x01로 채움...;;하하하..   
  142.   
  143.     ip.ip_header_len = sizeof(ip)/4;        // wireshark에서 안보여서 header length만 설정   
  144.                                             // sizeof(ip)/4 인 이유는   
  145.                                             // 1당 4 바이트를 의미하기 때문. 즉 20/4 = 5   
  146.   
  147.        
  148.     memcpy(packet+length, &ip, sizeof(ip));   
  149.     length += sizeof(ip);   
  150.   
  151.     if ( length < 64 ) {     // ethernet packet의 최소 size는 64 이다.   
  152.         for( i = length ; i < 64 ;i++)   
  153.         {   
  154.             packet[i]=0;   
  155.         }   
  156.     }   
  157.   
  158.   
  159.     /**************************************************************************************************
  160.     **   실제 패킷을 전송하는 부분                                                                 **  
  161.     **   같은 패킷을 두번 보낸다.(이유 없음..그냥!                                                 **  
  162.     **************************************************************************************************/  
  163.        
  164.     /* Send down the packet */  
  165.     if (pcap_sendpacket(fp, packet, length /* size */) != 0)   
  166.     {   
  167.         fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(fp));   
  168.         return -1;   
  169.     }   
  170.     /* Send down the packet */  
  171.     if (pcap_sendpacket(fp, packet, length /* size */) != 0)   
  172.     {   
  173.         fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(fp));   
  174.         return -1;   
  175.     }   
  176.   
  177.     return 0;   
  178. }  


아아악!!!!!!!!!!!!! 좁다.ㅠ.ㅠ

아래 그림은 wireshark에서 캡쳐한 패킷의 모습입니다.

소스에서 설정한 것처럼 나왔죠?ㅋㅋ

UDP든..TCP든....spoofing을 위한 ARP든....
프로토콜에 대해서 정확하게 이해한다면! 패킷을 만들수 있겠죠?...^-^;


출처 : http://heestory.kr/

728x90

댓글