• Malware Theory
    • Anti-Analysis
      • Anti-Debugging
      • Anti-VM
    • Persistency
    • Listener
    • Communication
    • Initial Access
      • Tricks
      • Executables
      • Containers
        (MOTW Bypass)
      • Delivery
    • Shellcode
      • Execution
      • Preparation
        • Encoding
        • Encryption
        • Placement
        • Generators
          (Msfvenom)
#Malware Theory #Shellcode

Shellcode

Shellcode is a piece of code that is responsible for enabling the attacker to execute commands on a system (shell interaction). It has the most important function in malware. This is usually native machine code represented in hexadecimal form. Looking at the code of malware the shellcode is usually easy to recognize. It looks like this:

// Fake shellcode in C (usually it's longer)
unsigned char buf[] = 
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
"\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
"\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5"
"\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
"\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5";

Because it is machine code, it must be written or generated for a specific processor architecture. Basically, all the rest of the malware code (written in C or C#, for example) is used to execute the shellcode one way or another. There are a lot of techniques for executing shellcode so as not to attract the attention of AV or EDR software. Shellcode is often generated by open source tools, so antiviruses know their signatures. To confuse them, shellcode is usually encoded and/or encrypted. It can also be placed in various sections of the executable (PE) file format.

Why machine code?

There is an important reason why shellcode is written in Assembly and put into malware in machine code form. Position independent machine code can be fully injected anywhere in memory and executed. Machine code is self-sufficient, we can take the whole thing, copy it to any memory location (such as another process memory) and execute it. It should work anywhere. Original shellcode location can be erased safely. This is not feasible for functions written in C. Using C we can't just take the function code and copy it elsewhere because we do not have absolute control over it. Functions written in C are compiled to run within a specific well-known executable file. Compilers do a lot of magic and we can't rely on unpredictable C-compiled code. We need total control over the shellcode to perform many of the execution techniques. Many techniques work as a fire-and-forget and shellcode must work well in an unfamiliar environment. In addition, machine code can decrypt and decode itself relatively easily anywhere.

Children

Shellcode
Execution
Preparation
Encoding
Encryption
Placement
Generators