Friday, April 23, 2010

Paranoid

So, I was reading this over on Slashdot this morning, and it got me paranoid. Okay, it didn't really (maybe). But it reminded me that I've wanted an easy way to randomize my MAC address (mostly for fun, so I can pretend that I'm some kind of super-hacker; honestly, no one is interested in tracking my repeated visits to Lambda the Ultimate) for a while.

It should be fairly clear by now that I prefer to write things myself, rather than use an existing tool (as long as I have time, and I can learn something in the process, and it's not too annoying - give me a god damn break, I'm human).

So, I hacked up a MAC address randomizer in Python in a few minutes. It's pretty gross, hard coding stuff everywhere. But I figured somebody might like it for reference (of how not to code, perhaps). Important note: you must run this as an administrator!

import winreg
import random
import os

# This is the name of the interface we want to change.  This can be
# found using "netsh interface show interface", which will list the names
# of all of your interfaces.
INTERFACE_NAME = "Wireless Network Connection"

# This is the registry key holding the item's address.  Unfortunately it has
# a funny name, not based on the INTERFACE_NAME above; we could probably locate
# this from the INTERFACE_NAME somehow, but this was faster.  You will probably
# have several keys of the form '...\0001', '...\0002', etc.  Be sure to
# pick the right one!
KEY_NAME = r"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0011"
SUBKEY_NAME = "NetworkAddress"
ROOT = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "")

# For some reason Windows 7 requires that the first 2 hexadecimal digits be
# "12".  Also, crappy random number generation.
def generate():
    return ("12%02x%08x" %
      (random.randint(0, 255), random.randint(0, 4294967295)))

# As I couldn't easily find a quick way of enabling and disabling the interface
# using pure Python, so shell it is.
def enable():
    print("Enabling interface...")
    if os.system("netsh interface set interface name=\"%s\" admin=ENABLED"
      % INTERFACE_NAME):
        print("Error: unable to enable interface.")
    return
    
def disable():
    print("Disabling interface...")
    if os.system("netsh interface set interface name=\"%s\" admin=DISABLED"
      % INTERFACE_NAME):
        print("Error: unable to disable interface.")
    return
    
def main():
    try:
        # Here we open up the relevant key for reading and writing values.
        with winreg.OpenKey(ROOT, KEY_NAME, 0,
          winreg.KEY_SET_VALUE | winreg.KEY_QUERY_VALUE) as key:
        
            # No need for this, just for reference; newlines for symmetry.
            (oldMAC, type) = winreg.QueryValueEx(key, SUBKEY_NAME)
            print("Current MAC: %s\n" % oldMAC)
            
            # Make a new key and set it; you can check that it worked using
            # "ipconfig /all" and reading of the adapter's MAC afterwards.
            newMAC = generate()
            winreg.SetValueEx(key, SUBKEY_NAME, 0, winreg.REG_SZ, newMAC)
            winreg.CloseKey(key)
            print ("New MAC: %s\n" % newMAC)
            
            # Reset the interface so it catches our update.
            disable()
            enable()
            print("Done.")
            return 0

    except WindowsError as e:
        # Really bad error handling; if you get 'access denied' you aren't
        # administrator and if you get 'file not found' you probably have the
        # wrong KEY_NAME.
        print("Error: %s" % str(e))
        return -1

exit(main())

Enjoy.

PS - I should confess that all of the comments were added after the fact.

No comments:

Post a Comment