Как загрузить DLL на диск в удаленный процесс через Golang?

Я новичок в программировании и решил забрать Golang. Один проект, над которым я работаю, — это внедрение DLL на диске в удаленный процесс через CreateRemoteThread. Цель программы состоит в том, чтобы запустить процесс жертвоприношения,notepad.exeи внедрить DLL,test.dll, в жертвенный процесс. DLL имеет единственный экспорт, в моем случае "Engage".

До сих пор мой подход заключался в сравнении кода Golang, который внедряет шеллкод через CreateRemoteThread, и кода C, который внедряет DLL через CreateRemoteThread. Два ресурса, которые я использую, можно найти здесь и здесь .

Мои знания о внедрении DLL, о том, как работают Windows API и как работает память, — все это новые области знаний, которые я пытаюсь развивать. С учетом сказанного мой код может не соответствовать правильной последовательности событий, необходимой для создания удаленного потока. И использование кода, который внедряет шеллкод, возможно, не лучший фреймворк для создания моего кода. Если это так, пожалуйста, дайте мне знать!

Ниже приведен код Голанга. Он работает успешно, но DLL не внедряется. Это было проверено с помощью Process Monitor. Единственная ссылка, которую я вижу в Process Monitor, - это операция «создать файл», указывающая на каталог, в котором находится DLL, но фактическое имя DLL искажено (не ASCII, SHƒì0èf.DLL). Есть несколько областей, с которыми у меня были проблемы, которые могут быть источником проблемы.

  1. VirtualAllocEx требует uintptr для DLL. Я не уверен, передается ли правильная информация для выделения памяти в удаленном процессе. И глядя на код C, люди просто используют длину строки пути к DLL.
  2. Нахождение местоположенияkernel32.dllв текущем процессе найти адрес "LoadLibraryA" для создания удаленного потока. Не уверен, что использование «syscall.LoadLibrary» является правильным подходом.
      package main

import (
    "fmt"
    "log"
    "os/exec"
    "syscall"

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

func main() {
    dllPath := "C:\\Users\\Documents\\GoCode\\src\\test.dll"
    /*
       Spawn process to inject to
    */

    cmd := exec.Command("notepad.exe")
    cmd.Start()

    cmdPid := cmd.Process.Pid
    fmt.Println("PID of notepad.exe:", cmdPid)

    /*
        Process Injction
    */
    kernel32 := windows.NewLazySystemDLL("kernel32.dll")
    VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
    WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
    CreateRemoteThreadEx := kernel32.NewProc("CreateRemoteThreadEx")

    //OpenProcess(desired access, inherite handle, PID)
    //Get a handle to the remote process with the proper secutiry attributes to create a remote thread
    proc, errOpenProcess := windows.OpenProcess(windows.PROCESS_CREATE_THREAD|windows.PROCESS_VM_OPERATION|windows.PROCESS_VM_WRITE|windows.PROCESS_VM_READ|windows.PROCESS_QUERY_INFORMATION, false, uint32(cmdPid))
    if errOpenProcess != nil {
        panic(fmt.Sprintf("[!]Error calling OpenProcess:\r\n%s", errOpenProcess.Error()))
    }

    //VirtualAllocEx(handle to process/must have PROCESS_VM_OPERATION, optional starting address for alloc, size of mem region to alloc in bytes, type of mem alloc, mem protect)
    //Allocate memory in the remote process for the DLL
    addr, _, errVirtualAlloc := VirtualAllocEx.Call(uintptr(proc), 0, uintptr(len(dllPath)), windows.MEM_RESERVE|windows.MEM_COMMIT, windows.PAGE_READWRITE)
    if errVirtualAlloc != nil && errVirtualAlloc.Error() != "The operation completed successfully." {
        panic(fmt.Sprintf("[!]Error calling VirtualAlloc:\r\n%s", errVirtualAlloc.Error()))
    }
    //Get uintptr to dll being injected, maybe?
    dll, errLoadLib := syscall.LoadLibrary(dllPath)
    if errLoadLib != nil {
        log.Fatal(errLoadLib)
    }

    dllH, getProcAddErr := syscall.GetProcAddress(syscall.Handle(dll), "Engage")
    if getProcAddErr != nil {
        log.Fatal(errLoadLib)
    }
    loadLibA, err := syscall.LoadLibrary("kernel32.dll")
    if err != nil {
        log.Fatal(errLoadLib)
    }
    loadLibAHandle, err := syscall.GetProcAddress(loadLibA, "LoadLibraryA")
    if err != nil {
        log.Fatal(errLoadLib)
    }

    //WriteProcessMemory(handle to process, base addr to where data is written, pointer to buffer that contains data, num of bytes to be written, optional num of bytes transferred)
    _, _, errWriteProcessMemory := WriteProcessMemory.Call(uintptr(proc), addr, (uintptr)(dllH), uintptr(len(dllPath)))
    if errWriteProcessMemory != nil && errWriteProcessMemory.Error() != "The operation completed successfully." {
        panic(fmt.Sprintf("[!]Error calling WriteProcessMemory:\r\n%s", errWriteProcessMemory.Error()))
    }

    //CreateRemoteThreadEx(handle to process, security attributes, ).
    _, _, errCreateRemoteThreadEx := CreateRemoteThreadEx.Call(uintptr(proc), 0, 0, loadLibAHandle, addr, 0, 0)
    if errCreateRemoteThreadEx != nil && errCreateRemoteThreadEx.Error() != "The operation completed successfully." {
        panic(fmt.Sprintf("[!]Error calling CreateRemoteThreadEx:\r\n%s", errCreateRemoteThreadEx.Error()))
    }
    /*
       Close handle to process
    */
    closeHandle := windows.CloseHandle(proc)
    if closeHandle != nil {
        fmt.Println("Error closing process:", closeHandle)
    } else {
        fmt.Println("Closed handle successfully.")
    }

}

0 ответов

Другие вопросы по тегам