Transcript
I took part in Nexus’s Kuwait CTF event and my team came 10th out of 60 competing teams. It was a wonderful opportunity to get real world practical experience in multiple Cybersecurity categories. In this write-up we will focus on one specific challenge called Undocumented.
init main()
We start by downloading the Undocumented.7z
file and take note of the challenge’s description since it can contain important clues.
Contents of extracted Undocumented.7z
:
└── Undocumented
├── ouput.bin
└── UND.exe
output.bin
– contains a long string that looks to be encryptedUND.exe
– is a 64bit windows binary
Challenge’s Description:
From what I remember it went along the lines of “This program is not supported anymore but no worries because we are reverse engineers”
De-compiling UND.exe
I recommend checking out this site first to see how different de-compilers handle the same binary. Pick the program that seems to return the most concise de-compilation of the binary.

I will be using Binary Ninja (BN).
Main Function
Typing “main” at the symbol search option located at the top left of BN, will navigate us to the location of the main function. Also try switching between different view settings to better understand the code, you can do this by tinkering with the top middle section.

I am using “High Level IL” but also check out “Pseudo C” for a much more familiar syntax or go with “Disassembly” for Assembly code analysis.
Click Here For Main Function Code
1 int64_t main()
2
3 void s
4 __builtin_memset(&s, c: 0xcccccccc, n: 0x160)
5 int64_t rax_1 = __security_cookie ^ &s
6 j_sub_140011fd0("Welcome to my OneofAKind encrypt…", j___CheckForDebuggerJustMyCode(&data_1400230f2))
7 int64_t var_230 = 0
8 void file
9 __builtin_strncpy(dest: &file, src: "C:\Users\tod\Desktop\flag.txt", n: 0x1e)
10 struct _iobuf* rax_2
11 int64_t rdx_1
12 rax_2, rdx_1 = fopen(&file, mode: U"r")
13
14 if (rax_2 == 0)
15 j_sub_140011fd0("Cannot open file", rdx_1)
16
17 fseek(public_stream: rax_2, offset: 0, whence: 2)
18 var_230 = sx.q(ftell(public_stream: rax_2))
19 fseek(public_stream: rax_2, offset: 0, whence: 0)
20 int64_t buffer = malloc(size: var_230)
21
22 if (buffer == 0)
23 fclose(public_stream: rax_2)
24 struct _iobuf* rax_5
25 int64_t r8_1
26 rax_5, r8_1 = __acrt_iob_func(id: 2)
27 j_sub_140011b00(rax_5, "Memory allocation failed\n", r8_1)
28 exit(return_code: 1)
29
30 if (fread(buffer, element_size: 1, element_count: var_230, stream: rax_2) != var_230)
31 fclose(public_stream: rax_2)
32 free(block: buffer)
33 j_sub_140011b00(__acrt_iob_func(id: 2), "Error reading file %s\n", &file)
34 exit(return_code: 1)
35
36 fclose(public_stream: rax_2)
37 char var_190
38 __builtin_strncpy(dest: &var_190, src: "badr7la3", n: 8)
39 char* var_170 = &var_190
40
41 if (j_sub_140011830(var_170, buffer, 8, var_230.d) != 1)
42 j_sub_140011fd0("Error %x", zx.q(GetLastError()))
43 else
44 j_sub_140011fd0("Encrypted successfully and here …", buffer)
45
46 void file_1
47 __builtin_strncpy(dest: &file_1, src: "C:\Users\tod\Desktop\ouput.bin", n: 0x1f)
48 struct _iobuf* rax_10 = fopen(file: &file_1, mode: "wb")
49
50 if (rax_10 == 0)
51 j_sub_140011b00(__acrt_iob_func(id: 2), "Failed to open file for writing:…", &file_1)
52
53 uint64_t rax_12 = fwrite(buffer, size: 1, count: var_230, stream: rax_10)
54 fclose(public_stream: rax_10)
55
56 if (rax_12 == var_230)
57 j_sub_140011fd0("Buffer successfully written to f…", &file_1)
58 else
59 j_sub_140011b00(__acrt_iob_func(id: 2), "Error occurred while writing to …", &file_1)
60
61 void var_258
62 j__RTC_CheckStackVars(&var_258, &data_14001ae60)
63 j___security_check_cookie(rax_1 ^ &s)
64 return 1
I tried running the UND.exe
in my windows virtual machine and was presented with a missing DLL error. I remembered that the description of the challenge did say that “This program is not supported anymore” so I continued with my static analysis.
Looking at the code we notice 2 important lines
- 9 __builtin_strncpy(dest: &file, src: “C:\Users\tod\Desktop\flag.txt”, n: 0x1e)
- 38 __builtin_strncpy(dest: &var_190, src: “badr7la3”, n: 8)
Line 9 looks to be storing a flag.txt file path inside buffer “&file”, this might be our flag in plaintext so lets keep an eye if the content of this file will be used later on.
Line 38 is copying the string “badr7la3” into the buffer “&var_190” , would be a good idea to rename “&var_190” to something we can recognize later on since this step will rename ALL instances of “&var_190” and make the code more readable.
Looking around more we see that the “flag.txt” has been opened and read and stored in a buffer called “buffer” (line 12 and 17 to 36 ), then used as an argument for function “j_sub_140011830” (line 41) along side the “badr7la3” string and the decimal 8 and “var_230.d” which is the length of the data stored in the “flag.txt”.
Following the “j_sub_140011830” function (double click on it) we see that it passes its arguments to another function called “sub_140011830” we will follow this new function.
“sub_140011830” Function
The most noticeable items here is the “Advapi32.dll” and “SystemFunction032”. A quick google search tells us that “SystemFunction032” is used for encrypting and decrypting data using the Windows Data Protection API (DPAPI), specifically RC4 encryption.
Decrypting The “output.bin” File Using RC4 Encryption
Using the information we gathered from our static analysis we theorize that the string “badr7la3” was used as the encryption key to encrypt the contents of “flag.txt” and return a output file called “output.bin” which we currently have access to.
Lets first upload the “output.bin” to this site to get the base64 encoded text.
xUpgm98fODLOWHHqJoHxuYFzU+oC04hfsCA6WFigtR96fhzcXtq3TgiRQnIQa97VE6RAHg==
Now lets use this site to convert the base64 to binary.
11000101 01001010 01100000 10011011 11011111 00011111 00111000 00110010 11001110 01011000 01110001 11101010 00100110 10000001 11110001 10111001 10000001 01110011 01010011 11101010 00000010 11010011 10001000 01011111 10110000 00100000 00111010 01011000 01011000 10100000 10110101 00011111 01111010 01111110 00011100 11011100 01011110 11011010 10110111 01001110 00001000 10010001 01000010 01110010 00010000 01101011 11011110 11010101 00010011 10100100 01000000 00011110
Finally we will use this site to input our binary data along side our encryption key string “badr7la3” to decode the binary and if our theory is right then the plaintext “flag.txt” string should be returned.

Press the “DECRYPT/ENCRYPT” button and you should now be able to see the flag string.
Thank you for reading this write-up and I hope it will help you to solve many more reverse engineering challenges.
Your words glow with authenticity — like candlelight in a quiet room.