The best kittens, technology, and video games blog in the world.

Showing posts with label london. Show all posts
Showing posts with label london. Show all posts

Wednesday, December 18, 2019

Challenges for November 2019 SecTalks London

Selfie by SethBahl from flickr (CC-NC)


October 2019 London SecTalks CTF was jointly won by me and Laurence, so we wrote challenges for November together.

There was a total of 9 challenges, 5 written by me and 4 by Laurence. It was a bit much, as one of the challenges got zero solves until after the event. In spite of very generous hints given halfway through the event.

Challenge files and code used to generate them are available on github.

There are no answers below, but some serious hints which might make it too easy.

For previous rounds, see posts about September 2017, November 2017, May 2018, July 2018, October 2018, February 2019, April 2019, and July 2019 CTFs.

Rockstar (5 points)

The puzzle was a rock song / program in Rockstar programming language. Just running the program would print ASCII codes, which could be easily turned into a flag.

Think Outside The Box (10 points)

The challenge is a BMP image file with flag hidden by incorrect image size. Changing the header reveals the image.

Dots (15 points)

This was Unicode Braille, but dots and no-dots were simply 1s and 0s to be decoded, ignoring any "Braille" structure. To my surprise nobody solved it even when given basically full explanations of what they're supposed to do.

CRC32 MAC (20 points)

A signed cookie server, which uses CRC32 with secret key as MAC. CRC32 is extremely unsuitable in this role.

Decryption Engine (25 points)

A small Python program which uses default password based on current date, and encoded file. Assuming password wasn't passed, the space of possible keys is tiny.

Salted MAC (30 points)

A signed cookie server, which uses SipHash with secret key, and then salt just to be extra sure.

In principle this should be difficult to break. The problem is a trivial implementation mistake.

PHPain (40 points)

It was a separately hosted PHP application vulnerable to recently published CVE.

Poly-DIY MAC (50 points)

Another signed cookie server, using a simplified variant of Poly1305. The variant is reasonable, however the server isn't very careful about nonce handling, and such schemes tend to fail catastrophically when nonce is reused.

GeoCaptcha (60 points)

It's a web "Captcha" which asks the user to locate 20 major cities on the map, with any mistake failing the Captcha.

You can play it here (for a while).

It's worth so many points mostly due to its very high entertainment value, not due to difficulty.

I was curious how people would approach it - only 2 players solved it with code (as robots), 6 solved it with tedious manual process (as humans). So I guess it works as a Captcha.

Monday, July 29, 2019

Challenges for July 2019 SecTalks London

Dewey by angela n. from flickr (CC-BY)

Another CTF, another victory. I won the June 2019 London SecTalks CTF and it was up to me to write challenges for July.

There were 12 challenges, theme of the challenges being Hacker-Archeology. It turns out that was too much, as only 10/12 challenges got even one solve, and nobody got more than 4. Even with very generous hint drops during the event.

Challenge files and code used to generate them are available on github.

There are no answers below, but some serious hints which might make it too easy.

For previous rounds, see posts about September 2017, November 2017, May 2018, July 2018, October 2018, February 2019, and April 2019 CTFs.

SHAR (5 points)

Self-extracting Shell archive nested 8 levels deep. It only works on Linux, OSX shell can't extract Linux-created SHAR files, showing what a dumb format this is.

XBM (10 points)

A weird way to encode image into C headers. While totally obsolete, a lot of tools still support it.

Maya (15 points)

An image with a sequence of Maya numerals, each encoding ASCII symbols. It seems people were confused by the fact that multi-digit Maya numerals are stacked vertically.

PCX (20 points)

PCX file with flag on it, but both foreground and background colors having same RGB color, so color palette would need to be adjusted to actually see it.

ECB (25 points)

A signed cookie server which would only sign cookies without admin=yes, and it would only give you the flag if you sent it signed cookie with admin=yes.

It's a classic cryptography attack on ECB mode, rearranging blocks within or between cookies.

SED (30 points)

SED is an obsolete programming language for text stream processing, and the challenge was a simple flag validation script which was just a sequence of regexp replace rules.

Nobody noticed that, but that SED script was also totally valid Perl 5 script.

CBC (35 points)

A signed cookie server which would only sign cookies without admin=yes, and it would only give you the flag if you sent it signed cookie with admin=yes.

It's a classic bit flipping attack on CBC.

