Saturday, October 21, 2017

Challenges for September 2017 SecTalks London

20171021_064556 by dejesus54 from flickr (CC-NC-ND)

SecTalks's name suggests that it might have started as "security talks" meetup, but its format evolved and it's primarily about doing security-related challenges.

Usually the person who won previously, or another volunteer, prepares a challenge, and then during the meetup everyone tries to solve it. Whoever finishes first then gets to run the next one.

The challenge usually takes multiple steps - once you solve one, you unlock the next layer.

After my most recent victory I decided to tweak the format a bit. Participants vary a lot in level of experience, so with layered challenge it's common for many to just get stuck and not do much for the rest of the meetup.

So instead I setup a CTFd server with 8 challenges which can be done in any order. This way if someone is stuck, they can just try another challenge.

You can get the challenges and the source code I used to generate them from this spoiler-free repository.

This post doesn't contain answers, but it might spoil quick a bit.

Archive (5 points)

It was a small bonus challenge, which I expected to be the easiest of all, but it somehow turned out to be hardest, with even the eventual winner solving it only after finishing everything else.

The archive contained file with the answer and some distraction files. It was packed into another archive together with some distraction archive files. And so on a few more levels.

It could be done manually, as distraction files were always identical, so you just go for the different one each time. Or it could be done with some simple Unix scripting.

I'm not even sure why people had so much trouble with it, maybe they expected something more devious?

Javascript 1 (10 points)

Most of challenges were about reverse engineering password validation script. Finding your way in a messy Javascript is one of core skills nowadays.

I wrote simple script with lines like these:

checksum += Math.pow(password.charCodeAt(0) - 115, 2)

And passed it through this obfuscator.

Javascript 2 (15 points)

Second Javascript reverse engineering challenge had more complicated validator.

Every character went through a few variables where it'd get shifted by a constant. Order was reshuffled and then obfuscator would rename those variables, so it was a small puzzle, but it wasn't too hard to just walk backwards.

var a5 = password.charCodeAt(5)
var b5 = a5 + 80
var c5 = b5 - 194

I passed this script through this more complex obfuscator , with settings of string array encoding: Base64, string array threshold: 1.

It was a lot harder than the first Javascript challenge.

One Letter (20 points)

This challenge is a cryptography classic - a block of text encoded by a monoalphabetic substitution cipher with spaces and punctuation removed.

In principle it's totally doable manually in a few minutes, but people who tried to do it this way. Most solved it with online statistical analysis tools.

Python (25 points)

Finding obfuscated code in non-JS languages is rare, but everybody should have basic familiarity with wide range of popular languages.

Validation script contained tests like these:

    if ord(key[7]) + 97 != 197:
        return False

Then I used online obfuscator, but it's no longer available. I think it was based on this.

There was extra step here, as it only worked in Python 2, and many people obviously tried to run it on the most recent version.

Ruby (30 points)

I couldn't find any ruby obfuscators, so I found some old one for 1.8, and based on it wrote my own.

People had little trouble getting through the obfuscator, but the next step of dealing with validation script itself turned out to be really difficult.

Validator concatenates password 4 times, then modifies it by taking out letters one at a time.

  return unless password.slice!(10, 1).ord == 110

Some people wrote scripts to reverse slice! into insert, others tried to do it one character at a time from the top. Either way it was hardest of all validation scripts.

Perl (35 points)

Validation script contained shuffled lines like these:

return if substr($key, 10, 1) ne "s";

And then I used this obfuscator.

Even though Perl isn't very popular any more, it turned out to be quite easy.

RSA (40 points)

And finally, a simple RSA challenge.

With same message sent to 3 different recipients, and small exponent e=3, it's probably the easiest of all RSA attacks.

Final Thoughts


CTFd server was very easy to setup. It takes just a few minutes in basic (for "classroom" sized userbase) setup.

The format was very successful - on top end it was a tight race - with leader changing many times during the meetup, and in the end with only 13 second gap between first and second finisher.

For everyone else, almost everyone managed to do at least a few challenges, and when people got stuck, they just tried something else instead of getting stuck and giving up.