HACKVent 2020 – Day 22

  • by

Challenge – Padawanlock

A new apprentice Elf heard about “Configuration as Code”. When he had to solve the problem to protected a secret he came up with this “very sophisticated padlock”.

Solution

Unpacking the .zip archive, we got a 19MB Linux executable. That’s large. But maybe it statically links a dozen libraries? After running it, this seemed unlikely as we were presented a simple terminal application asking for a 6 digit key. So indeed a padlock, just like the challenged described. Normally a small password like this can be bruteforced quickly. This application took its time responding however, allowing only a few password per second.

All the outputs were some random Star Wars quotes as can be seen in the image.

We had to dig deeper. Turns out most of the file is code, as the .text section is huge. retdec decompiler did not like it. So Assembly it was. We started radare2 with the Cutter UI and quickly found the entry point. It didn’t do much at all. Interesting was the call into a HUGE function, consisting of very repetitive code. So that is where the 19MB went.

Upon closer inspection you’ll see that most of this code is actually just deliberately wasting CPU cycles and slowing down the password check. Two of those loops are marked in the image. Since we couldn’t possibly patch ~6MB of code, we needed help. There are dedicated tools out there, but the instructions are all so similar and of the same size that you’d probably get away with a text editor and a regex search&replace.

We instead, used some not-so-sophisticated C# program to change all mov ecx, 0x0150???? to mov ecx, 0x00000001 so the condition is true and the jne taken on the first try.

var bytes = File.ReadAllBytes("padawanlock");

for (var i = 0; i < bytes.Length; i++) {
    if (bytes[i] != 0xb9) {
        continue;
    }

    if (bytes[i + 3] == 0x50 && bytes[i + 4] == 0x01) {
        bytes[i + 1] = 0x01;
        bytes[i + 2] = 0x00;
        bytes[i + 3] = 0x00;
        bytes[i + 4] = 0x00;
    }
}

File.WriteAllBytes("padawanlock-patched", bytes);

Then we ran the patched padawanlock and it responded much faster to the input. Bruteforcing was now feasible. So feasible that a shell script produced enough throughput to get the flag in a few minutes. In the next screenshot you can see a reproduction of the run (with a modified number to find the flag faster).

#!/bin/bash
i=0
s=""

while [ $i -lt 999999 ]
do
   if ! ((i % 10000)); then
       echo $i
   fi

   s=$(echo $i | ./padawanlock-patched)

   if [[ $s =~ $testseq ]]; then
     echo $s
     exit 0
   fi
i=$(( i+1 ))
done
HV20{C0NF1GUR4T10N_AS_C0D3_N0T_D0N3_R1GHT}

Leave a Reply

Your email address will not be published. Required fields are marked *