免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1814 | 回复: 0
打印 上一主题 下一主题

DNS query 原理 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-22 08:53 |只看该作者 |倒序浏览
本文主要基于SOCK_RAW套接字的简单代码来展示DNS的query过程:
  1. #include <stdio.h>
  2. #include <linux/udp.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <netinet/ip.h>
  7. #include <arpa/inet.h>
  8. #include <stdlib.h>
  9. #include <time.h>
  10. #include <unistd.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <error.h>

  14. #define ATTACK_PORT 53
  15. #define NAME_LENTH 13
  16. static char default_gw[13] = "172.16.0.254";

  17. typedef struct{
  18.     short id;
  19.     short flag;
  20.     short question_num;
  21.     short rr_num;
  22.     short anthority_num;
  23.     short additional_rr;
  24. }dns_header_t;

  25. typedef struct{
  26.     char name[NAME_LENTH + 1];
  27.     short type;
  28.     short class;
  29. }dns_query_t;

  30. typedef struct {
  31.     struct udphdr udp_header;
  32.     dns_header_t dns_header;
  33.     dns_query_t dns_query;
  34. }dns_t;

  35. static int raw_socket_init(int *sockfd, void *s)
  36. {
  37.     int on = 1;
  38.     int rawfd;
  39.     struct sockaddr_in *ser = (struct sockaddr_in *)s;

  40.     setuid(getuid());
  41.     if((rawfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) < 0){
  42.         perror("socket fail");
  43.         exit(1);
  44.     }

  45.     *sockfd = rawfd;
  46.     setsockopt(rawfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));
  47.     
  48.     memset(ser, 0, sizeof(*ser));
  49.     ser->sin_family = AF_INET;
  50.     ser->sin_port = htons(ATTACK_PORT);
  51.     ser->sin_addr.s_addr = inet_addr("172.16.0.254");

  52.     return 0;
  53. }
  54. static int ip_init(void *ipp)
  55. {
  56.     struct iphdr *ip = ipp;

  57.     ip->version = IPVERSION;
  58.     ip->ihl = sizeof(struct ip) >> 2;
  59.     ip->tos = 0;
  60.     ip->tot_len = sizeof(struct ip) + sizeof(dns_t);
  61.     ip->id = 0;
  62.     ip->frag_off = 0;
  63.     ip->ttl = MAXTTL;
  64.     ip->protocol = IPPROTO_UDP;
  65.     ip->check = 0;
  66.     //inet_pton(AF_INET, "172.16.0.254", (void*)&ip->daddr);
  67.     inet_pton(AF_INET, default_gw, (void*)&ip->daddr);
  68.     
  69.     return 0;
  70. }

  71. static int dns_init(dns_t *dns)
  72. {
  73.     char name[] = {0x03,'w','w','w',0x04,'a','d','i','d',0x03,'c','o','m','\0'};
  74.     dns->udp_header.source = htons(8888);
  75.     dns->udp_header.dest = htons(53);
  76.     dns->udp_header.len = htons(sizeof(dns_t));
  77.     dns->udp_header.check = 0;

  78.     dns->dns_header.id = 0x0001;
  79.     dns->dns_header.flag = htons(0x0100);
  80.     dns->dns_header.question_num = htons(1);
  81.     dns->dns_header.rr_num = 0;
  82.     dns->dns_header.anthority_num = 0;
  83.     dns->dns_header.additional_rr = 0;
  84.     
  85.     memcpy(dns->dns_query.name, name, sizeof(name));
  86.     dns->dns_query.type = htons(1);
  87.     dns->dns_query.class = htons(1);

  88.     return 0;
  89. }

  90. static char * dns_databuf_init(void)
  91. {
  92.     char *data_buf = NULL;
  93.     struct iphdr *ip;
  94.     dns_t *dns;

  95.     if((data_buf = malloc(sizeof(dns_t) +
  96.                     sizeof(*ip))) == NULL){
  97.         free(data_buf);
  98.         perror("malloc");
  99.         return NULL;
  100.     }

  101.     ip = (struct iphdr *)data_buf;
  102.     ip_init(ip);
  103.     dns = (dns_t *)(data_buf + sizeof(*ip));
  104.     dns_init(dns);

  105.     return data_buf;
  106. }

  107. static int send_dns_query(int rawfd,
  108.         char *databuf, int lenth, void *addr)
  109. {
  110.     struct sockaddr_in *skaddr = addr;
  111.     srand(time(NULL));

  112.     sendto(rawfd, databuf, lenth, 0,
  113.                 (struct sockaddr *)skaddr, sizeof(*skaddr));
  114.   
  115.     return 0;
  116. }

  117. static int help_info(void)
  118. {
  119.     fprintf(stdout, "dns usage:\n");
  120.     fprintf(stdout, "./dns [-gw gateway] [--help]\n");

  121.     return 0;
  122. }

  123. static int param_input(int argnum, char **arg)
  124. {
  125.     int i;

  126.     if(1 == argnum){
  127.         fprintf(stderr, "input err: without dest gateway ipaddr\n");
  128.         help_info();
  129.         exit(1);
  130.     }

  131.     for(i = 1; i < argnum; i++){
  132.         if(strcmp(arg[i], "-gw") == 0){
  133.             i++;
  134.             if(i >= argnum || 12 < strlen(arg[i])){
  135.                 help_info();
  136.                 exit(1);
  137.             }
  138.             memset(default_gw, '\0', sizeof(default_gw));
  139.             strncpy(default_gw, arg[i], strlen(arg[i]));
  140.         }else if(strcmp(arg[i], "--help") == 0){
  141.             help_info();
  142.             exit(0);
  143.         }else{
  144.             help_info();
  145.             exit(1);
  146.         }
  147.     }

  148.     return 0;
  149. }

  150. int main(int argc, char *argv[])
  151. {
  152.     int rawfd;
  153.     int data_len;
  154.     struct sockaddr_in ser;
  155.     char *data_buf;
  156.     
  157.     param_input(argc, argv);
  158.     //printf("gateway:%s\n", default_gw);

  159.     /* create raw socket and init dest addr */
  160.     raw_socket_init(&rawfd, (void*)&ser);

  161.     /* create and init data send buffer */
  162.     if((data_buf = dns_databuf_init()) == NULL){
  163.         perror("dns_databuf_ini");
  164.         exit(1);
  165.     }
  166.     
  167.     /* send manual buffer data to the dest server with the raw socket */
  168.     data_len = sizeof(dns_t) + sizeof(struct iphdr);
  169.     
  170.     send_dns_query(rawfd, data_buf, data_len, (void*)&ser);
  171.     
  172.     free(data_buf);
  173.     return 0;
  174. }
基于dns的数据包与格式的原理通过wireshark的转包截图图下:
 
通过上面的原理图,很容易理解上述的基于DNS的代码原理,当然这只是简单的一个小示例,我想其他的网络数据包
的原理跟上述的思路一样,所以读者应该明白在了解各种网络协议原理的基础上,辅以相关的抓包工具,利用原始
套接字(SOCK_RAW in AF_INET or PF_INET)足以模拟制作各种网络报文了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP