Книга: Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software
Назад: Custom Encoding
Дальше: Conclusion

shows a small Python program that decodes a standard Base64-encoded string. Replace the example_string variable to decode the string of interest.

shows an example of a Python function that implements a NULL-preserving XOR encoding, as described earlier in this chapter.

shows a small Python script that translates the custom Base64 characters to the standard Base64 characters, and then uses the standard decodestring function that is part of the Python base64 library.

) provides a wide variety of cryptographic functions. Similar libraries exist for different languages. shows a sample Python program that performs decryption using the DES algorithm.

section. shows the function header plus the primary instructions that are a part of the encryption loop shown previously in .

, this function is labeled encrypt_Init.

  • We know that when we reach address 0x40122A, the encryption has been completed.

  • We know several of the variables and arguments that are used in the encryption function. These include the counter and two arguments: the buffer (lpBuffer) to be encrypted or decrypted and the length (nNumberOfBytesToWrite) of the buffer.

  • We have an encrypted file, the malware itself, and the knowledge of how its encryption function works. Our high-level goal is to instrument the malware so that it takes the encrypted file and runs it through the same routine it used for encryption. (We are assuming based on the use of XOR that the function is reversible.) This high-level goal can be broken down into a series of tasks:

    1. Set up the malware in a debugger.

    2. Prepare the encrypted file for reading and prepare an output file for writing.

    3. Allocate memory inside the debugger so that the malware can reference the memory.

    4. Load the encrypted file into the allocated memory region.

    5. Set up the malware with appropriate variables and arguments for the encryption function.

    6. Run the encryption function to perform the encryption.

    7. Write the newly decrypted memory region to the output file.

    In order to implement the instrumentation to perform these high-level tasks, we will use the Immunity Debugger (ImmDbg), which was introduced in . ImmDbg allows Python scripts to be used to program the debugger. The ImmDbg script in is a fairly generic sample that has been written to process the encrypted files that were found with the malware, thereby retrieving the plaintext.

    follows the high-level tasks closely. immlib is the Python library, and the immlib.Debugger call provides programmatic access to the debugger. The open calls open files for reading the encrypted files and writing the decrypted version. Note that the rb option on the open commands ensures that binary characters are interpreted correctly (without the b flag, binary characters can be evaluated as end-of-file characters, terminating the reading prematurely).

    The imm.remoteVirtualAlloc command allocates memory within the malware process space inside the debugger. This is memory that can be directly referenced by the malware. The cfile.read command reads the encrypted file into a Python buffer, and then imm.writeMemory is used to copy the memory from the Python buffer into the memory of the process being debugged. The imm.getRegs function is used to get the current register values so that the EBP register can be used to locate the two key arguments: the memory buffer that is to be decrypted and its size. These arguments are set using the imm.writeLong function.

    The actual running of the code is done in two stages as follows, and is guided by the setting of breakpoints using the imm.setBreakpoint calls, the setting of EIP using the imm.setReg("EIP",location) calls, and the imm.Run calls:

    • The initial portion of code run is the start of the function, which sets up the stack frame and sets the counter to zero. This first stage is from 0x004011A9 (where EIP is set) until 0x004011b7 (where a breakpoint stops execution).

    • The second part of the code to run is the actual encryption loop, for which the debugger moves the instruction pointer to the start of the cryptographic initialization function at 0x004011f5. This second stage is from 0x004011f5 (where EIP is set), through the loop one time for each byte decrypted, until the loop is exited and 0x0040122a is reached (where a breakpoint stops execution).

    Finally, the same buffer is read out of the process memory into the Python memory (using imm.readMemory) and then output to a file (using pfile.write).

    Actual use of this script requires a little preparation. The file to be decrypted must be in the expected location (C:\encrypted_file). In order to run the malware, you open it in ImmDbg. To run the script, you select the Run Python Script option from the ImmLib menu (or press ALT-F3) and select the file containing the Python script in . Once you run the file, the output file (decrypted_file) will show up in the ImmDbg base directory (which is C:\Program Files\Immunity Inc\Immunity Debugger), unless the path is specified explicitly.

    In this example, the encryption function stood alone. It didn’t have any dependencies and was fairly straightforward. However, not all encoding functions are stand-alone. Some require initialization, possibly with a key. In some cases, this key may not even reside in the malware, but may be acquired from an outside source, such as over the network. In order to support decoding in these cases, it is necessary to first have the malware properly prepared.

    Preparation may merely mean that the malware needs to start up in the normal fashion, if, for example, it uses an embedded password as a key. In other cases, it may be necessary to customize the external environment in order to get the decoding to work. For example, if the malware communicates using encryption seeded by a key the malware receives from the server, it may be necessary either to script the key-setup algorithm with the appropriate key material or to simulate the server sending the key.

    Назад: Custom Encoding
    Дальше: Conclusion

    sss
    sss

    © RuTLib.com 2015-2018