Every year, the Shmoo Group runs an information security conference in Washington called ShmooCon. I’ve been going every year, and it’s both a fantastic con and a great deal. The conference in 2010 was memorable because it coincided with the worst snowstorm Washington’s had in decades.  It was also memorable for me as another victory in the badge puzzle contest.

ShmooCon 2010 Badge

ShmooCon 2010 Badge

Last year, my buddy Дурак (@gypak – more or less “Durak,” pronounced “doo-rock”) and I attacked the badge puzzle in parallel, working more-or-less independently but sharing progress, ideas, problems, etc. After a couple of weeks, he gave up, but I kept on for a few more days and ended up winning the contest (beating the next team by just over an hour). This year, Дурак and I worked as a team from the start, and again, were the first to solve the puzzle, landing us fabulous prizes and numerous bragging rights.

The badges this year were little round foam/rubber coasters. They featured a Moose head, “2010 Shmoocon,” and four sets of numbers.  These numbers were the puzzle, but they weren’t exclusively on badges: 5 other sets of numbers were hidden in plain sight elsewhere in the conference.

The numbers on my own badge were:

268 -28.09944 4995 140.196944

Since I have done a lot of Geocaching, I immediately recognized what we had: a Latitude / Longitude pair, and a bearing / range pair. This meant that I had to get a map, find 28.09944 S by 140.196944 E, and from that location move 268 degrees (almost due west) for 4995… for 4995… er… feet? Meters? Miles? It seemed unlikely that it would be miles or kilometers, as after too far the curvature of the Earth becomes significant and it’s difficult to project accurately. On the other hand, I’ve actually seen a cache that projected using centimeters, so it could really be just about anything.

We collected another couple of badges, got our laptops connected to the network, enjoyed the opening talks, and even visited with G. Mark Hardy (the creator of the puzzle) to say “Hi,” thank him for last year’s puzzle, and to collect a couple of punch cards for another challenge.  By the time the opening Keynote started, we had about four codes, including a code from the conference program.  Sitting in the keynote, I started plugging the numbers into Google Earth, and right away noticed that all the coordinates were on, or very near to, airports. Which fit very well with the con’s overall “Shmoo Airlines” theme.

I was also trying some projections for each badge, but didn’t see anything obvious – the points were all nearby the the airports (I was assuming feet for the time being), but just ended up in empty fields, parking lots, etc. I really wasn’t sure what I was looking for. Perhaps the angle between the bearing and the airports primary runway was significant (but then why would we need a range?) Perhaps the airports were linked based on runway orientations. You could leave airport A via the bearing on A’s badge, find an airport with its runway that matches that angle, and that’s the next one in the list. (at this point, all of the airports we’d seen had only a single runway).

About this time, the con shut down for the night, and we wandered down to Connecticut Avenue to try and find a restaurant that was open during the blizzard. (as an aside – everyone laughed at me for bringing a full-out mask and ski goggles, but only until their eyeglasses got completely coated with snow.)

That night, I spent some time looking up all the codes we’d had on my iPhone, trying to figure out what airports they are, and recording the airport code and runway orientation for each.  At this point, we have MOO, NEV, SEZ, YMI, SOY, and ZAZ. We’ve pretty much decided that the airport codes will spell out a ciphertext, and the challenge for the first stage would be to arrange them in the right order.

The next morning at breakfast, we read through all the hints (for some reason we’d missed those), but didn’t see anything that helped us much. There was one hint that implied we would have to shift one column of data upwards, but we weren’t too sure what that meant. Working theory: put all the data in the right order, stack up the airport codes, then shift one of the three columns of letters to get the final cipher text.

By now, we have all the data. Or, at least we think we do. In the early afternoon we go to a talk from G. Mark, and he confirms that there are six badges. We scoured his presentation for more hints, but didn’t get anything. Also, we tried to collect more of the punch card clues for his other puzzle. Eventually, we move on and start trying to link the codes together.

Bearing Latitude Range Longitude Source Airport Code
268 -28.09944 4995 140.196944 Badge MOO
114 17.205642 5251 -62.594003 Safety Brochure NEV
0 -4.674342 0 55.521839 Security Badge SEZ
42 49.971153 4584 -94.700518 Speaker Badge YMI
150 59.158051 2926 -2.641389 Badge SOY
313 41.663679 3698 -1.011665 Badge ZAZ

We start off trying to link the airports by distance. The bearing data help a little, but mostly those just confuse us, having a limited grasp of the geography of some of these airports and the whole concept of great circle routes. However, we did find a site that would calculate the distance between two airports. So we put all the airports into a grid and recorded the distance between all airport pairs. Pretty quickly we realized the distances on the badges were in nautical miles. But converting to miles didn’t quite work for us, because the site we were using was based in kilometers and their mile conversion was inaccurate. So we converted all the data to kilometers and built the grid that way.

(Though we worked in Kilometers, the grid reproduced here is left in nautical miles.)

NEV 5251 9380 3607 2502 3453 7092
MOO 4995 0 8392 8001 8748 4988
SOY 2926   0 2990 1052 4706
YMI 4584     0 3686 7693
ZAZ 3698       0 4147

As the grid filled out we were able to start making conclusive links by looking at the range for a given data point (4995 on my badge) and then finding which airport was that distance away. For example, from ZAZ the next airport is 3698 miles away. We look under the ZAZ column and across the ZAZ row, and find the number closest to that – and decide that YMI, at 3686 miles, is the closest match (only 12 miles off). Unfortunately, we can only make that link and MOO to SEZ – certainly not enough to generate the complete ciphertext.