MD4 (40 points)

A signed cookie server which would only sign cookies without admin=yes, and it would only give you the flag if you sent it signed cookie with admin=yes.

It's a classic length extension attack.

Midi (45 points)

A midi file with flag encoded in Morse code, played on an Ocarina instrument suggestively named "Morse Ocarina".

It could be done either by hand, or by converting note lengths in Midi format to dots and dashes. I think everybody ended up doing it by hand.

DOS (50 points)

A very small COM file flag validator. It was extremely simple, but a lot of tooling like Ghidra has trouble with COM files, as they're too old to be relevant.

It got zero solves, which was fairly surprising, as flag validator is really simple:

# Initialize counter in BX
  mov bx, 0xd7ab

# Get ASCII code of next character into AL
  mov ah, 0x1
  int 0x21

# Add AX to the counter, check if correct
  add bx, ax
  cmp bx, 0xd911
  jnz near 0x19d

# Repeat for next character

Differences between constants being compared are 256 + ASCII code of each letter (first being 0x166 or 256 + "f").

Hieroglyphs (55 points)

Monoalphabetic cipher encoded into Egyptian hieroglyphs. The text was very long English text with spaces removed.

It's really simple for anyone who ever did monoalphabetic cipher breaking through statistical analysis, so that many points mostly being potentially quite time consuming, but it didn't even take people that much time.

Perl 6 (60 points)

In remote past Perl 6 used to be the language of the future. That future never came.

The challenge is a flag validator in Perl 6 aggressively using many unusual Perl 6 operations. I'm not really surprised that nobody succeeded at solving it.

Tuesday, April 30, 2019

Challenges for April 2019 SecTalks London

O'Malley by Sylvie MM from flickr (CC-NC-ND)

I just keep winning them, and by convention the winner organizes the next one, so I just ran another round of London SecTalks CTF.

There were 10 challenges. The winner got only 6, but each challenge was solved by at least one person during the event. So maybe it was just a bit too much, but it's better to have too many than too few challenges.

Challenge files and code used to generate them are available on github.

There are no answers below, but some serious hints which might make it too easy.

For previous rounds, see posts about September 2017, November 2017, May 2018, July 2018, October 2018, and February 2019 CTFs.

EBCDIC (5 points)

It was a simple challenge for beginners. The flag was encoded using EBCDIC. It could even be done manually.

CSS (10 points)

This was possibly the most original challenge, the flag was encoded in a pure CSS maze, where you'd need to mouseover each correct letter in order to get the challenge.

CSS wasn't too obfuscated, so that was the easiest way to solve it.

CTR (15 points)

A small server which encrypted your message with AES-CTR. There was also encrypted flag.

The problem was that IV was not generated every time, and there's a standard attack for that.

sayflag (20 points)

This was a small MP3 file, encrypted with a XOR key. The file did not have ID3 tag, so there's not enough known plaintext for the usual attack.

The hint suggested one alternative approach: MP3 compression works like JPG, but block artifacts would be fatal, so compressed blocks overlap a bit. To avoid special treatment for the last block, encoders add some silence at the end of the file (also sometimes at the start), so that part usually has very low entropy. No ID3 here.

With this hint it should be fairly easy to adapt the attack.

Rust (25 points)

A simple flag validator, this time written in Rust to make reverse engineering a bit more challenging.

RSA Signatures v1 (30 points)

This was a fun double challenge. The challenge was "textbook RSA" signature server without any padding or hashing. It would verify and sign any "safe" message, and the task was to give it "unsafe" one containing admin=yes.

There were two versions of this challenge, and diffing them revealed some extra checks which were missing from the first version, which could be very easily exploited.

Codage Hexadecimal (35 points)

French plaintext got hex-encoded, but with digits mixed up. It was tiny bit harder than previous English challenge, as there were was a bit of Unicode with accented characters.

from_past_import_flag (40 points)

A program that would generate a flag, but only if you run it in 2005. To avoid being fooled by changing laptop clock it double checks with NTP server, but NTP is completely unsecured, so it's very easy to redirect that traffic to a local NTP server.

Or just attack the file with gdb.

RSA Signatures v2 (45 points)

In the second part of textbook RSA signatures challenge, bounds check issues were fixed, so a proper RSA signature malleability attack was needed.

Chifferment par Substitution (50 points)

