Mac OS X Kernel Patches
formerly MAC Spoofing on the Mac

table of contents


An essential component of penetration testing and network wargames is the ability to specify arbitrary MAC addresses. This ability is also required for the implementation of certain kind of protective security functionality such as proxy ARP, in conjunction with tools such as arpcatch. It's my understanding that ARP spoofing is even being used in some experimental intrusion detection technologies.

Note that this patch is not a tool in and of itself; it merely extends other tools and APIs, and actually requires some knowledge to use. (Read: spare me your accusations of feeding the skript kiddies until you know what you're talking about.)

Like other BSD-derived codebases, Mac OS X and Darwin kernels like to meticulously stick the hardware address into the source field of each ethernet header. The following Darwin / Mac OS X kernel patch removes that tendency for AF_UNSPEC packets, allowing injected packets to forge that field in the header.

Also supplied below are a RAW4ALL patch, so you don't always have to be root to use raw sockets, and a FORCE_VERBOSE patch to force verbose output at boot time without having to press Option-V. Note that the FORCE_VERBOSE patch is not necessary with some Apple-supplied tarballs and CVS checkouts.

In recent days, Jeff Nathan has put together a less kludgey patch that fixes all the known issues; this is linked to below. These patches have been tested and verified with up to OS X 10.3 (Darwin 7.x) and verified to allow MAC spoofing with ethernet cards as well as wireless cards.

OS X 10.4.x (Darwin 8.x) kernel sources appear to require no modification in order to spoof MAC addresses.


Building a Darwin kernel is a little different than building one in Open, Free, or NetBSD, so I've included brief directions. If you're a seasoned Darwin user or developer, you likely have all the tools ready to go to build xnu, the source tree for the Darwin kernel. If so, skip ahead to step 5. However, if you've just installed Mac OS X, you likely don't have everything you need to compile kernels, and there are a few steps to go through:
  1. Grab and install the developer tools from Apple's developer site if you haven't already.
  2. make and make install relpath from the bootstrap_cmds project.
  3. make and make install the Libstreams project.
  4. Unpack the cctools project,
  5. [Mac OS X 10.3 / Darwin 7.x and above] Build kextsymboltool from the kext_tools project and install in /usr/local/bin. You will need to pull in headers from the IOKitUser project and cctools.
  6. Build the xnu project with the patches of your choice below, the proper options in bsd/conf/MASTER, and the directions in the README supplied by Apple in the xnu tarball. Install your new kernel at /mach_kernel. It goes without saying that you should back up your old one first.
  7. Reboot your box.
I've encountered or heard about a variety of very different compile-time problems, depending on the version of the operating system and the developer tools you're using; if this is the case, try fiddling around with gcc_select.

The directions above, by the way, are intentionally not very thorough. I've tried to write these directions for those who will be able to make use of this patch. In other words, if you can't navigate through the directions above, you probably shouldn't be messing with this patch. Either way, please use it responsibly.

source diffs

Even if you are using CVS, one of the patches above will likely work with your kernel source tree.

I have decided that these source patches are trivial enough that they do not require integrity hashes. However, please review what you download before applying them to your source tree.

Also, I'm pretty sure all these source patches are all subject to the Apple Public Source License.

known issues

Jeff Nathan's patch should fix all the known issues with the original ETHERSPOOF patch. Do not use his patch with any of the ETHERSPOOF patches above. They are incompatible, and his patch is better.

Patches called "ETHERSPOOF" above break the DHCP client thanks to the funky DLILization of the kernel, and though I have yet to see them cause problems getting an address personally, I have received reports and seen the cause of the problem, empty source ethernet address fields in the header.



contact info

this page compiled by
peter bartoli (
pgp key)
and last updated 11/5/2009