Sunday, October 23, 2016

UTPHAX'16 Pre-liminary Challenge 4 (Encryptilicous) Write-Up

Challenge Files :  https://drive.google.com/open?id=0B_TlESfLlYGQakdRQnljVnVVbjg

Anyone who reversed the binary should come to the conclusion that it is just using xor encrypt (very simple encryption algorithm) to encrypts the data, with having the key 'dafa' hardcoded into the binary.

However, most of us might be confused with the fact that the output isn't same with the value returns by the encryptor function.

Observation

Let us observe below behavior, suppose that I want to encrypt "kkkk" with the encryptor program.

shahril:q4$ wine encryptor.exe > kkkk.bin
kkkk
shahril:q4$ cat kkkk.bin | xxd -c 20
00000000: 456e 7465 7220 7465 7874 2079 6f75 2077 616e 7420  Enter text you want 
00000014: 746f 2065 6e63 7279 7074 3a0f 0d0a 0d0d 0a0d 0a    to encrypt:........

The output is the part that I highlighted, so the output will be :

0xf 0xd 0xa 0xd 0xd 0xa 0xd 0xa

Observing the above output, you must feel weird. How can suddenly "kkkk" produces 8 bytes hex while it should produce only 5 bytes hex (the xor-ed string + null terminator).

Hmm. something must be wrong here....

Firstly I thought that this behavior was produced by the encryptor.exe itself. So I studied the binary to observe whether this behavior is intended by the author or not.


So from above GIF, the encryptor function returns string containing the :

0xf 0xa 0xd 0xa

So above output hex length (4) + null terminator (1) = (5) output that we expected from the program.

So what is wrong here?

Null Terminator/Line Ending

There are one thing that needs to be clear out first, the behavior of line terminator between Windows and Unix-like OS is different.

Windows uses \r\n or 0xd 0xa for its line terminator.
Unix-like (Mac or Linux) uses \n or 0xa for its line terminator.

Read more here : http://www.cs.toronto.edu/~krueger/csc209h/tut/line-endings.html

The different between line terminator behavior might confuse many of us, especially for those who didn't know that Windows uses different line ending than most OS do.

For those who had been programming inside Windows before, you all must have the experience where some naïve editor such as Windows's Notepad doesn't line terminate the \n byte. It only terminates when we put \r\n (carriage return + newline) inside the text file.

Identifying The Problem

After observing the encryptor.exe with PE file identifier, it said the program was compiled using GCC MINGW-64w compiler under Windows.


To make the problem much more easier to observe, let us create a simple program using C, that will print only a newline character to the stdout (screen).

#include <stdio.h>
int main() {
    printf("\n");
    return 0;
}

We need to compile the source into two binary programs, which both ELF (under Linux) and PE (under Windows).


shahril:q4$ cat test.c 

#include <stdio.h>
int main() {
    printf("\n");
    return 0;
}

shahril:q4$ gcc test.c -o test_unix
shahril:q4$ x86_64-w64-mingw32-gcc test.c -o test_win.exe

And we try to run both of the programs, and pipe the stdout data into xxd (hex viewer).

shahril:q4$ ./test_unix | xxd -c 3
00000000: 0a       .
shahril:q4$ wine test_win.exe | xxd -c 3
00000000: 0d0a     ..
note: 0d0a is \r\n

From above output, we can conclude that, the Mingw GCC under Windows produces \r\n newline while Unix produces just \n newline.

Solution

So we know that encryptor.exe must also have converted the original \n into \r\n when it outputting the data into the stdout (screen).

We also know that encrypted.bin is the output from encryptor.exe.

However, encrypted.bin now contains the \r\n bytes that originally is just a \n. So how can we deal with this problem?

There is one tool inside Linux, that can automatically convert the \r\n bytes into \n. YES! dos2unix!

Let take a look again into the hex dump content of encrypted.bin :

shahril:q4$ cat encrypted.bin  | xxd
00000000: 250d 0d0a 180b 1416 040b 110d 0a04 070d  %...............
00000010: 0a 

The part that I highlighted is the \r\n hex bytes inside the encrypted.bin. So applying dos2unix into the encrypted.bin should remove the exceeded \r in front of \n byte.

shahril:q4$ dos2unix -f encrypted.bin 
dos2unix: converting file encrypted.bin to Unix format ...

Take a look again inside patched encrypted.bin content.


shahril:q4$ cat encrypted.bin  | xxd
00000000: 250d 0a18 0b14 1604 0b11 0a04 070a       %............

After having the good boy file, then we need to emulate the original encryptor.exe to decrypt the contents of converted encrypted.bin. So that purpose I created a simple Python script.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import sys, os

def main():

    # get file name from argument 1
    file = sys.argv[1]

    # get size in byte
    size = os.fstat(os.open(file, os.O_RDONLY)).st_size

    with open(file, "r") as f:

        byte = f.read(1)
        i = 0

        # i < size-1 => to skip processing last null terminator
        while byte and i < size-1:

            result = chr(ord(byte) ^ ord("dafa"[i % 4]))
            sys.stdout.write(result)

            byte = f.read(1)
            i += 1

    print ""

if __name__ == "__main__":
    main()

So, run the script, and we got the nice flag appears inside our terminal. :)

shahril:q4$ python decrypt.py encrypted.bin 
Allyoupeoplec

So the flag is "Allyoupeoplec"!

Till we meet again :)

Shahril, Alfarabi 2.0, UiTM Perlis

2 comments:

  1. nice one! sebab line termination tu ja aku dpt output pelik. pape pun congrats shahril and the team!

    ReplyDelete