Monday, December 12, 2016

IPv6 spoofing trickery

Tales of spoofing on BSD based kernels (actually Darwin).

Although OSX setups should mostly be targets of spoofed
packets, there are times when you need to spoof IPv6 packets
from a OSX box.
Unlike with IPv4, there is no such thing as a IP_HDRINCL
socket option that lets you pass arbitrary IP headers
to raw sockets. In fact, there are RFCs on the subject
(RFC3542 and RFC 3493) and the authors put a lot of effort
to specify on how certain flags and details may be modified,
but the end of the story is that, in this way or another,
its not possible to have a handy library function to
generically send a spoofed IPv6 packet on a raw socket on OSX.

man 4 ip6 says:
"Note: Since the checksum is always calculated by the kernel for an ICMPv6 socket, applications are not able to generate ICMPv6 packets with incorrect checksums (presumably for testing purposes) using this API."

I like the presumably for testing purposes part most.
So I had to eventually switch to packet sockets for
my UDP6 sample of libusi++. Its a bit more work to
set it up initially, but after that all the get/set
of source addresses etc. work as expected.

Thanks to the inject function of libpcap, thats easy
enough.Its probably not worth the effort to handle all the
socket options or ancillary data for raw IPv6 sockets just to 
achieve a goal that at the end still has some header-parts un-modifiable.
I did not test it on OpenBSD or FreeBSD, but the manpage
reads more or less the same, so I expect the same problem
exists there too.