hasherezade / pe_to_shellcode

Converts PE into a shellcode
https://www.youtube.com/watch?v=WQCiM0X11TA
BSD 2-Clause "Simplified" License
2.27k stars 423 forks source link

Donut works but pe2shc does not #45

Closed Beykir closed 4 weeks ago

Beykir commented 2 months ago

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)
}
hasherezade commented 2 months ago

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

Beykir commented 4 weeks ago

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

hasherezade commented 3 weeks ago

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