MemITM: Tool to make in memory man in the middle
What’s the MemITM tool?
The MemITM (Mem In The Middle) tool has been developed in order to easily intercept “messages” in Windows processes memory. We developed a lot of custom memory interception tools in order to capture network messages before encryption, or IPC messages, and to be able to inspect them or alter them to do some fuzzing. Each tool was really custom, not generic, implemented in C/ASM and was not easy to use/maintain/adapt.
The MemITM tool has been developed in order to address these problems, and consists in :
- an IDA Python script, which generates a “config” file, indicating where and how the interception points have to be placed (relative address, how to find the buffer and its size, how to place the hook, etc.) ;
- the DLL file, which will be injected into the target process and will load the config and places the hooks ;
- a DLL file injector, which will load the DLL in the target process ;
- a python script, which communicates with the injected DLL/hooks, and gets in real-time the intercepted buffers (and can alter them) in really simple callbacks you can modify as you want.
How does it work internally?
The IDA Pro script embeds a simple “hooking” engine, which allows moving several instructions to a specific area (derived from our DIMCT tool). It must handle lots of corner cases, such as memory relative instructions, cross-references, etc. and will probably display lots of “can’t install hook here” if you try intercepting really small basic blocks (<5 bytes for x86 binaries, <12 bytes for x64 ones) which contain multiple cross-references. For more information, just read the source code :).
It generates the following information in the config file:
- the module name;
- the relative address of the interception point;
- the interception hook area (aka “T1 trampoline”), which places the buffer/length into
RDXand calls the DLL log routine;
- the restoration hook area (aka “T2 trampoline”), which restores the context and executes replaced instructions before returning to the interception point;
- the restoration hook area relocations, for relative instructions which have been converted to absolute ones and must be patched.
The DLL injector is a simple DLL injector (CreateRemoteThread/LoadLibraryA stuff).
The DLL itself initiates a shared memory area and waits for the config data (the shared memory area has 3 generic fields: the shared memory message ID, the message size and the message buffer). Once received, it parses and installs the hooks in memory, and no config update will be allowed after this (you must kill the process if you want to set up new hooks). Any placed hook will land in the genericHookFunction DLL function. This function just fills the memory area (protected with critical sections) with the buffer data, its size and the message ID (set in higher bits of the shared memory message ID field). In order to notify the python process, 2 events are used to signal new messages and to wait for the process to patch them (timeout is 2 seconds). If the buffer has been updated, the original buffer is modified too.
The memitm.py script runs the injector process and waits for the shared memory to be created. It then sends the configuration and waits for the message event. When received, the shared memory is read and the logger and fuzzer functions are called with the buffer, the process ID and the message ID. If the logger function returns a different buffer than the original one and its size is equal, it is written to the shared memory area. The “ACK” event is then signalled, and the script waits for a new message.
git clone https://github.com/AMOSSYS/MemITM.git
Copyright (C) 2018 0x00ach