Contents

Zero2Auto: Custom Sample

Overview

This is an analysis of a custom sample from Zero2Auto, my objective was to develop a script that automates the decryption process for the first stage of the malware. After that, I dive into a more in-depth analysis of its behavior and structure. Hope you enjoy the process and find it insightful!

drawing

The Case

During an ongoing investigation, one of our IR team members managed to locate an unknown sample on an infected machine belonging to one of our clients. We cannot pass that sample onto you currently as we are still analyzing it to determine what data was exfilatrated. However, one of our backend analysts developed a YARA rule based on the malware packer, and we were able to locate a similar binary that seemed to be an earlier version of the sample we’re dealing with. Would you be able to take a look at it? We’re all hands on deck here, dealing with this situation, and so we are unable to take a look at it ourselves. We’re not too sure how much the binary has changed, though developing some automation tools might be a good idea, in case the threat actors behind it start utilizing something like Cutwail to push their samples.

Analysis

To start, let’s take a look at the sample in DiE. All sections appear normal, except .rsrc, which has very high entropy.

drawing

Looking at the imports, we only see kernel32.dll and a few suspicious functions

drawing

This raises suspicion that functions may be imported dynamically using LoadLibrary and GetProcAddress. Let’s jump to IDA Pro for a closer look.

drawing

First, we see strange strings being pushed before calling sub_401300. After that, LoadLibrary and GetProcAddress are called. This suggests dynamic API resolution after decrypting the function names. Let’s analyze sub_401300.

The function implements ROT-13, shifting each character by 13 positions in a fixed alphabet:

drawing

With that in mind, here are the decoded strings observed during execution:

Before After
.5ea5/QPY4// kernel32.dll
yb14E5fbhe35 LoadResource
F5gG8e514pbag5kg SetThreadContext
pe51g5Ceb35ffn CreateProcessA
I9egh1/n//b3rk VirtualAllocEx
E5fh=5G8e514 ResumeThread
t5gG8e514pbag5kg GetThreadContext
Je9g5Ceb35ffz5=bel WriteProcessMemory
I9egh1/n//b3 VirtualAlloc
E514Ceb35ffz5=bel ReadProcessMemory
F9m5b6E5fbhe35 SizeofResource
s9a4E5fbhe35n FindResourceA
yb3.E5fbhe35 LockResource

There’s a lot happening in each function, so to summarize:

This sample creates a suspended copy of itself using CreateProcessA with the 4th parameter set to 0x00000004. This is confirmed via debugging.

drawing drawing

Next, it locates the .rsrc section (with high entropy) and loads it.

drawing

Then it retrieves the size using SizeofResource, which is 0x0001541C.

drawing

It then calls VirtualAlloc, but with size 0x00015400

drawing

This is slightly suspicious, and with the next piece of code, everything starts to make sense:

drawing

Its a RC4 decryption routine, so what is probably happen is that it is considering only the content of .rsrc after 0x1C bytes from the start and maybe before that is the key for decryption

drawing

Let’s debug until we find something related to the decryption key in the routine, and… there it is! The key is kkd5YdPM24VBXmi, and it’s located right before the encrypted content. Nice!

drawing

Using CyberChef, we can decrypt the .rsrc content after the key to reveal a second executable:

drawing

Using this knowledge, I created a Python script to automate the decryption of the embedded executable: https://github.com/n0tr3alX/Zero2Auto-Custom-Sample

let’s continue the analysis. Once again one value caught my attention: 0xEDB88320 a well-known constant from the CRC-32 hashing algorithm, indicating API hashing is being used.

drawing

And looking a bit further it is possible prove this theory, a classic routine of load library, a loop to check the hash of each import, and then GetProcAddress to get the function addresses.

drawing

To speed things up, I used hash db to look up the CRC-32 hashes.

drawing drawing

So lets take a look again in the main function again, it checks whether the filename is svchost.exe. If not, it executes anti-analysis and anti-debugging routines using IsDebuggerPresent, CreateToolhelp32Snapshot, Process32FirstW, and Process32NextW, looking for x32dbg.exe (easily bypassed by renaming it).

drawing drawing

But both of then have the same core functions:

drawing

It first resolves some Windows APIs that will connect to a URL and then retrieve its content using InternetReadFile. After that, a value located at xmmword_413C7C and xmmword_413C8C is processed: each character is shifted four positions to the left (using ROL1), then XORed with 0xC5.

drawing

So lets use cyberchef to do it!

drawing

And we have a pastebin URL, that contains another URL.

drawing drawing

This URL is passed to a function that appears to retrieve the content from it. (Note that cruloader is set as the user agent.)

drawing drawing

So the result of this function is the URL inside the Pastebin. Moving on with the execution, we again have the same call to the function that retrieves the content of the URL, now using the URL that points to the PNG file

drawing

After that, it creates a directory and a file in the user’s temp folder, and the PNG file is written to disk.

drawing drawing

Then it starts doing something really interesting: it searches for the string redaolurc (which is cruloader reversed) within the content of the PNG, likely to locate a specific region of the file.

drawing drawing

Right after that, it jumps 9 bytes (to skip the cruloader string) and starts performing a XOR operation with 0x61

drawing

So let’s do this in CyberChef… and there it is, the final binary!

drawing

After this, it performs a classic process hollowing technique on a suspended svchost.exe.

drawing drawing drawing

Executing the final binary…..

drawing

Concluding Thoughts

Zero2Auto is an amazing course, and each chapter is really rich in knowledge. Hopefully, this can teach something new!

Thank you for taking the time to read this analysis! If you have any questions, insights, or suggestions, feel free to reach out.