Skip to content

Comment on Finnish Defence Forces' Cyber Challenge

Comments

Spoiler alert! Answers below:

===

===

===

===

===

Ad 1. Someone tries to exploit Internet Explorer. You see a command line which is subprocess of web browser (unlikely normal).

Ad 2. a) 16 days ~= (31337 4) / (700 * 109 * 3600 * 24) b) 10 days ~= 95 9 / (700 * 10 9 * 3600 * 24)

Ad 3. Lorem~Ipsum (Base64)

Ad 4. Yes. One of the programs guess the same as random, the other guess the opposite of random.

Ad 5. QWErty

8. "password"

    $6$saltsaltsaltsalt$bcXJ8qxwY5sQ4v8MTl.0B1jeZ0z0JlA9jjmbUoCJZ.1wYXiLTU.q2ILyrDJLm890lyfuF7sWAeli0yjOyFPkf0
11. (1/3)^3 + 3 * (1/3)^2 * (2/3) = 0.2592592 (can someone else please verify this?)

26. An attacker could work out the password reset token using the time.

Multiple SQL injection vulns.

Not a vuln, but a mistake - Line 6 of passwordRecover.php should be

    if ($_GET['token'] == $result[0]['pass_recover']){

For 11 I think you're wrong because you forgot the part: "As minutes pass, you begin to vaguely remember lurking in your basement and typing the command ':(){ :|: & };:' in an xterm session just before everything went black.". The fact that you have a machine which has an xterm session means that it's either an OS X or Linux Box, which rules out the possibility of having 3 windows boxes. So you have 1/26 chances of having 3 linux boxes and 3*2/26 chances of having 2 exactly 2 linux boxes, so in total it's 7/26 (or 0.2692307692307692).

Yes, that would make more sense.

ad 11. I think that all the possible "combinations" are not 27 but 10, because e.g. tuples (Linux, Windows, Linux) and (Linux, Linux, Windows) are identical. I.e you should count combinations not variations.

All the poss combinations: LLL, LLW, LLO, LWW, LWO, LOO, WWW, WWO, OWO, OOO

Then you cross out WWW (xterm constraint), and you have 9 combinations, of which 3 are valid for the condition (at least two "Ls"). So 1/3.

Let me know if I got sth wrong :).

No, there are 27 combinations(when you still account for the fact that you can have three windows machines).

You can see it in that way:

machine1: L, machine2: W, machine3: O machine1: L, machine2: W, machine3: W

The reason why it matters is that you have more ways to have exactly two linux machines:

m1: L, m2: L, m3: O

m1: L, m2: O, m2: L,

etc.

That gives you 2*3 ways of having exactly two linux machines (you have 3 ways of having exactly one non linux machine, and then this machine can be two different things). If you say that LLO is OLL, you would have only 2 ways of having exactly two linux machines.

Hope this makes sense.

I see. LLO and LOL are different occurences and must be counted for. Thanks for clarifying!

I thought 10. was fun, couldn't get under 35 characters though:

([bcdfghjklm]).(...)*\1

grep -E "^([^aeiouyåäö]).(...)*\1$" < /usr/share/dict/finnish

Spoiler: A few other answers which I think are right. Please correct me if I'm wrong or missing anything.

13. All of the above.

14. Just 5 I think?

16. 4 and 5

21. Looks like it wants a password of "hunt". The logic under it is either expecting the bitwise NOT'd value of a different static key or is doing something I don't understand.

22. Stack cookie. 2 and 3.

23. Definitely missing a lot of things, but #20 allows support users to execute anything as root due to the "*".

24. #15 - SQL injection, #21 - MD5 is unsuitable for password hashing, #25 - if an exception triggers you will automatically be authenticated, as "" == "", #28 - String comparison vulnerable to timing attacks

25. Lots of command injection. Buffer overflow in `error` function (buf holds 128 bytes but 128 + strlen("error: ") bytes could be copied to it). Probably many other things I'm missing.

26. No CSRF tokens (arguably not that necessary for these since every form wants some sort of password, but you could exploit vulns through someone else's browser via CSRF as a way of hiding the true source of the attack), SQL injection and XSS via $_GET['id'], SQLi with $_GET['email'], weak DB pass, LDAP injection with $_POST['username'], == should be ===, all user rows will be set to have the same recoveryPass due to missing WHERE clause in tue UPDATE, string comparison timing attacks, time() is a very weak and predictable seed for generating a random recovery password, you can probably hijack the emailer to send phishing messages and links by adding some extra text to $email with " someuseryouwanttophish+also visit http://evilsite.com@gmail.com" (I don't know if mail()/Gmail would actually deliver that due to the leading space and such, though). Probably missing 1 or 2 things.

There's another anomaly for #1:

There is a "rundll322.exe", should be "rundll32.exe". Also, its description is "Print driver host for...", which would not make sense for the real rundll32.

How did you get answer for 5? I just got gibberish when I converted from binary to string

Can you explain answer 4 and 5 please?

Thanks.

Number 4 is pretty cool because the programs use the fact that they know how the other program guesses to make sure they win.

If I'm Program 1 and I see a 0, I will guess 0. If Program 2 sees a 0, Program 1 guessed correctly and it doesn't matter what he guessed. If Program 2 sees a 1, he will guess the opposite (0) and this means that Program 1 was wrong but Program 2 was right.

If Program 1 sees a 1, he guesses 1. If Program 2 sees a 1, Program 1 is correct. If Program 2 sees a 0, he guesses 1 and is correct.

The above is a truthtable in words that shows they are always right.

For number 5, I translated the binary numbers to decimal and used an ASCII table to convert them to ')87*;+xorXOR'. This is a different answer than grandparent. The following C++ code does the conversion: http://pastebin.com/ThxdHHwu

4 is pretty simple if you look at all possibilities.

Program A will receive a 0 or a 1 and will guess the opposite of this value.

Program B will receive a 0 or a 1 and will guess this same value.

So, you have 4 possibilities:

(A/B is the bit received, a/b is the guess, you 'win' if b == A || a == B) (In other words, if B's guess is equal to what A received, or vice versa)

A|B|a|b

0|0|1|0 (b == A)

0|1|1|1 (a == B)

1|0|0|0 (a == B)

1|1|0|1 (b == A)

Another way to think of it is that A is guessing that they will receive different values, and B is guessing that they will receive the same value. One must be right.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.