ZeroDays CTF 2024 RE - 4
The fourth challenge is named ‘acup.exe’.
Upon analysis with Detect-It-Easy, it is revealed that the file is packed using PyInstaller.
PyInstaller is a popular tool used to convert Python scripts into standalone executable files. It bundles the Python interpreter and all necessary dependencies into a single executable, making it easier to distribute Python applications to users who do not have Python installed.
To unpack and retrieve the compiled Python bytecode, pyinstxtractor.py available here, is utilized.
After downloading and executing the pyinstxtractor.py file according to the provided readme instructions, probable entry points and extracted Python bytecode files are obtained.
We analyze the generated acup.pyc file, a probable entry point, using the same method as described in ZeroDays CTF 2024 RE - 1, employing pycdc.exe.
The generated output is provided below.
The code employs obfuscation techniques such as unintelligible variable names, base64 encoding, and decryption logic to unveil the final flag.
To comprehend the provided code, we'll dissect it section by section and examine the following code.
The code retrieves clipboard data, ideally input by the user, processes it through the ebg46() function, and compares its lowercase version to "zvfpuvrs_znantrq". If unequal, the program sleeps and retrieves clipboard data again, repeating the process once again to check if they match. If matched, the variable rfno is created by converting the lowercase clipboard data to bytes, base64 encoding it, and then UTF-8 decoding it. Subsequently, variable k is formed using parts of the rfno variable.
Let's examine the ebg46() function in detail.
The given function, ebg46(), appears to be a simple Caesar cipher implementation with a fixed shift of 13 characters (commonly known as ROT13). It first generates a lowercase alphabet string c using a lambda function and shifts it by 13 characters to create the cipher key t. Then, it defines a lambda function rc to perform the character substitution based on the shift. Finally, it applies the substitution to each character in the input string x using another lambda function and returns the resulting string.
Based on the observed pattern, it can be inferred that applying the ROT13 cipher to the expected output "zvfpuvrs_znantrq" results in the original string. This is due to the property of ROT13, where applying the cipher twice (ROT13(ROT13(x))) returns the original input string x.
Utilizing CyberChef, we can execute the operation on the expected string, “zvfpuvrs_znantrq”, to obtain the input string required for the second condition to match. However, since there is no scenario where both if conditions in the previous code are met, this challenge cannot be resolved by executing the program. Instead, it can only be resolved through static analysis of the code.
As displayed above, the expected input for the second condition to match is "mischief_managed".
Now, let's comprehend the final section of the code.
Firstly, let's calculate the value of the variable rfno, which is "bWlzY2hpZWZfbWFuYWdlZA==".
Now, the variable k can be generated, resulting in “puca”.
To understand the arc4 import and its usage, we examine an example of its usage, sourced from here.
The arc4 package is a Python implementation of the ARCFOUR (RC4) cipher, prized for its compactness and exceptional speed, as indicated on the referenced page above.
Upon comparing this with the preceding code, it's evident that the variable k
is utilized as the key. Next, the variable erucvp
is converted from hexadecimal, decrypted using RC4, and decoded as UTF-8 to form the flag string.
These operations can be replicated in CyberChef to manually retrieve the flag.
I have also written a Python script to generate the decoded text utilized to form the key and the key itself.
The acquired flag is as follows -