英文:
Go: Why do processes/Threads started using Win32API funcs seem to hijack and kill the parent proccess?
问题
现在,以下代码做了它应该做的事情,将calc.exe加载到内存并执行,它执行得很好。
我将这段代码拼接在一起,以展示CreateThread()在弹出calc.exe之前终止了我的程序执行流程,仅在CreateThread.Call()之后执行其他指令。
我相信这不是内存分配的问题,因为如果我将CreateThread()包装在一个goroutine中(go runThread()),它会在弹出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 {
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)
}
我对为什么会发生这种情况感到好奇。
英文:
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?
答案1
得分: 0
原来如此,确实是一个shellcode问题。代码调用Fine,我不知道msfvenom的有效载荷有时会以奇怪的方式干扰它们的主机调用者。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论