
Ivy is a payload creation framework for the execution of arbitrary VBA (macro) source code directly in memory. Ivy’s loader does this by utilizing programmatical access in the VBA object environment to load, decrypt and execute shellcode.
To view the latest version of Ivy or to submit an issue, reference https://github.com/Tylous/Ivy.
If you want to learn more about the techniques utilized in this framework as well as the defensive measure to help defend against it, please take a look at Article.
Ivy is a payload creation framework for the execution of arbitrary VBA (macro) source code in memory. Ivy’s loader does this by abusing programmatical access in the VBA object environment to load, decrypt, and execute shellcode. This technique is as close as possible to be truly fileless, as most fileless attacks these days require some sort of files being dropped on disk, as a result bypassing standard signature-based rules for detecting VBA code. Typical VBA payloads have the following characteristics:
By running purely in memory, these behavior characteristics makes it harder to be detected by EDRs.
Ivy’s loaders are encrypted using RC4 encryption (AES encryption causes a lot of bloat and takes forever for VBA to decrypt) and then broken into separate strings, preventing any sandboxing from recognizing these strings as encrypted strings that should be investigated. This also prevents any decoding mechanism from recognizing these payloads as anything but garbage characters.
Ivy’s loader first performs a registry query to enable “Trust access to the VBA project object mode”. This registry key value is stored in user-mode which allows the user to modify the value without requiring any elevated permissions. The registry value is set from a zero to 1; if the registry key does not exist Ivy will create it with a value of “1”. With this value enabled, programmatical access is allowed to the VBA object environment from a different process.
Once this is done the loader will then spawn a hidden Excel process and load the encrypted strings into a VBA function. This is done by using ActiveX to simulate the GUI actions of doing the same task. This helps bypass a lot of traditional controls in place to monitor for execution. As a result, the decrypt function and shellcode are moved from one memory buffer to another, never touching disk. Finally, the loader uses command-GUI calls and executes the run function, which simulates the act of clicking on the run macro button in the GUI panel of VBA, beginning the decryption function, followed by the actual execution of the shellcode.
IMPORTANT
The target endpoint must have Microsoft Office installed and activated in order to run because Ivy relies on a abusing the programticatical access to the VBA environment of Microsoft office.
This allows Ivy to use low-level system calls to build its own version of the Windows function WriteProcessMemory by referencing the direct memory address and register values indirectly. Ivy can overwrite sections of memory that are not writable without calling any of the memory change API functions. This is done because of a feature of WriteProcessMemory which temporarily changes the permissions of the region of memory to writeable (if you have sufficient privileges, which we do since we own the process). It writes the value and restores the original permissions without calling the VirtualProtect function, instead it automatically calls the associated syscall (NtProtectVirtualMemory).
Ivy does not utilize its own version of NtWriteVirtualMemory because this process of temporarily changing the memory permissions would not occur, meaning the protection of the specific memory address would not be modified and the execution would fail. This is a “feature” Microsoft has released to make debuggers more stable. As debuggers want to modify memory on the fly, they can simply modify a section without having to perform multiple tasks. (See devblogs.microsoft.com for information)
Let’s take a look at the series of events that an EDR would see:
Once all the EDR hooks have been flushed out it, the loader then performs its normal action to establish a remote session.
Ivy address this by unhooking common system DLLs EDR's hook, this includes:
When using unhook with a payload type Inject Ivy's loader will first unhook the office process removing the edr from it and then remove the hooks in the injected processs. These ensures that both processes are hook free, preventing any telemetry from the parent and child process from being sent to the EDR.
Using the same technique to unhook, Ivy can patch ETW functions, preventing any event from being generated by the process. ETW utilizes built-in Syscalls to generate this telemetry. Since ETW is a native feature built into Windows, security products do not need to "hook" the ETW syscalls to gain the information. As a result, to prevent ETW, Ivy patches numerous ETW syscalls, flushing out the registers and returning the execution flow to the next instruction. Patching ETW is now default in all loaders, if you wish to not patch ETW use the -noetw command-line option to disable it in your loader.
Ivy was developed with go.
The first step as always is to clone the repo. Before you compile Ivy, you'll need to install the dependencies. To install them, run following commands:
go get github.com/fatih/color
go get github.com/KyleBanks/XOREncryption/Go
Then build it
go build Ivy.go
$ ./Ivy -h
___ ___ ___ ___ ___
|\ \ |\ \ / /||\ \ / /|
\ \ \\ \ \ / / /\ \ \/ / /
\ \ \\ \ \/ / / \ \ / /
\ \ \\ \ / / \/ / /
\ \__\\ \__/ / __/ / /
\|__| \|__|/ |\___/ /
\|___|/
(@Tyl0us)
The suffering. The pain. Can't you hear them?
Their cries for mercy?