Substitution cipher, this time on a French text, and without most punctuation. It's not difficult, it's just fairly time consuming.

Friday, March 01, 2019

Challenges for February 2019 SecTalks London

Snow Leopard Cub Looking Curious by Eric Kilby from flickr (CC-SA)

I ran another round of London SecTalks CTF.

There were 12 regular challenges, and 1 super-hard bonus challenge. Only 10/13 got at least one solve during the event, so maybe difficulty or number of challenges were a bit too high.

Challenge files and code used to generate them available on github.

There are no answers below, but some serious hints which might make it too easy.

For previous rounds, see posts about September 2017, November 2017, May 2018, July 2018, and October 2018 CTFs.

from_future_import_flag (5 points)

It was a simple program which could tell you the flag if you run it in year 2020.

Censored SVG (10 points)

A simple HTML file with SVG image on it. The image contains flag covered with some censoring square. SVG image is base64 encoded for one small layer.

Hello RISC-V (15 points)

A simple binary which will give you the flag if you run it. It only runs on RISC-V, so you'll need to figure out a way to do so.

Crystal (20 points)

Password validator binary compiled from Crystal. Binary contains a lot of extra stuff, but validating function shouldn't look all that strange.

Powerpoint (25 points)

PowerPoint PPTX file encrypted with XOR. Flag is on the slides.

RISC-V Verify (30 points)

RISC-V binary validating password. It might be easier to run static analysis, but you should still understand basics of RISC-V assembly. Or you could run gdb on RISC-V emulator.

OCaml (35 points)

Password validator binary compiled from OCaml. OCaml uses unusual integer representation, so it's extra layer of confusion.

It had zero solves during the event.

LOLHEX (40 points)

English text encoded by hex encoding, but which of 16 digits is which is scrambled. Simple statistical analysis should do here.

Imba (45 points)

Password validator written in Imba. It will tell you if you get your flag right. It can be solved by static analysis (data driving logic is easy to see), or in-browser, possibly by by attaching DOM breakpoints.

It had zero solves during the event.

Catzip (50 points)

For mandatory meme challenge. It's a zip format made by gzipping something, then turning it into a PNG containing cat emojis. There's two cat emojis, 8 per row, so you can probably guess where it's going.

FPGA (55 points)

A slight variant of challenge from previous time. It's a small circuit, and you need to find inputs which give positive result. This time circuit has NAND, AND, NOR, OR, and XOR gates.

It's highly advisable to use Z3 or similar for it.

Monoalphabetische Chiffrierung (60 points)

German text encoded with monoalphabetic cipher, and then turned into Unicode Fraktur.

It's actually very easy, as punctuation, capitalization, digits etc. were not really scrambled.

LOL64 (100 points)

For super hard bonus challenge, it's English text encoded by Base64 variant, but which of 64 digits is which is scrambled.

Understandably, it had zero solves during the event.

It's definitely solvable in principle, but I'm not really sure how to write such solver. It can be seen as breaking a key of 64 6-bit parts, so 512 bits total. Knowing that it's all ASCII and simple statistical methods get a lot of those bits, but from that point on it would take some creative statistical analysis. Big difficulty is just size of the key, and how a single error in decoding can mess up all following statistical analysis, and cost a lot of time.

I'm sure there are also some ways to circumvent this whole process, and find exact encoded text from some simple statistical properties, but I didn't try it this way as it's less fun.

Sunday, October 28, 2018

Challenges for October 2018 SecTalks London

She loves the computer by glennwilliamspdx from flickr (CC-BY)

Last month I ran another round of London SecTalks CTF.

There were 10 challenges, and the winner got 9/10 of them during the event (and last one on the following weekend), so difficulty level was about right.

Challenge files and code used to generate them available on github.

There are no answers below, but some serious hints which might make it too easy.

For previous rounds, see posts about September 2017, November 2017, May 2018, and July 2018 CTFs.

Archive (5 points)

A small variant of the 16-level 16-way nested archive, to test for basic Unix scripting skills. This time using RAR.

MonoRSA (10 points)

It's RSA-encrypted message, but it uses only one prime, not two. This is extremely insecure, and can be trivially broken, but you still need to do some math.

BCRYPT (15 points)

Each letter of the flag was encrypted with bcrypt. It's easy to break, as long as you know how bcrypt works, which isn't quite the same as plain hashes, so it was causing a bit of confusion.

