🤬
  • ■ ■ ■ ■ ■ ■
    README.md
    skipped 45 lines
    46 46  This precise logic is provided by `walkCallStack` and `spoofCallStack` functions in `main.cpp`.
    47 47   
    48 48   
    49  -## Actually this is not (yet) a true stack spoofing
     49 +## Demo
    50 50   
    51  -As it's been pointed out to me, the technique here is not _yet_ truly holding up to its name for being a _stack spoofer_. Since we're merely overwriting return addresses on the thread's stack, we're not spoofing the remaining areas of the stack itself. Moreover we leave a sequence of `::CreateFileW` addresses which looks very odd and let the thread be unable to unwind its stack. That's because `CreateFile` was meant to solely act as an example, we're making the stack non-unwindable but still obscuring references to our shellcode memory pages.
     51 +This is how a call stack may look like when it is **NOT** spoofed:
    52 52   
    53  -However I'm aware of these shortcomings, at the moment I've left it as is since I cared mostly about evading automated scanners that could iterate over processes, enumerate their threads, walk those threads stacks and pick up on any return address pointing back to a non-image memory (such as `SEC_PRIVATE` - the one allocated dynamically by `VirtuaAlloc` and friends). A focused malware analyst would immediately spot the oddity and consider the thread rather unusual, hunting down our implant. More than sure about it. Yet, I don't believe that nowadays automated scanners such as AV/EDR have sorts of heuristics implemented that would _actually walk each thread's stack_ to verify whether its un-windable `¯\_(ツ)_/¯` .
     53 +![not-spoofed](images/not-spoofed.png)
    54 54   
    55  -Surely this project (and commercial implementation found in C2 frameworks) gives AV & EDR vendors arguments to consider implementing appropriate heuristics covering such a novel evasion technique.
     55 +This in turn, when thread stack spoofing is enabled:
    56 56   
    57  -The research on the subject is not yet finished and hopefully will result in a better quality _Stack Spoofing_ in upcoming days. Nonetheless, I'm releasing what I got so far in hope of sparkling inspirations and interest community into further researching this area.
     57 +![spoofed](images/spoofed.png)
    58 58   
    59  -Next areas improving the outcome are to research how we can _exchange_ or copy stacks (utilising [`GetCurrentThreadStackLimits`](https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentthreadstacklimits)/`NtQueryInformationThread`) from a legitimate thread running `kernel32!Sleep(INFINITE)` or possibly by manipulating our Beacon's thread `TEB/TIB` structures and fields such as `TebBaseAddress` providing shadowed TEB. Another idea would be to play with `RBP/EBP` and `RSP/ESP` pointers on a paused Beacon's thread to change stacks in a similar manner to ROP chains.
     59 +Above we can see a sequence of `kernel32!CreateFileW` being implanted as return addresses. That's merely an example proving that we can manipulate return addresses.
     60 +To better enhance quality of this call stack, one could prepare a list of addresses and then use them while picking subsequent frames for overwriting.
     61 + 
     62 +For example, a following chain of addresses could be used:
     63 + 
     64 +```
     65 +KernelBase.dll!WaitForSingleObjectEx+0x8e
     66 +KernelBase.dll!WaitForSingleObject+0x52
     67 +kernel32!BaseThreadInitThunk+0x14
     68 +ntdll!RtlUserThreadStart+0x21
     69 +```
     70 + 
     71 +When thinking about AVs, EDRs and other automated scanners - we don't need to care about how much legitimate our thread's call stack look, since these scanners only care whether a frame points back to a `SEC_IMAGE` memory pages, meaning it was a legitimate DLL/EXE call (and whether these DLLs are trusted/signed themselves). Thus, we don't need to bother that much about these chain of `CreateFileW` frames.
    60 72   
    61 73   
    62 74  ## How do I use it?
    skipped 9 lines
    72 84  - **Unhook everything you might have hooked** (such as AMSI, ETW, WLDP) before sleeping and then re-hook afterwards.
    73 85   
    74 86   
    75  -## Demo
    76  - 
    77  -This is how a call stack may look like when it is **NOT** spoofed:
    78  - 
    79  -![not-spoofed](images/not-spoofed.png)
    80  - 
    81  -This in turn, when thread stack spoofing is enabled:
     87 +## Actually this is not (yet) a true stack spoofing
    82 88   
    83  -![spoofed](images/spoofed.png)
     89 +As it's been pointed out to me, the technique here is not _yet_ truly holding up to its name for being a _stack spoofer_. Since we're merely overwriting return addresses on the thread's stack, we're not spoofing the remaining areas of the stack itself. Moreover we leave a sequence of `::CreateFileW` addresses which looks very odd and let the thread be unable to unwind its stack. That's because `CreateFile` was meant to solely act as an example, we're making the stack non-unwindable but still obscuring references to our shellcode memory pages.
    84 90   
    85  -Above we can see a sequence of `kernel32!CreateFileW` being implanted as return addresses. That's merely an example proving that we can manipulate return addresses.
    86  -To better enhance quality of this call stack, one could prepare a list of addresses and then use them while picking subsequent frames for overwriting.
     91 +However I'm aware of these shortcomings, at the moment I've left it as is since I cared mostly about evading automated scanners that could iterate over processes, enumerate their threads, walk those threads stacks and pick up on any return address pointing back to a non-image memory (such as `SEC_PRIVATE` - the one allocated dynamically by `VirtuaAlloc` and friends). A focused malware analyst would immediately spot the oddity and consider the thread rather unusual, hunting down our implant. More than sure about it. Yet, I don't believe that nowadays automated scanners such as AV/EDR have sorts of heuristics implemented that would _actually walk each thread's stack_ to verify whether its un-windable `¯\_(ツ)_/¯` .
    87 92   
    88  -For example, a following chain of addresses could be used:
     93 +Surely this project (and commercial implementation found in C2 frameworks) gives AV & EDR vendors arguments to consider implementing appropriate heuristics covering such a novel evasion technique.
    89 94   
    90  -```
    91  -KernelBase.dll!WaitForSingleObjectEx+0x8e
    92  -KernelBase.dll!WaitForSingleObject+0x52
    93  -kernel32!BaseThreadInitThunk+0x14
    94  -ntdll!RtlUserThreadStart+0x21
    95  -```
     95 +The research on the subject is not yet finished and hopefully will result in a better quality _Stack Spoofing_ in upcoming days. Nonetheless, I'm releasing what I got so far in hope of sparkling inspirations and interest community into further researching this area.
    96 96   
    97  -When thinking about AVs, EDRs and other automated scanners - we don't need to care about how much legitimate our thread's call stack look, since these scanners only care whether a frame points back to a `SEC_IMAGE` memory pages, meaning it was a legitimate DLL/EXE call (and whether these DLLs are trusted/signed themselves). Thus, we don't need to bother that much about these chain of `CreateFileW` frames.
     97 +Next areas improving the outcome are to research how we can _exchange_ or copy stacks (utilising [`GetCurrentThreadStackLimits`](https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentthreadstacklimits)/`NtQueryInformationThread`) from a legitimate thread running `kernel32!Sleep(INFINITE)` or possibly by manipulating our Beacon's thread `TEB/TIB` structures and fields such as `TebBaseAddress` providing shadowed TEB. Another idea would be to play with `RBP/EBP` and `RSP/ESP` pointers on a paused Beacon's thread to change stacks in a similar manner to ROP chains.
    98 98   
    99 99   
    100 100  ## Example run
    skipped 95 lines
Please wait...
Page is in error, reload to recover