Random Top Mower Techniques: An Overview of Advanced Malware Development Techniques
0:00:19 Knowledge Sharing: The speaker emphasizes the importance of sharing knowledge and not keeping it confined.
0:01:34 Vector Exception Handling: An application can register a handler that gets called whenever an exception occurs, differing from structured exception handling by not being frame-based. These handlers are stored as a linked list.
0:02:40 Exception Information Structure: Whenever an exception occurs, the registered handler receives a structure containing exception information and a captured context, including register values and the instruction pointer.
0:04:45 Exception Handling Behavior: If no exception handlers can successfully deal with the exception, then the program will most likely crash.
0:06:12 Removing Vector Exception Handlers: The goal is to obtain the head of the linked list of exception handlers and then remove them. The presenter makes clear that the method presented is not the only way, and there are many other, potentially better ways to do so.
0:08:50 Obtaining Linked-List Head: Add a dummy exception handler to return a pointer, then cast it and compare it. Find a linked list entry that is located in the dot dot section for ntdll.
0:11:10 Restoring Vex Handlers: When restoring, DecodePointer must be called on the function address (vector handler), as AddVectoredExceptionHandler encodes the pointer.
0:11:57 DLL Load Notifications: DLL load notifications register for a notification when a DLL is first loaded and unloaded. The notification is a callback to a function defined by the user, containing information about the DLL.
0:13:37 Registering and Using DLL Notifications:LdrRegisterDllNotification is used, pointing to a callback, and saving a cookie. The cookie is used as an internal structure. Calling LoadLibrary will trigger DLL Load Notifications.
0:14:59 Removing DLL Notifications: Similar to Vex, register a fake notification, find the head (again, in the .data section of ntdll), and unlink all entries.
0:18:11 Work Items: If shell code needs to load an HTTP library, work items can be used so that the image load routine in the kernel will not be triggered. They function essentially as a thread pool.
0:19:57 Work Item Execution: You can control the function address and pass a context. The context is passed as the first parameter. Load the library with RtlQueueWorkItem or RtlRegisterWait.
0:22:00 Circumventing Work Item Parameter Limitation: NTContinue can be used for work items to set up all arguments in registers (RCX, RDX, R8, R9), useful for circumventing ETW threat intelligence (ETWTI).
0:23:44 Compile-Time Tricks (Lowering Entropy): Define an array and populate it with the same character, then store it in either the .text or .data section to raise the entropy of these sections.
0:24:40 Lowering Entropy: Store this fake array in the dot Tech section. This section will increase, and the entropy will lower.
0:25:40 Entropy is Suspicious: A packed binary has a high entropy. By lowering the entropy, it can be as suspicious as high entropy.
0:26:11 Compile-Time API Hashing: Compile-time API hashing can be done efficiently in C++ using compile-time evaluation.
0:27:13 Compile-Time Evaluation: C++ compile time evaluation allows caching strings that can part-time, making it easy to change the hashing algorithm.
0:28:12 Hardware Breakpoints: Every thread has its own context, and this context contains debug registers. Hardware breakpoints involve setting debug registers and using vectored exception handling to capture debug register exceptions.
0:28:39 Hardware Breakpoints: Registers DR0-DR3 specify addresses, while DR7 specifies conditions to trigger exceptions on those addresses. Hardware breakpoints can be set and removed with syscalls.
0:30:17 Hooking with Hardware Breakpoints: Insert a descriptor entry that points to the intended function (e.g., AmsiScanBuffer). When that function is hit, the instruction pointer is set to the address of the next ret instruction (C3 opcode).
0:33:01 Example for Heap Free: Set a breakpoint on HeapFree's address, get the size of the heap being freed, and then mem set the memory, preventing sensitive data from being scanned.