First off, let me clarify that this question refers to a private project that is intended for educational purpose only.
I tried to write my own "DNS spoofer". Don't worry, this question is not related to any coding practices.
The current setup
The operating machine is a MacBook (with OSX) in a local network (so there're some other unimportant devices as well). There's a basic router that uses another machine (also in the local network) as local DNS server. Although this setup is a little unusual, it should not be the cause of the issue (described below).
The goal
DNS Spoofing - when the MacBook sends a DNS request, send an answer with a fake IP address.
My current approach
I use BPF (Berkeley Packet Filter) to get raw access to the data link layer.
Now, I'm listening for/capturing any queries on the Ethernet network interface of the MacBook (referred to as "MB" in the following part).
I disabled IPv6 on the MB.
I delete the DNS cache on the MB with the following commands:
sudo killall -HUP mDNSResponder;sudo killall mDNSResponderHelper;sudo dscacheutil -flushcache
Procedure
- MB sends a DNS request with some queries
- I create a DNS response with the same queries and answers to all A-Type (IPv4) queries and send this response
- The MB receives two responses: my fake response first, then the real one sent by the real local DNS server
Each fake DNS response packet will include:
- the Ethernet MAC address of the requested DNS server as Ethernet source address
- the IP address of the requested DNS server as IP source address
- the port 53 as source port
- the port as destination port that the DNS request originated from
- a correct IP header checksum
- a correct UDP checksum
- a correct Frame Check Sequence/Ethernet Checksum.
Each DNS response is sent over the same network interface I'm listening on.
Whenever a query is sent, there'll be two responses:
- the first one sent immediately by the "DNS spoofer", the 'fake' packet/DNS response, arrives before the second
- the second one, the 'real' DNS response, sent by the local DNS server.
I also assumed (although I'm not sure about this) that OSX always picks the first DNS response it gets to resolve a domain name to its IP address.
To sum this up; both DNS responses are equal except that the checksums and the DNS answer IP addresses are different. Also, the 'real' DNS server does not send (for what reason ever) an FCS (Frame Check Sequence). I do, although it is not calculated and just set to zero (zeroed-out).
Issue
OSX seems to ignore the fake DNS responses. Might also be that the OS is overstrained; the behaviour when using Safari to open a Website is the following:
When using Safari and typing "http://some-url.com" into the address bar, nothing happens. It does not connect to the real site nor does it connect to the fake page. The page seems to load forever. Sometimes, after a decade, it connects to the real page.
Example (captured with Wireshark)
A random example.
Request:
0000 b8 27 eb b9 a0 0f a0 ce c8 10 75 8c 08 00 45 00
0010 00 33 74 2c 00 00 ff 11 62 06 c0 a8 b2 1f c0 a8 .3t,..ÿ.b.À¨².À¨
0020 b2 16 f2 7e 00 35 00 1f 49 71 67 00 01 00 00 01 ².ò~.5..Iqg.....
0030 00 00 00 00 00 00 01 32 03 63 6f 6d 00 00 01 00 .......2.com....
0040 01 .
Fake Response:
0000 a0 ce c8 10 75 8c b8 27 eb b9 a0 0f 08 00 45 00
0010 00 43 12 34 00 00 40 11 82 ef c0 a8 b2 16 c0 a8 .C.4..@..ïÀ¨².À¨
0020 b2 1f 00 35 f2 7e 00 2f 46 44 67 00 81 80 00 01 ²..5ò~./FDg.....
0030 00 01 00 00 00 00 01 32 03 63 6f 6d 00 00 01 00 .......2.com....
0040 01 c0 0c 00 01 00 01 00 00 07 08 00 04 ac d9 17 .À...........¬Ù.
0050 8e 22 4f 80 1c ."O..
Real Response:
0000 a0 ce c8 10 75 8c b8 27 eb b9 a0 0f 08 00 45 00
0010 00 7c 9c 19 40 00 40 11 b8 d0 c0 a8 b2 16 c0 a8 .|..@.@.¸ÐÀ¨².À¨
0020 b2 1f 00 35 f2 7e 00 68 83 00 67 00 81 83 00 01 ²..5ò~.h..g.....
0030 00 00 00 01 00 00 01 32 03 63 6f 6d 00 00 01 00 .......2.com....
0040 01 c0 0e 00 06 00 01 00 00 03 84 00 3d 01 61 0c .À..........=.a.
0050 67 74 6c 64 2d 73 65 72 76 65 72 73 03 6e 65 74 gtld-servers.net
0060 00 05 6e 73 74 6c 64 0c 76 65 72 69 73 69 67 6e ..nstld.verisign
0070 2d 67 72 73 c0 0e 5c 83 f7 73 00 00 07 08 00 00 -grsÀ.\.÷s......
0080 03 84 00 09 3a 80 00 01 51 80 ....:...Q.
Any help is highly appreciated. If you need more detail, let me know. If you'd like a bounty, let me know.
999.999.999.999
, "malicious", "Frame Check Sequence". etc... Try to cut out 80% of the content of your question, and focus on what your problem is, asking a single question if possible, and give examples.