How Malware Developers are able to evade detection

How Does This Work?

Code

#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>

using namespace std;
// This function will run in a dummy thread
DWORD WINAPI DummyThread(LPVOID lpParam) {
    Sleep(INFINITE); // This thread simply waits indefinitely
    return 0;
}
// Function to manipulate the stack of a thread in a process
void CleanStack(HANDLE hThread) {
    CONTEXT ctx;
    ctx.ContextFlags = CONTEXT_FULL;
    // Suspend the thread before modifying its context
    SuspendThread(hThread);
    // Get the thread's context
    if (!GetThreadContext(hThread, &ctx)) {
        cerr << "Error retrieving thread context" << endl;
        ResumeThread(hThread);
        return;
    }
    DWORD64 originalRsp = ctx.Rsp;
    cout << "Original RSP: " << hex << originalRsp << endl;
    constexpr int STACK_CLEAN_SIZE = 16;
    DWORD64 stackValues[STACK_CLEAN_SIZE];
    // Read the target thread's stack
    SIZE_T bytesRead;
    if (!ReadProcessMemory(GetCurrentProcess(), (LPCVOID)originalRsp, stackValues, sizeof(stackValues), &bytesRead)) {
        cerr << "Error reading stack memory" << endl;
        ResumeThread(hThread);
        return;
    }
    // Clear the stack
    ZeroMemory(stackValues, sizeof(stackValues));
    // Write the cleaned values back to the thread's stack
    SIZE_T bytesWritten;
    if (!WriteProcessMemory(GetCurrentProcess(), (LPVOID)originalRsp, stackValues, sizeof(stackValues), &bytesWritten)) {
        cerr << "Error writing stack memory" << endl;
    }
    ctx.Rsp = originalRsp;  // Restore RSP
    // Apply the changes to the thread context
    if (!SetThreadContext(hThread, &ctx)) {
        cerr << "Error setting thread context" << endl;
    }
    // Resume the thread
    ResumeThread(hThread);
}
int main() {
    // Create a dummy thread within the same process
    HANDLE hThread = CreateThread(NULL, 0, DummyThread, NULL, 0, NULL);
    if (!hThread) {
        cerr << "Error creating thread" << endl;
        return 1;
    }
    // Get the Thread ID of the created thread
    DWORD threadId = GetThreadId(hThread);
    cout << "Thread ID: " << threadId << endl;
    // Wait for the thread to initialize
    Sleep(100);
    cout << "Before Cleaning stack..." << endl;
    getchar();
    // Manipulate the dummy thread's stack from the main thread
    CleanStack(hThread);
    cout << "After Cleaning stack..." << endl;
    getchar();
    // Now we can terminate the dummy thread
    TerminateThread(hThread, 0);
    // Wait for the thread to complete before closing the program
    WaitForSingleObject(hThread, INFINITE);
    // Close the thread handle
    CloseHandle(hThread);
    Sleep(100000); // Simulate a long wait before the program exits
    return 0;
}

Proof of Concept

Detection

Litterbox:

_____                        __          
  /     \   ____   ____   _____/  |______   
 /  \ /  \ /  _ \ /    \_/ __ \   __\__  \  
/    Y    (  <_> )   |  \  ___/|  |  / __ \_
\____|__  /\____/|___|  /\___  >__| (____  /
        \/            \/     \/          \/ 
Moneta v1.0 | Forrest Orr | 2020
09c3c3b7217907e384a13c73c15486f6_StackCallCleaner.exe : 3508 : x64 : C:\Users\s12de\Desktop\LitterBox\Uploads\09c3c3b7217907e384a13c73c15486f6_StackCallCleaner.exe
  0x00007FF63E920000:0x00029000   | EXE Image           | C:\Users\s12de\Desktop\LitterBox\Uploads\09c3c3b7217907e384a13c73c15486f6_StackCallCleaner.exe | Unsigned module
    0x00007FF63E920000:0x00001000 | R        | Header   | 0x00000000 | Primary image base
    0x00007FF63E921000:0x00010000 | RWX      | .textbss | 0x00010000 | Modified code
    0x00007FF63E931000:0x0000a000 | RX       | .text    | 0x00000000
      Thread 0x00007FF63E931320 [TID 0x00000f80]
      Thread 0x00007FF63E931276 [TID 0x00001ef0]
    0x00007FF63E93B000:0x00004000 | R        | .rdata   | 0x00000000
    0x00007FF63E93F000:0x00001000 | RW       | .data    | 0x00001000
    0x00007FF63E940000:0x00005000 | R        | .pdata   | 0x00001000
    0x00007FF63E940000:0x00005000 | R        | .idata   | 0x00001000
    0x00007FF63E945000:0x00001000 | WC       | .msvcjmc | 0x00000000
    0x00007FF63E946000:0x00003000 | R        | .00cfg   | 0x00000000
    0x00007FF63E946000:0x00003000 | R        | .rsrc    | 0x00000000
    0x00007FF63E946000:0x00003000 | R        | .reloc   | 0x00000000... scan completed (0.172000 second duration)

ThreatCheck

Windows Defender

BitDefender Free AV

Conclusions

Leave a Reply

Your email address will not be published. Required fields are marked *