RSA RNG (20 points)

It's Debian weak RSA key attack all over. We have target's public key and encrypted message. Also a lot of other people's public keys, all generated using same bad RNG. If two keys share a prime it's easy to break them, even if direct factoring isn't viable.

Python (25 points)

Small bit of reverse engineering - small Python password validator obfuscated with one of online tools for it.

MultiRSA (30 points)

A little known fact about RSA is that it works just fine with more than two primes. So this challenge uses 16 - which is fine, except key size was not adjusted appropriately, so each of those primes is small enough to break it.

Binary (35 points)

Binary password validator, provided in two versions (Linux and OSX) for convenience. It was compiled with -O3 which made its encrypting loops unroll, and what was very trivial code turned into hard to understand vectorized mess. Then again, actually running the program might reveal something interesting.

SVG XOR (40 points)

The flag is written in SVG flag, which was encrypted with a XOR cipherer. This turned out to be quite easy, as SVG files have a lot of structure which can be used to attack this.

FPGA (45 points)

Probably the most original challenge this time. A netlist of NAND gates which can validate the flag and tiny emulator were provided. Can you figure out the inputs necessary to get the validator to accept?

This was the only challenge without anyone solving it during the event, but there were some solutions afterwards.

Tweets (50 points)

A flag was hidden in collection of Donald Trump's tweets, encrypted with monoalphabetic cipher. Great exercise for frequency analysis.

Wednesday, August 01, 2018

Challenges for July 2018 SecTalks London

Cat sitting on a desk by freestocks.org from flickr (PD)

Last month I ran another round of London SecTalks CTF.

I only created 6/9 challenges this time, 3 Android challenges were created by imhotep.

Challenge files and code used to generate them available on github.

There are no answers below, but some serious hints which might make it too easy.

For previous rounds, see posts about September 2017, November 2017 CTFs, and May 2018.

Hidden treasure (5 points)

As per tradition, there was a bonus challenge with a zip bomb. This time at the end of 16-deep archive with 16 branches each there were pictures with a treasure, with EXIF tags containing either the flag or information that you failed.

Android 1 (10 points)

The simplest Android challenge wasn't even all that Android specific - as the flag was hidden directly inside the .apk.

RE1 (15 points)

Easy reverse engineering challenge was just a 32-bit Linux binary, which verified passed flag character by character, in random order.

Disassembling it, you'd get instructions like:

cmpb   $0x74,0x10(%ebx)
jne    80484b7

If you arranged them correctly, you'd see the flag. Or you could just grep for all characters, and use anagram solver - apparently that was an option too.

Android 2 (20 points)

This one required actually running the app, or fairly complex static analysis. The app saved a file with the flag to device storage. If you can find the file, the flag is yours.

RSA (25 points)

This challenge was actually quite realistic.
Bob sent a message we need to decrypt.

Probably due to bad RNG, it looks like Bob and Alice picked same N for their keys, and we managed to steal Alice's private key as well.

Perhaps there's a way to take advantage of this.
And there is a way. Having private key (n, e, d) there's algorithm to factor n into p, q. It's not completely obvious, but it's fairly short to implement. With p, q (shared between both), and Bob's e, you can trivially get Bob's d. Then you can decrypt the message.

RE2 (30 points)

It was a slightly harder version of reverse engineering challenge. The only difference was that flag was encoded into Base64 before checking, which could throw people off, but binary wasn't stripped so b64_encode method was a massive hint.

Android 3 (35 points)

The challenge app is making HTTP request, which needs to be intercepted and modified to get the flag from the server.

Once you get the request it's obvious what to do, and there were hints provided how to setup proxy on Android to get them.

CTR (40 points)

Another somewhat realistic challenge. A collection of Elon Musk's tweets and a flag was encrypted using AES-128 in CTR mode. Reusing same IV for all of them.

This turns CTR mode into XOR with random keystream, and breaking XOR cipher is fairly basic. It turns out nobody remembered mode names, so I had to give people some hints before they tried CBC or CFB attacks on it.

Croatian Monoalphabetic (50 points)

This challenge was worth the most points, but in principle it was very easy, just a bit time-consuming - and I ended up giving people hints how to approach that.

It's just statistical analysis of another Latin script language. So you can start by assuming space is the most common character, then use character frequency tables for Croatian, or lists of most common words, or take advantage of the fact that flag (very long word) is embedded inside.

