Raising wifi security awareness using wifi-probe.py

I wrote a small python script used in a demonstration aimed at raising wifi security awareness amongst campus visitors. The script displays SSIDs sent out from the phones or other devices of people passing by. I found this script to be an useful eye catcher in awareness campaigns.

It leverages the scapy framework and is pretty easy to setup. A wireless card in monitor mode is basically all you need to get started.

Computer running wifi-probe.py

This is what it looks like when you speed things up a bit:

wifi-probe.py in action

I recommend using it together with other demonstrations, e.g. a simple tcpdump and driftnet to show the benefit of encrypted HTTPS connections.

Wifi security awareness demonstration

You can grab a copy of wifi-probe.py at github.

Running multiple instances of unbound daemon on OpenBSD

Here is my latest OpenBSD endeavor: Running multiple instances of the same daemon using different configuration files for each instance.

For the sixfw IPv6 firewall project we need multiple instances of the unbound resolver. We use address family translation (NAT64) for traffic passing some interfaces. For true v6-only networks and for the router itself, we don’t (or just can not) use address family translation. Therefore we need one resolver that does expose 64:ff9b::/96-based DNS RRs for some interfaces, and a second one that refrains from using its DNS64 superpowers at all.

Our policy here at sixfw is to stay as close to OpenBSD and its best current practices as possible. Here is how we dealt with the problem:

Make sure you have both config files ready, one for each instance.

# ls /var/unbound/etc/
unbound.conf    unbound64.conf

Now create a copy of the original daemon’s rc script. Avoid dashes in the name, underscores seem to be fine, though.

# cp /etc/rc.d/unbound /etc/rc.d/unbound64

Add a _flags variable for the new instance in /etc/rc.conf.local. It is important to define a separate config file for each instance.

unbound_flags="-c /var/unbound/etc/unbound.conf"
unbound64_flags="-c /var/unbound/etc/unbound64.conf"

Now both instances are ready to be fired up.

# /etc/rc.d/unbound start
unbound(ok)
# /etc/rc.d/unbound64 start
unbound64(ok)

If you like to have the instances auto-started each time the system boots, enable them using rcctl:

# rcctl enable unbound   
# rcctl enable unbound64

In our case we additionally wanted to check if DNS64 is working as expected. Choose a hostname that is known to not have a AAAA RR, e.g. hosts of organizations that still think the Internet is Neuland. Now query the first instance for the RR:

# host bundesregierung.de ::1
bundesregierung.de has address 46.243.126.120

And the second instance, configured to use DNS64:

# host bundesregierung.de 2001:67c:26f4:a100::1
bundesregierung.de has IPv6 address 64:ff9b::2ef3:7e78
bundesregierung.de has address 46.243.126.120

Voilà!

Double Dice Crypto

I heard you like double dice crypto to solve a mystery? Feel free to use my quickly hacked python script below or entrust your data to a third party.

Hint You can automate the process much better if you work locally 😏

#!/usr/bin/env python3

print("Roll the dice, Santa!")

def encrypt(plain, key):
    cipher = list(key)
    for i in range(len(cipher)):
        cipher[i] += str(i)
    for i in range(len(plain)):
        cipher[i % len(key)] += plain[i]
    cipher = sorted(cipher)
    for i in range(len(cipher)):
        cipher[i] = cipher[i][2:]
    return "".join(str(e) for e in cipher)

def decrypt(cipher, key):
    rkey = sorted(key)
    plain = []
    ret = ""
    for i in range(len(key)):
        plain.append({ "pos": rkey.index(key[i]),
                       "len": len(cipher) // len(key),
                       "txt": "" })
        rkey[rkey.index(key[i])] = ' '
    for i in range(len(cipher) % len(key)):
        plain[i]["len"] += 1
    j = 0
    for i in range(len(key)):
        for p in plain:
            if p["pos"] == i:
                break
        while len(p["txt"]) < p["len"]:
            p["txt"] += cipher[j]
            j += 1
    i = 0
    while i < len(cipher):
        ret += plain[i % len(key)]["txt"][i // len(key)]
        i += 1
    return ret

# PoC
# Example from http://public.hochschule-trier.de/~wambacht/webseite2/

cipher="NRSGSESAIEOZRABINADIILURTNDEHXUSRHEVIEEPAEHEEGTLZFTLIANMEL"
key1="NOTEBOOK"
key2="DECKEL"

print(decrypt(decrypt(cipher, key2), key1))