Let's now discuss emulation. Emulation is a technology
which is used by many antivirus solutions.
It gives the antivirus a chance to gain some insight into the behavior
of a piece of code without actually executing it.
An emulator will try to mimic a real operating system.
The reason being that if a piece of code calls a given API, the
emulator needs to ensure that it returns a valid response or else
the code might not behave as it would on a real system. Artifacts
are recorded during emulation,
which can be used to gain insight into what the code
will do when launched on a real system.
Unfortunately,
emulation is expensive and will, at some point, have to stop
to avoid consuming too many CPU cycles.
Different emulators will have different stop conditions, such as the
number of CPU instructions which have occurred,
the elapsed time, or the number of API calls which were observed.
Let's now take a look at what emulation looks like in practice.
Let's once again generate a Meterpreter stager using
the raw format and send it to a file.
I chose to use Speakeasy, a free emulator which is developed by FireEye,
a well‑known cybersecurity company.
We can run Speakeasy with the following command.
The ‑r specifies that this is raw shell code. The ‑a is
used to specify the architecture.
In our case, we chose to generate a 64‑bit stager.
The ‑t option is used to specify the file name containing the shell code,
which we want to emulate.
The ‑o specifies where we want to store the emulation report and
the ‑d where we want to store memory dumps.
When we run the code through the emulator,
we can immediately see very interesting output.
We can see the call to LoadLibrary,
which, as we saw in the Meterpreter Deep Dive module is
used to load the wininet library.
We can also see that there were many calls to APIs
exported by the wininet library.
We can even see the URI which would be used when connecting to the handler.
You can also see the call to VirtualAlloc,
which is something we also observed when using API monitoring and ETW providers.
The difference here is that the code has not been run on
the endpoint. It has just been emulated.
This gives us, or an antivirus solution,
the ability to block something before it actually happens.
For instance,
we could imagine that the antivirus file system filter driver is
informed that an executable file is being written to disk.
The antivirus could send the file through an emulator to
figure out what it would do if executed.
If we take a closer look,
we can see that the emulation crashed after the calls to InternetReadFile.
This makes sense because our payload was not downloaded.
Bear in mind that a dummy payload could be sent back by the
emulator to check what would have happened if a Meterpreter
payload had been sent back to the stager.
This is what the emulation looks like at a high level.
On the left,
we have the antivirus, which can send the file or
script containing code to the emulator.
The code is then emulated in a fake environment. Artifacts are
collected and sent back to the antivirus,
which can make an informed decision on whether the submitted sample is
malicious or not by analyzing the collected artifacts.
These artifacts can relate to APIs,
which would have been called, as well as memory dumps.