Wednesday, June 13, 2018

Challenges for May 2018 SecTalks London

そんな目で見ちゃダメだねぇ by amika_san from flickr (CC-ND)

Last month I ran another round of London SecTalks CTF.

There were 8 challenges as before. And again, the winner only did 7 of 8 on time, the last one (Monoalphabetic) only after the event.

Challenge files and code used to generate them available on github.

There are no answers below, but some serious hints which might make it too easy.

For previous rounds, see posts about September 2017 and November 2017 CTFs.

Invisible Flag (5 points)

It's a third iteration of the zip challenge.

There's a zip file containing 16 zip files inside. And each contains 16 more zip files. And so on for 16 levels, until you get to the flag.

For a small additional complication, the flag is completely invisible, and made out of different types of Unicode spaces. Replacing special spaces with different characters will reveal it.

Perl (10 points)

It's a very simple password validator written in very straightforward Perl.

The validator is mostly a sequence of commands like

s/^(.{7})i(.*)$/\2\1/;

Which removes character "i" from 8th position, and swaps everything before and after it. If the answer is empty, the validation is successful.

The easy way to solve it is to work backwards from an empty answer.

Almost Invisible Flag (15 points)

The challenge is an image with 1s and 0s written onto it in a very faint color. Once you figure that out, and transcribe the numbers into a binary file, it's a zip. Unpacking it reveals the flag.

React.js (20 points)

It's a react.js based validator. Validator is build of component layers, first layer checks length of the password, then each layer checks one character and passes the data to next layer with some transformations applied.

React Developer Tools for Chrome can be quite helpful for this.

This can be solved in many ways. You could brute force each layer with a simple script, or turn React code into a recursive function, and solve in an old fashioned way.

RSA (25 points)

For this challenge p and q are very close to each other. In fact they differ by just 2. There's a very simple attack for such case.

Monoalphabetic Cipher (30 points)

This challenge is a bit of text with flag embedded in it, encrypted by monoalphabetic cipher - all lower case letters, upper case letters, digits, spaces, punctuation each getting separate character.

The trick is that symbols used by the cipher are all emoji, which doesn't make the challenge any harder, just more fun.

The slight difficulty is that the text is not actually in English, so statistical methods can suffer a small detour. It's actually in German.

This was the only challenge that wasn't solved in time, but I don't think it's really that hard or time consuming.

I really like challenges about classical ciphers, but I don't want the solution to be simply copypasting it on quipquip.

PDF (35 points)

The challenge is a PDF file encrypted by a XOR key. The content is just a result of Chrome's print to PDF function. For extra challenge the flag is censored with a black bar over it, but that's very easy to workaround.

PDFs have a lot of plaintext inside, so there's a ton to work with, however it's somewhat unpredictable where that plaintext is located.

The key is three lower case English words without spaces.

A surprise extra challenge is that I accidentally left newline character at end of the key, which I only noticed during the challenge and told the contestants.

Javascript (40 points)

It's a very simple Javascript validator, obfuscated with jsfuck to only use 6 charecters.

I expected that people would need to write a simple JSFuck decoder, and that's why it's worth so many points, but most people just used Chrome debugger instead to solve this challenge really quickly.

Monday, January 29, 2018

London cycle hire adventures

Lilith on bike seat by catmom42 from flickr (CC-NC-ND)
Today I felt like coming home with a cycle hire (commonly known as "Boris Bikes", officially now "Santanders Cycles" after a rebrand).

I went to a nearest dock, which the app claimed to be in perfectly fine order, and tried to get a bike. Error. Tried a few more times just in case, still error. I thought that's just app error, so I tried to use the terminal instead - which is really painful as it involves clicking same stupid confirmation dialogs about 25 times before it lets you rent the damn bike - but it was just as broken as the app.

Could the app somehow mark the dock as not working? Right...

So I walked to the next dock, that somehow wasn't broken, so I got a bike, cycled to Aldgate, and from there to the end of pompously named "Cycle Superhighway 2" at Stratford.

Stratford is a traffic hell, with no docks near the "Cycle Superhighway 2" or the station. The app claimed the nearest two docks had zero spaces left.

There was one about 10 minutes away from the station which claimed to have 4 free spaces. I went there - wasting tons of time going in circles because direct route is not possible anywhere near Stratford - and there was only one space, which didn't take the bike in spite of repeated attempts, for whichever reason. First it flashed red, then it just gave up.

