We were given a 64-bit ELF file and as the file name suggests, it was a compiled Go file. The file does not need any runtime hence there are too many functions which makes reversing difficult.
I was looking for some pointer or obvious place to start with; After running the file, I saw the message “Specify the file to package as argv1, will overwrite, existing”.
I tried searching the strings with no success, so I looked for a function that handles output and I found it: ‘fmt_Println’.
Search for functions that call ‘fmt_Println’ led me to the address 0x40120C; I scrolled up and found ‘main_step1’, ‘main_step2’, ‘main_step3’ and ‘main_step4’. I set a breakpoint at the beginning of the function and ran the file; The following picture shows the argument check after the breakpoint is triggered:
This function reads a part of memory and Xors it with 0x69 and generates ‘golang-or-bust’; Later I found out that it’s the password for the protected Zip file.
Most of the work is done in the ‘main_step2’: it reads the input file, encrypts it and compresses it into a Zip file. By tracing ‘github_com_alexmullins_zip___FileHeader__SetPassword’ function, I found out that the password is ‘golang-or-bust’. Also the exact code used in the program is copied from “github.com/alexmullins.zip”
Finally it’s time to review ‘main_step4’ (ignoring the ‘main_step3’); Here’s the algorithm used in this function:
1- Take the first and second byte
2- Subtract the first byte from the second
3- Replace the first byte with the result from step 2
4- Do it until the end of the file.
We have to reverse the above procedure: from the end of the file to the beginning. Here’s a quick script:
f = open('flag.enc', 'rb').read() b = bytearray(f) i = len(b)-1 o = '' while i>0: res = ((b[i]) + (b[i-1])) b[i-1] = (((b[i]) + (b[i-1])) & 255) o += chr(res & 255) i-=1 open('flag.zip', 'wb').write(o[::-1])
The output Zip file needs repair, so I used WinRAR to fix it and got the flag with the password we acquired earlier on:
Though I found the flag, it was late and we lost the 250 points because of less than a minute of being late 🙁