One of my most recent coding projects on GitHub has been an effort to better learn C#. One of my recent certifications utilized C# often to interact with Windows processes. I found this to be extremely interesting and wanted to play around with it more. The course also covered a lot of basic antivirus evasion techniques for penetration testing and red team engagements. Since I will be a red team intern this summer I figured it would be great practice. Much of the code is translated from the C code outlined in this PDF. If you are interested in this project, more details can be found on my GitHub.
Allocates a ~1.07GB byte array and zeroes it out, then checks if the last value is equal to 0. The theory is that an antivirus engine will forgo zeroing out all this memory, thus the program will quit before the shellcode runner can be examined.
Iterates through a for loop nine hundred million times in an effort to discourage AV from emulating the rest of the program.
This code attempts to open PID 4, which is a SYSTEM process. In theory, a normal user should not be able to open this process while an AV engine would be able to. This would return a null handle when run by a legitimate user. The Win32 API OpenProcess is imported for this code snippet. This API is often used in malicious code so this evasion technique may generate more detections. 0x001F0FFF is the hexadecimal representation of PROCESS_ALL_ACCESS.
This code makes an HTTP request to a fictitious domain, if no response is received (expected outcome) the shellcode runner will execute. If a response is received, this indicates some shenanigans are going on. AV sandboxes often are not allowed to make outbound requests and will instead reply with a fake response so the code may continue execution. Thus, if the code fails it is in the real world, otherwise it might be in an AV sandbox.
If the target's username is known, then it may be possible to specify specific actions that will only run in the context of that user. For example, here we are writing a file to the desktop of the user "User". Then, the contents of that file are read back, if they match what was written, the shellcode will execute.
Some AV engine simply can not emulate all known Windows APIs. This means if they encounter an unknown API, it will stop examining the malicious program. Here we are imported the Win32 API VirtualAllocExNuma which is used to configure memory management in multiprocessing systems. If the memory allocated is not NULL, then the shellcode will execute.
Similar logic to 06, some AV emulators will return a failing condition when FlSAlloc is called. For future reference, UInt32 is the C# equivalent of DWORD and IntPtr.Zero is the equivalent of NULL. 0xFFFFFFFF equates to -1 which is equivalent to failing conditions, the original code uses FLS_OUT_OF_INDEXES.
In this example, GetProcessMemoryInfo is imported then information is gathered about the current process. If the the current working set (amount of memory a process requires in a given time interval) is less than 3.5MB then the shellcode executes. Much of this code can be found from the "Sample Code" section here.