After a lot of loud cursing, I had to cycle to the next dock, which fortunately somehow had free spaces, probably because it was really damn far from the station.

The cycling itself was fine, just everything else about the experience was totally miserable, and of course they charged me extra for wasting my time due to broken docking stations.

Which is pretty much what I learned to expect from the TfL. Unionized 💩💩💩.

I really hope some competition with dockless bikes comes to London. Right now none of these new schemes allow realistic commuting between Central London and zones 2/3, but there's some hope for the future.

Tuesday, December 19, 2017

Challenges for November 2017 SecTalks London

Christmas Luke by Nicholas Erwin from flickr (CC-NC-ND)

Following highly successful September round of London SecTalks, I ran another round in November.

The round consisted of 8 tasks, and they were a bit harder this time, with even the winner only finishing 7 in time - a few people completing the challenges only after time.

You can find challenges and code used to generate them in this spoiler-free repository.

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

Archive (5 points)

It was nearly identical to previous round's archive challenge - 16-level nested archive, with 1 real and 15 fake archives on every level. The only difference was that distraction files were 0-padded to have same size as the real file, which forced smarter strategy than simply going for the largest file every level.

Of course MD5ing to find unique file, or just unpacking them all and removing duplicate files still worked.

CSS (10 points)

The password was encoded within CSS rules. I've never seen this kind of challenge anywhere, so maybe it's the world's first?

It was very short, and every character was independent, so it seems that everyone just manually brute forced it.

Secret Message (15 points)

The answer was written in one color on background of another extremely similar color. Everybody managed to finish it so quickly, I didn't even have a chance to see what kind of tools they used to solve it.

EDIT: Oops, it seems that I messed up ImageMagick options and also accidentally left the answer in EXIF.

Python (20 points)

As we all know Python is a whitespace-sensitive language. So I encoded some secrets in the whitespace.

Quite a few people used editors which cleaned up whitespace automatically, messing up with the file. Once a person figured out what the challenge is about, it wasn't usually too hard to solve it.

Ruby (25 points)

Obfuscated Ruby challenge was the hardest one of the round. It used two layers of Unicode obfuscation, first with emoji, and then with CJK characters. Other than using unusual characters, obfuscations applied weren't particularly hard.

ECB BMP (30 points)

This was a fun one. It was basically a version of the famous ECB penguin from Wikipedia.

People had a lot of trouble figuring out dimensions and bit depth of the image, which had to be given as a hint, even thought they were fairly usual.

XOR GIF (35 points)

This was a two step challenge. A GIF file was xor-encrypted with a word from a dictionary.

The challenge was then to find out which Twitter account the image is from.

Since GIF header is known, it was very easy to figure out the first few letters of the key. However, people had a lot of trouble completing it, as the word I've chosen was only in some dictionaries. This wasn't intentional.

After getting the image, it turns out only some reverse image search could find it properly, and others returned bogus matches.

ROT Word (40 points)

I wanted to have a task for statistical analysis of some classical cipher, but all the real ones have online tools you can use to solve them in a few seconds.

So I made up one - it's like rot cipher with multi-letter key, except each letter is used for whole word, not for one letter.

encrypt("All your base are belong to us!", "omg") == "ozz kagd hgyk ofs nqxazs zu ig"

For a bit of extra challenge the message was in English, but contained a bunch of non-English proper names.

Final Thoughts

I made this one just a bit harder, and maybe it was a tiny bit too much.

Overall, a lot of fun happened.

I'd definitely recommend CTFd server for this.

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.

Sunday, January 20, 2008

My poor bottom left 6

tree eater by splityarn from flickr (CC-NC-SA)

My tooth hurt a bit in the last week, and it got really bad yesterday, so I called some 24h dental service. It wasn't as 24h as they claimed and I was only able to get an appointment for the next day. The bad news is - root canal treatment was required. The even worse news - it was damn 700 quid for two visits. Here goes the new computer, at least for now. It's seriously insanely expensive compared to dentistry in Poland, whene plain checkup is about 10 GBP, and root canal treatment is about 50 GBP - just Google for prices if you don't believe me. If I actually knew in advance it would cost that much I'd probably just book a flight. Too bad you cannot schedule your dental problems.