Like hells gate, but more go, more banana.
Useful references:
- https://github.com/am0nsec/HellsGate
- https://www.cyberbit.com/blog/endpoint-security/malware-mitigation-when-direct-system-calls-are-used/
This is a pure-go implementation of using direct syscalls to do Windowsy stuff. Don't be silly and try this on not-Windows, it won't work and I honestly don't know why you'd even think it would?
API not yet stable, vendor your shit properly. Sorry in advance if I push changes that break your malware :)
Several useful functions in dealing with process things are provided by this lib. Namely:
Syscall
with a providedsysid
anduintptr
s to parameters, you're able to do a Windows syscall for pretty much any defined kernel call. I only tried with a handful, but it should work with any/most.GetPEB
return the memory location of the PEB without performing any API calls. At it's core, just does this:MOVQ 0x60(GS), AX ; MOVQ AX, ret+0(FP)
(this is the Go ASM syntax, incase you're confused.)GetNtdllStart
return the start address of ntdll loaded in process memory. Does not make any API calls (see asm_x64.s for details)WriteMemory
take a byte slice, and write it to a certain memory address (may panic if not writable etc lol)A handful of predefined kernel calls likeNtAllocateVirtualMemory
etc. See source for more details and whatnot.- A direct version of
mkwinsyscall
(mkdirectwinsyscall
in the cmd dir) which should make it easy for you to resolve and use syscalls, and now I don't have to support them :). - Halo's gate implementation by @nodauf
- When using auto mode, BananaPhone will first try to get the syscall ID from memory using the exported function name, then fail over to Halo's Gate, then Fail over to reading ntdll from disk. The Disk read is not done with any MapViewOfSection functions, so detection must be conducted using handles to the ntdll file.
All of the PE parsing and extraction of interesting information is provided by https://github.com/Binject/debug, which adds on to the stdlib pe
library in some very cool ways.
See examples in example/
.
See mkdirectwinsyscall readme in cmd/mkdirectwinsyscall
, and example of use in example
.
Here is an example I posted into a slack chan recently:
...
var (
modntdll = windows.NewLazySystemDLL("ntdll.dll")
ntapi = modntdll.NewProc("NtCreateThreadEx")
)
...
ntapi.Call(0, 1, 1, 1, 1)
var x *uintptr
bananaphone.NtCreateThreadEx(createthread, x, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2)
ntapi.Call(0, 3, 3, 3, 3)
What you're looking at is the output of API Monitor, which can be used to track a program's API calls. Each function was called with some easy to identify values (all 1's as a parameter, all 2's etc). What this shows is that the call made by bananaphone.NtCreateThreadEx
is not captured by API Monitor, and any AV/EDR that uses similar methods probably won't catch it either. Neat.