After we’d gotten the grid built, someone (thinking back, it might actually have been G. Mark) pointed out the code on the program, giving us ERS. We felt more than a little stupid that we had missed it. It wouldn’t be the first time that our powers of observation would be lacking. We added ERS to our grid and decided it came after NEV.

Later in the afternoon they announced that one box of badges never got distributed. Which has us confused, since we were told there were six badges, and we had six badge codes. We’d thought that one of the badges duplicated the codes on the “safety card,” which seemed odd but for some reason we didn’t question it, even after being shown the code in the program. Stupid us.

Bearing Latitude Range Longitude Source Airport Code
345 -22.612239 3973 17.080442 Program ERS
118 -0.413773 6187 35.251589 Badge KEY

After exchanging one of our badges for a new one, we now had a total of eight data points: six actual badges (four for conference attendees, one for security, and one for speakers), plus data from the con program and safety card. But it still wasn’t enough. The last badge gave us KEY, which appeared to connect to MOO.

No matter what we try, we can’t make the last few links. We’re obviously missing some data, but we don’t know how much…probably at least three sets.

Just as we’re sitting down for the 5:00 talk there’s announcement that G. Mark will be answering questions at the registration desk. So we go there, ask a couple of questions, and try to listen to other people as they ask questions. While standing there, we notice the three huge schedule posters. Each of which has a code down the edge. Three more data points. Dammit! How could we have missed those?

Bearing Latitude Range Longitude Source Airport Code
122 29.95925 1281 81.33975 Schedule Board UST
166 40.137722 2473 26.426777 Schedule Board CKZ
301 13.266669 5572 19.716677 Schedule Board OUM

We quickly copy those down, trying not to look too obvious, then return to the lounge area to work with the new codes. Punch coordinates into Google Earth, figure out the airport or nearby city name, look it up on Wikipedia, get the airport code, add it to the grid, and calculate all the distances.

NEV: 5251 9380 3607 2502 3453 5247 5870 1280 4734 4697 7092
MOO: 4995 0 8392 8001 8748 6317 6166 8628 7377 7510 4988
SOY: 2926   0 2990 1052 5003 3992 3541 2928 1579 4706
YMI: 4584     0 3686 7260 6890 1346 5686 4569 7693
ZAZ: 3698       0 3986 3204 3830 2018 1242 4147
ERS: 3973         0 1714 6480 2158 3801 2474
KEY: 6187           0 6793 1245 2480 1226
UST: 1281             0 5562 4987 7927
OUM: 5572               0 1650 2389
CKZ: 2473               0 3130

We know what the last airport is, because that code had no follow-on bearing or range. So starting at the end, with SEZ, we construct the ciphertext backwards. What links to SEZ? MOO. What links to MOO? KEY. And so on, until we run out of data and I say “Okay, now we have a ciphertext.” Which is met with the response “It’s not a cipher!”

Rather than get too ahead of ourselves, I force myself not to look at Дурак’s notes, and convince him to run through the list again, forwards, just to be sure we have it correct. Then I look at what we have. Wow. No code. It’s a completed message, plain as day. But it gets all wonky in the middle. Something is still wrong.

We re-verify the numbers, re-check the airport codes, and try to imagine what we could have done wrong. Everything just fits too well – we can’t see where any missing data points could fit into what we have. And we’re so close!

Then, it hits us: scratch out the Zs. This:



So you must never say Mick-key Moose.

Success! At 6:00 on Saturday, we’ve solved the puzzle!

We close the laptops, send a tweet to G. Mark, and run off to find Heidi. She knows the answer, and pretty much confirms it right off, but she tries to call G. Mark anyway. Eventually we get him on the phone, and I let Дурак do the honors, and he relays the answer. Woot! The official public announcement happens via Twitter at 6:20 pm. The next team, we’re told later, came in about 12:30 the next afternoon.

I tell Heidi that we really did work as a team, but that if there’s to be only one prize awarded, I’m content to let it go to Дурак, and to let her decide whether I’d qualify as a runner-up or if we’d just let the next team claim that prize – “It’s your contest, however you want to handle it is fine with me.” They later decide to give us both joint credit, and we both win tickets to the next year’s con. We also get little stuffed moose head trophies to hang on the wall. Finally, G. Mark really surprises us by throwing in free airline flights, which we naturally redeem for tickets to DEFCON.

Moose Trophy

Moose Trophy

So how’d this year’s contest compare to last year’s? I liked it a lot better. For one, it was actually solvable during the con, which didn’t happen last year. In fact, last year it took 3 weeks to get solved. So right off the bat, that makes it a better puzzle. This was partially because it wasn’t quite as obscure as last year, though maybe folks who’ve rarely dealt with geolocation and range/bearing measurements might not have thought so.

Originally, G. Mark had planned to have all the data points listed out, and then shift one of the columns “up” a single row (so all the latitude/longitude pairs would be slightly off). If the shifted column had been range or bearing, it might’ve been a good additional challenge, but if it had been the latitude or longitude, then I’m not sure it would have ever been solved, at least not without help. So it could easily have been unreasonably difficult. For one thing, it would have been difficult to start piecing together the airport codes until the all airport coordinates had been collected. Being able to attack the problem in multiple discrete steps is crucial to being able to solve the puzzle (and, especially, crucial to being able to solve the puzzle enjoyably.)

As it was, we never even needed the bearing data point – only the distances between airports were necessary to reconstruct the path, and thus, the plaintext. Though if we’d noticed that (for example) a couple of airport codes together spelled “MOOSEZ”, we might have simply tried to anagram everything together and solved it without even using the ranges. Having not gotten all the data pieces until the very end kept us from taking that particular shortcut.

So, as it was, this was (in my mind) a well-done, interesting, and fun puzzle to solve. Thanks again to G. Mark, Heidi, and ShmooCon!