Yearly Archives: 2016

MAC Randomizer Alfred Script

December 19, 2016 » Geek

A recent conversation I had dealt with free wifi that limited the amount of time you could use it before it kicked you off. Now, while I support the right of wifi providers to do as they please, it’s an interesting question. AFAIK most tracking of that sort is done based on MAC addresses, which you can easily spoof if you want.

I wrote up a quick Alfred workflow that shells out from Python to do the real work. Note that if your wifi interface isn’t called en0 this won’t work for you.

Workflow Overview

The first script shells out to ifconfig to get the current address. Which gives output like the following. We are interested in that ether f4:5c:89:b3:37:e1 line. The first three octets are of a MAC are the Organizationally Unique Identifier (OUI) and we don’t need to change those, what we have is valid already.

en0: flags=8863 mtu 1500
	ether f4:5c:89:b3:37:e1
	inet6 fe80::8da:f24a:a0bb:3b7a%en0 prefixlen 64 secured scopeid 0x4
	inet netmask 0xffffff00 broadcast
	nd6 options=201
	media: autoselect
	status: active

Our script captures the OUI, then generates three more octets for the rest of the address, and prints it out.

from subprocess import check_output
from re import compile
from random import randint

MATCHER = compile("\W*ether ([a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2})")
output = check_output(["ifconfig", "en0"])

mac = None

for line in output.split("\n"):
    match = MATCHER.match(line)
    if match is not None:
        mac = match.groups()[0]

prefix = mac[:8]

print "%s:%x:%x:%x" % (prefix, randint(0, 255), randint(0, 255), randint(0, 255))

Next we need to actually set this new random MAC. This is a privileged operation, so it we passed it directly to ifconfig it would error out. Long story short, if we want a nice authorization dialog we have to pass through applescript, russian nesting doll style.

osascript -e  "do shell script \"sudo ifconfig en0 ether {query} >/dev/null;\" with administrator privileges"

I also added a way to reset it to the hardware value. The networksetup command handily has that for the taking. We just shell out, capture it and pass it through to ifconfig again.

from subprocess import check_output
from re import compile

MATCHER = compile("Ethernet Address: ([a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2})")
output = check_output(["networksetup", "-getmacaddress", "en0"])
match = MATCHER.match(output)
print match.groups()[0]

You can download this workflow, comments and improvements appreciated.

Anonymous Code of Conduct Reporting With Twilio

August 29, 2016 » Geek

I’m lucky to be one of the organizers of NEJS Conf, a great little JavaScript & frontend conference here in Omaha, NE.

One of the core values we’ve held since the beginning of our conference was for it to be diverse, respectful and safe. To that end we adopted a Code of Conduct from the very beginning, based on the excellent JSConf example.

Our first year, we identified specific volunteers as our CoC points of contact. It seemed like a good plan, but our only report that year came via a circuitous route, which may have been a result of the face-to-face reporting we had defaulted to.

This spring I got to attend Twilio’s SIGNAL conference, and one neat thing they had in their Code of Conduct was an anonymous reporting phone line. Sounds like a good idea, and something fun to build!

The plan is simple: add a Twilio backed phone number which anonymizes incoming SMS and calls, then forwards them to the code of conduct reporting volunteer. Twilio makes this easy. At it’s core it’s just two TwiML files, one for SMS and one for Voice.

The SMS response contains the original message, a destination number to send it to (i.e. the CoC volunteer), a unique ID per reporter, and a link to the web interface. Behind the scenes we are doing a little but of work to assign the ID, match up numbers to destinations, etc, but not a lot of work total.

<?xml version="1.0" encoding="UTF-8" ?>
  <Message to="{{ destination_number }}">[{{ reporter_id }}] {{ message_body }}

{{ link }}</Message>

Voice is even simpler. Here we just connect the call to the CoC volunteer, and spoof the caller ID with the hotline’s number.

<?xml version="1.0" encoding="UTF-8"?>
  <Say>Connecting, one moment.</Say>
  <Dial record="true" callerId="{{ caller_id }}">{{ number.destination }}</Dial>

That’s the core of it, only took an evening to get things running. As I hinted above, I added a web interface for replying to reporters, as well as seeing the entire interaction in one place.

SMS Reporting Web Interface Voice Reporting

If you’d like to run this for your event, the source is all on github.

Tags: , , ,