As you can tell, I'm back from my month long vacation. It was great! I visited family in India and made my way to several awesome places and also visited Katy in Nepal, pictures to be posted later when I sort through all 1,000 of them!

Anyway, thought I'd kick off blogging again with some fun tricks. If you read the MS Exchange Team blog, you would have spotted the article on The Secret Decoder Ring. Long story short, the default admin group and routing group in Exchange 2007 are named quite oddly:

Exchange Administrative Group (FYDIBOHF23SPDLT)
Exchange Routing Group (DWBGZMFD01QNBJR)

I actually didn't know what they meant either... only a few people on the team knew. During a presentation by a fellow PM on the team on the subject, I decided to solve the puzzle using PowerShell. Here is how I got started.

#1. Assume the letters are the results of a cipher

In all ciphers, there is a generating function, so the goal is to guess the generating function. If you can guess the generating function, you can work backwards and construct the original message.

#2. Use PowerShell to examine each letter

We want to look at each letter in a sequence. There are several ways of doing this:

Boring standard way:

$str = "FYDIBOHF23SPDLT" 
for($i =0; $i -lt $str.Length; $i++) { $str[$i] }

Cool powershell way. First examine what is available for you to use using get-member or gm:

"FYDIBOHF23SPDLT" | gm

You'll see that Strings have an interesting method:

GetEnumerator Method System.CharEnumerator GetEnumerator()

You see that it returns a CharEnumerator. What does this do?  Best way to find out is to try it out:

PS> "Test".GetEnumerator()
T
e
s
t

As you can see, each character in the string is returned immediately as a seperate entity. Useful.

#3. Now that we know how to get to each letter in the coded message, its time to guess the generating function. We know that each letter represents an actual value, so it should be straightforward to automate "guessing" the function. From past experience I knew that text ciphers are generally based on a either a rotation scheme (each letter in a code represents another letter). So the best place to start is to write a script that takes the string and then strong arms the rotation (i.e. runs the text through different rotations):

"FYDIBOHF23SPDLT".getenumerator() | % { [char]([int]$_- 20 } 

What is the above doing? Let me explain what's going on. The result of the call to GetEnumerator() returns characters, which are then passed to a foreach that basically rotates that letter by a given number (in this example it rotates each letter by 20). But that actually returns another list of characters, which is a little annoying. That's not the main problem, its still not automatable, but at least if we had pure human labor and this was a real code to crack, we could throw humans at the problem by letting them guess arbitrary numbers. The real world code crackers, however, rely on automation.

Another explanation of what [Char] [int] does. Each letter returned is a "char" which in technical lingo is a special type representing a readable or non-readable character (like "L"). Well we need to be able to operate on this as a number for our code cracking, so we need to cast it to a number or integer. This is done by applying [int] to the value we want to covert. In PowerShell all literals are either string or nums at the end of the day, so you have to be careful of this trick. For example:

[int]'f'

fails but:

[int][char]'f'

works. Can you figure out why? Anyway, back to the exercise, in our case remember that GetEnumerator() returns a CharEnumerator, which coincidentally is a char, so we just need to cast the current letter coming through the pipeline to a [int] and then operate on it, in our case rotating negatively (subtracting) the current char by the given rotation amount. For example: Rot = 1, letter = B, code = A. This is because if you walk back from B by one letter you get A.

#4. Automate the function to walk through a huge list of rotatations. Step #3 gave us a way to apply a rotation

filter guesser
{
  $rot = $_ 
  "FYDIBOHF23SPDLT".getenumerator() | % { [char]([int]$_- $rot }  | &{
    process 
    {
      $local:s += $_ 
    }
    end
    {
      $s 
    } 
  }
}

This looks complicated but really what its doing is defining a function that takes numbers and then applies those numbers as rotations to the code. So for example, this works:

PS> 1..5 | guesser
EXCHANGE12ROCKS
DWBG@MFD01QNBJR
CVAF?LEC/0PMAIQ
BU@E>KDB./OL@HP
AT?D=JCA-.NK?GO

And whoala, there's our secret right there. Looks like the code was using 1 as a rotation :)

To impress your friends (or scare away the ladies), knowing that the rotation is 1, in the future you could just do this:

"FYDIBOHF23SPDLT".getenumerator() | % { [char]([int]$_- 1 } 

But wait, what about the other message DWBGZMFD01QNBJR? You'll find that 1..200 doesn't yield anything useful. But you should be able to figure that out without changing any of the functions above. Its a nice PowerShell trick that I will leave as an exercise.