module_udp_dns.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. /*
  2. ZMap Copyright 2013 Regents of the University of Michigan
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  7. */
  8. /* send module for performing massive UDP DNS OpenResolver scans
  9. * default will send type A query with Recursion Desired for www.google.com
  10. * SUCCESS only for response msg with noerr response code */
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <stdint.h>
  14. #include <unistd.h>
  15. #include <string.h>
  16. #include <assert.h>
  17. #include "../../lib/includes.h"
  18. #include "../../lib/random.h"
  19. #include "probe_modules.h"
  20. #include "packet.h"
  21. #include "logger.h"
  22. #include "module_udp_dns.h"
  23. #include "module_udp.h"
  24. #define MAX_UDP_PAYLOAD_LEN 1472
  25. #define UNUSED __attribute__((unused))
  26. #define DNS_HEAD_LEN 12
  27. #define DNS_TAIL_LEN 4
  28. static char *udp_send_msg = NULL;
  29. static int udp_send_msg_len = 0;
  30. // std query recursive for www.google.com type A
  31. // HEADER 12 bytes
  32. // \xb0\x0b -> TransactionID
  33. // \x01\x00 -> Flags: 0x0100 Standard query - Recursion desired
  34. // \x00\x01 -> Questions: 1
  35. // \x00\x00 -> Answer RRs: 0
  36. // \x00\x00 -> Authority RRs: 0
  37. // \x00\x00 -> Additional RRs: 0
  38. // DOMAIN NAME 16 bytes
  39. // default will be replaced by passed in argument
  40. // \x03\x77\x77\x77\x06\x67\x6f\x6f\x67\x6c\x65\x03\x63\x6f\x6d\x00 -> www.google.com
  41. // TAILER 4 bytes
  42. // \x00\x01 -> Type: A (Host address)
  43. // \x00\x01 -> Class: IN (0x0001)
  44. static const char udp_dns_msg_default[32] = "\xb0\x0b\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x77\x77\x77\x06\x67\x6f\x6f\x67\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01";
  45. static const char udp_dns_msg_default_head[DNS_HEAD_LEN] = "\xb0\x0b\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00";
  46. // static const char udp_dns_msg_default_name [16] = "\x03\x77\x77\x77\x06\x67\x6f\x6f\x67\x6c\x65\x03\x63\x6f\x6d\x00";
  47. static const char udp_dns_msg_default_tail[DNS_TAIL_LEN] = "\x00\x01\x00\x01";
  48. // google packet from wireshark
  49. // static const char udp_dns_msg_default[36] = "\xf5\x07\x00\x35\x00\x24\x04\x51\x10\xf5\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x06\x67\x6f\x6f\x67\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01";
  50. /* defined in module_udp.c
  51. const char *udp_unreach_strings[] */
  52. const char *udp_dns_response_strings[] = {
  53. "DNS no error",
  54. "DNS format error",
  55. "DNS server failure",
  56. "DNS domain name error",
  57. "DNS query type not implemented",
  58. "DNS query refused",
  59. "DNS Reserved 6",
  60. "DNS Reserved 7",
  61. "DNS Reserved 8",
  62. "DNS Reserved 9",
  63. "DNS Reserved 10",
  64. "DNS Reserved 11",
  65. "DNS Resevered 12",
  66. "DNS Resevered 13",
  67. "DNS Resevered 14",
  68. "DNS Resevered 15"
  69. };
  70. probe_module_t module_udp_dns;
  71. static int num_ports;
  72. //this will convert www.google.com to 3www6google3com
  73. void convert_to_dns_name_format(unsigned char* dns,unsigned char* host) {
  74. int lock = 0;
  75. strcat((char*)host,".");
  76. for(int i = 0; i < ((int) strlen((char*)host)); i++) {
  77. if(host[i]=='.') {
  78. *dns++=i-lock;
  79. for(;lock<i;lock++) {
  80. *dns++=host[lock];
  81. }
  82. lock++;
  83. }
  84. }
  85. *dns++ = '\0';
  86. }
  87. // allocates and returns a string representation of a hexadecimal IP
  88. // hexadecimal ip must be passed in network byte order
  89. char* hex_to_ip(void* hex_ip) {
  90. if(!hex_ip){
  91. return NULL;
  92. }
  93. char* addrstr = malloc(INET_ADDRSTRLEN);
  94. if(addrstr == NULL){
  95. exit(1);
  96. }
  97. //fprintf(stderr, "hex_ip %s\n", (char*)hex_ip);
  98. //memcpy(addrstr, hex_ip, sizeof(&hex_ip));
  99. if(inet_ntop(AF_INET, (struct sockaddr_in *)hex_ip, addrstr, INET_ADDRSTRLEN) == NULL){
  100. free(addrstr);
  101. return NULL;
  102. }
  103. return addrstr;
  104. }
  105. char* parse_dns_ip_results(struct dnshdr* dns_hdr) {
  106. (void) dns_hdr;
  107. return strdup(""); // This is why we don't accept pull requests
  108. #if 0
  109. // parse through dns_query since it can be of variable length
  110. char* dns_ans_start = (char *) (&dns_hdr[1]);
  111. while (*dns_ans_start++); // <---- SERIOUSLY FUCK THAT
  112. // skip qtype and qclass octets
  113. dns_ans_start += 4;
  114. // number of answers * 16 chars each (each followed by space or null, and quotes)
  115. size_t size = ntohs(dns_hdr->ancount)*INET_ADDRSTRLEN+2;
  116. char* ip_addrs = malloc(size);
  117. // should always be 4 for ipv4 addrs, but include in case of unexpected response
  118. //uint16_t prev_data_len = 4;
  119. int output_pos = 0;
  120. if(ntohs(dns_hdr->ancount) > 1000){
  121. return NULL;
  122. }
  123. for (int i = 0; i < ntohs(dns_hdr->ancount); i++) {
  124. //dnsans* dns_ans = (dnsans *) ((char*) dns_ans_start + (12 + prev_data_len)*i);
  125. dnsans* dns_ans = (dnsans *) ((char*) dns_ans_start + (12)*i);
  126. if(!dns_ans->addr){
  127. //prev_data_len = ntohs(dns_ans->length);
  128. continue;
  129. }
  130. char* ip_addr = hex_to_ip(&dns_ans->addr);
  131. if (!ip_addr) {
  132. //prev_data_len = ntohs(dns_ans->length);
  133. continue;
  134. }
  135. output_pos += i == 0 ? sprintf(ip_addrs + output_pos, "\"%s", ip_addr) : sprintf(ip_addrs + output_pos, " %s", ip_addr);
  136. //prev_data_len = ntohs(dns_ans->length);
  137. }
  138. if (output_pos) {
  139. sprintf(ip_addrs + output_pos, "\"");
  140. }
  141. return ip_addrs;
  142. #endif
  143. }
  144. static int udp_dns_global_initialize(struct state_conf *conf) {
  145. char *args, *c;
  146. int dns_domain_len;
  147. unsigned char* dns_domain;
  148. num_ports = conf->source_port_last - conf->source_port_first + 1;
  149. udp_set_num_ports(num_ports);
  150. udp_send_msg_len = sizeof(udp_dns_msg_default);
  151. udp_send_msg = malloc(udp_send_msg_len);
  152. memcpy(udp_send_msg, udp_dns_msg_default, udp_send_msg_len);
  153. if (!(conf->probe_args && strlen(conf->probe_args) > 0))
  154. return(0);
  155. args = strdup(conf->probe_args);
  156. if (! args) exit(1);
  157. c = strchr(args, ':');
  158. if (!c) {
  159. free(args);
  160. free(udp_send_msg);
  161. log_fatal("udp_dns", "unknown UDP DNS probe specification (expected "
  162. "domain name with name:www.domain.com)");
  163. exit(1);
  164. }
  165. *c++ = 0;
  166. if (strcmp(args, "name") == 0) {
  167. free(udp_send_msg);
  168. // prepare domain name
  169. dns_domain_len=strlen(c)+2; // head 1 byte + null terminator
  170. dns_domain = malloc(dns_domain_len);
  171. convert_to_dns_name_format(dns_domain, (unsigned char*)c);
  172. udp_send_msg_len=dns_domain_len + DNS_HEAD_LEN + DNS_TAIL_LEN; // domain length + header + tailer
  173. udp_send_msg = malloc(udp_send_msg_len);
  174. // create query packet
  175. memcpy(udp_send_msg, udp_dns_msg_default_head, sizeof(udp_dns_msg_default_head)); // header
  176. // random Transaction ID
  177. random_bytes(udp_send_msg, 2);
  178. memcpy(udp_send_msg + sizeof(udp_dns_msg_default_head), dns_domain, dns_domain_len); // domain
  179. memcpy(udp_send_msg + sizeof(udp_dns_msg_default_head) + dns_domain_len, udp_dns_msg_default_tail, sizeof(udp_dns_msg_default_tail)); // trailer
  180. free(dns_domain);
  181. } else {
  182. log_fatal("udp_dns", "unknown UDP DNS probe specification (expected "
  183. "domain name with name:www.domain.com)");
  184. free(udp_send_msg);
  185. free(args);
  186. exit(1);
  187. }
  188. if (udp_send_msg_len > MAX_UDP_PAYLOAD_LEN) {
  189. log_warn("udp_dns", "warning: reducing UDP payload to %d "
  190. "bytes (from %d) to fit on the wire\n",
  191. MAX_UDP_PAYLOAD_LEN, udp_send_msg_len);
  192. udp_send_msg_len = MAX_UDP_PAYLOAD_LEN;
  193. }
  194. free(args);
  195. return EXIT_SUCCESS;
  196. }
  197. int udp_dns_global_cleanup(__attribute__((unused)) struct state_conf *zconf,
  198. __attribute__((unused)) struct state_send *zsend,
  199. __attribute__((unused)) struct state_recv *zrecv) {
  200. if (udp_send_msg) {
  201. free(udp_send_msg);
  202. }
  203. udp_send_msg = NULL;
  204. return EXIT_SUCCESS;
  205. }
  206. int udp_dns_init_perthread(void* buf, macaddr_t *src,
  207. macaddr_t *gw, __attribute__((unused)) port_h_t dst_port,
  208. __attribute__((unused)) void **arg_ptr) {
  209. memset(buf, 0, MAX_PACKET_SIZE);
  210. struct ether_header *eth_header = (struct ether_header *) buf;
  211. make_eth_header(eth_header, src, gw);
  212. struct ip *ip_header = (struct ip*)(&eth_header[1]);
  213. uint16_t len = htons(sizeof(struct ip) + sizeof(struct udphdr) + udp_send_msg_len);
  214. make_ip_header(ip_header, IPPROTO_UDP, len);
  215. struct udphdr *udp_header = (struct udphdr*)(&ip_header[1]);
  216. len = sizeof(struct udphdr) + udp_send_msg_len;
  217. make_udp_header(udp_header, zconf.target_port, len);
  218. char* payload = (char*)(&udp_header[1]);
  219. module_udp_dns.packet_length = sizeof(struct ether_header) + sizeof(struct ip)
  220. + sizeof(struct udphdr) + udp_send_msg_len;
  221. assert(module_udp_dns.packet_length <= MAX_PACKET_SIZE);
  222. memcpy(payload, udp_send_msg, udp_send_msg_len);
  223. return EXIT_SUCCESS;
  224. }
  225. int udp_dns_make_packet(void *buf, ipaddr_n_t src_ip, ipaddr_n_t dst_ip,
  226. uint32_t *validation, int probe_num, __attribute__((unused)) void *arg) {
  227. struct ether_header *eth_header = (struct ether_header *) buf;
  228. struct ip *ip_header = (struct ip*) (&eth_header[1]);
  229. struct udphdr *udp_header= (struct udphdr *) &ip_header[1];
  230. ip_header->ip_src.s_addr = src_ip;
  231. ip_header->ip_dst.s_addr = dst_ip;
  232. udp_header->uh_sport = htons(get_src_port(num_ports, probe_num,
  233. validation));
  234. ip_header->ip_sum = 0;
  235. ip_header->ip_sum = zmap_ip_checksum((unsigned short *) ip_header);
  236. return EXIT_SUCCESS;
  237. }
  238. void udp_dns_print_packet(FILE *fp, void* packet) {
  239. struct ether_header *ethh = (struct ether_header *) packet;
  240. struct ip *iph = (struct ip *) &ethh[1];
  241. struct udphdr *udph = (struct udphdr*) (iph + 4*iph->ip_hl);
  242. fprintf(fp, "udp_dns { source: %u | dest: %u | checksum: %#04X }\n",
  243. ntohs(udph->uh_sport),
  244. ntohs(udph->uh_dport),
  245. ntohs(udph->uh_sum));
  246. fprintf_ip_header(fp, iph);
  247. fprintf_eth_header(fp, ethh);
  248. fprintf(fp, "------------------------------------------------------\n");
  249. }
  250. int udp_dns_validate_packet(const struct ip *ip_hdr, uint32_t len,
  251. uint32_t *src_ip, uint32_t *validation)
  252. {
  253. if (!udp_validate_packet(ip_hdr, len, src_ip, validation)) {
  254. return 0;
  255. }
  256. if (ip_hdr->ip_p == IPPROTO_UDP) {
  257. struct udphdr *udp = (struct udphdr *) ((char *) ip_hdr + ip_hdr->ip_hl * 4);
  258. uint16_t sport = ntohs(udp->uh_sport);
  259. if (sport != zconf.target_port) {
  260. return 0;
  261. }
  262. }
  263. return 1;
  264. }
  265. void udp_dns_process_packet(const u_char *packet, UNUSED uint32_t len, fieldset_t *fs) {
  266. struct ip *ip_hdr = (struct ip *) &packet[sizeof(struct ether_header)];
  267. if (ip_hdr->ip_p == IPPROTO_UDP) {
  268. struct udphdr *udp_hdr = (struct udphdr *) ((char *) ip_hdr + ip_hdr->ip_hl * 4);
  269. struct dnshdr *dns_hdr = (struct dnshdr *) (&udp_hdr[1]);
  270. fs_add_string(fs, "classification", (char*) "udp_dns", 0);
  271. // success is 1 if application level success
  272. // response pkt is an answer and response code is no error
  273. uint16_t qr = dns_hdr->qr;
  274. uint16_t rcode = dns_hdr->rcode;
  275. fs_add_uint64(fs, "success", (qr == DNS_QR_ANSWER) && (rcode == DNS_RCODE_NOERR));
  276. fs_add_uint64(fs, "sport", ntohs(udp_hdr->uh_sport));
  277. fs_add_uint64(fs, "dport", ntohs(udp_hdr->uh_dport));
  278. fs_add_null(fs, "icmp_responder");
  279. fs_add_null(fs, "icmp_type");
  280. fs_add_null(fs, "icmp_code");
  281. fs_add_null(fs, "icmp_unreach_str");
  282. fs_add_string(fs, "app_response_str", (char *) udp_dns_response_strings[rcode], 0);
  283. fs_add_uint64(fs, "app_response_code", rcode);
  284. fs_add_uint64(fs, "udp_pkt_size", ntohs(udp_hdr->uh_ulen));
  285. if(ntohs(udp_hdr->uh_ulen) == 0){
  286. fs_add_null(fs, "data");
  287. }else{
  288. fs_add_binary(fs, "data", (ntohs(udp_hdr->uh_ulen) - sizeof(struct udphdr)), (void*) &udp_hdr[1], 0);
  289. }
  290. /*
  291. char* ip_addrs = parse_dns_ip_results(dns_hdr);
  292. if (!ip_addrs){
  293. fs_add_null(fs, "addrs");
  294. } else {
  295. fs_add_string(fs, "addrs", ip_addrs, 1);
  296. }
  297. */
  298. fs_add_null(fs, "addrs");
  299. } else if (ip_hdr->ip_p == IPPROTO_ICMP) {
  300. struct icmp *icmp = (struct icmp *) ((char *) ip_hdr + ip_hdr->ip_hl * 4);
  301. struct ip *ip_inner = (struct ip *) &icmp[1];
  302. // ICMP unreachable comes from another server, set saddr to original dst
  303. fs_modify_string(fs, "saddr", make_ip_str(ip_inner->ip_dst.s_addr), 1);
  304. fs_add_string(fs, "classification", (char*) "icmp-unreach", 0);
  305. fs_add_uint64(fs, "success", 0);
  306. fs_add_null(fs, "sport");
  307. fs_add_null(fs, "dport");
  308. fs_add_string(fs, "icmp_responder", make_ip_str(ip_hdr->ip_src.s_addr), 1);
  309. fs_add_uint64(fs, "icmp_type", icmp->icmp_type);
  310. fs_add_uint64(fs, "icmp_code", icmp->icmp_code);
  311. if (icmp->icmp_code <= ICMP_UNREACH_PRECEDENCE_CUTOFF) {
  312. fs_add_string(fs, "icmp_unreach_str",
  313. (char *) udp_unreach_strings[icmp->icmp_code], 0);
  314. } else {
  315. fs_add_string(fs, "icmp_unreach_str", (char *) "unknown", 0);
  316. }
  317. fs_add_null(fs, "app_response_str");
  318. fs_add_null(fs, "app_response_code");
  319. fs_add_null(fs, "udp_pkt_size");
  320. fs_add_null(fs, "data");
  321. fs_add_null(fs, "addrs");
  322. } else {
  323. fs_add_string(fs, "classification", (char *) "other", 0);
  324. fs_add_uint64(fs, "success", 0);
  325. fs_add_null(fs, "sport");
  326. fs_add_null(fs, "dport");
  327. fs_add_null(fs, "icmp_responder");
  328. fs_add_null(fs, "icmp_type");
  329. fs_add_null(fs, "icmp_code");
  330. fs_add_null(fs, "icmp_unreach_str");
  331. fs_add_null(fs, "app_response_str");
  332. fs_add_null(fs, "app_response_code");
  333. fs_add_null(fs, "udp_pkt_size");
  334. fs_add_null(fs, "data");
  335. fs_add_null(fs, "addrs");
  336. }
  337. }
  338. static fielddef_t fields[] = {
  339. {.name = "classification", .type="string", .desc = "packet classification"},
  340. {.name = "success", .type="int", .desc = "is response considered success"},
  341. {.name = "sport", .type = "int", .desc = "UDP source port"},
  342. {.name = "dport", .type = "int", .desc = "UDP destination port"},
  343. {.name = "icmp_responder", .type = "string", .desc = "Source IP of ICMP_UNREACH message"},
  344. {.name = "icmp_type", .type = "int", .desc = "icmp message type"},
  345. {.name = "icmp_code", .type = "int", .desc = "icmp message sub type code"},
  346. {.name = "icmp_unreach_str", .type = "string", .desc = "for icmp_unreach responses, the string version of icmp_code (e.g. network-unreach)"},
  347. {.name = "app_response_str", .type = "string", .desc = "for DNS responses, the response code meaning of dns answer pkt"},
  348. {.name = "app_response_code", .type = "int", .desc = "for DNS responses, the RCODE of dns answer pkt"},
  349. {.name = "udp_pkt_size", .type="int", .desc = "UDP packet lenght"},
  350. {.name = "data", .type="binary", .desc = "UDP payload"},
  351. {.name = "addrs", .type="string", .desc = "DNS answers"}
  352. };
  353. probe_module_t module_udp_dns = {
  354. .name = "dns",
  355. .packet_length = 1,
  356. .pcap_filter = "udp || icmp",
  357. .pcap_snaplen = 1500, // TO BE CHANGED FOR EXSTIMATE REFLECTION SIZE
  358. .port_args = 1,
  359. .thread_initialize = &udp_dns_init_perthread,
  360. .global_initialize = &udp_dns_global_initialize,
  361. .make_packet = &udp_dns_make_packet,
  362. .print_packet = &udp_dns_print_packet,
  363. .validate_packet = &udp_dns_validate_packet,
  364. .process_packet = &udp_dns_process_packet,
  365. .close = &udp_dns_global_cleanup,
  366. .fields = fields,
  367. .numfields = sizeof(fields)/sizeof(fields[0])
  368. };