Introducing Goffloader: A Pure Go Implementation of an In-Memory COFFLoader and PE Loader

We are excited to announce the release of Goffloader, a pure Go implementation of an in-memory COFFLoader and PE loader. This tool is designed to facilitate the easy execution of Cobalt Strike BOFs and unmanaged PE files directly in memory without writing any files to disk. Goffloader aims to take functionality that is conventionally within the realm of C/C++ and make it easily accessible to Golang security tooling.

Why Goffloader?

While there are several excellent C implementations of COFF loaders available, we saw a need for a Go-based solution. Here are a few reasons why we developed Goffloader:

  1. Expanding Go’s Security Capabilities: Adding BOF loading to Go opens up a plethora of open-source security projects that can now be integrated into Go-based security tools. Entire repositories of useful functionality are now accessible via this library.
  2. Avoiding CGO Complications: Although it’s possible to use C implementations of COFF loaders, integrating C code with Go using CGO can be cumbersome. Additional toolchains need to be installed, libraries need to be built, and it requires working in multiple languages at once. Goffloader eliminates these hassles.
  3. Static Signature Evasion: Go is a great language for static signature evasion. For instance, we have successfully run an embedded version of Mimikatz without needing to employ complex evasion techniques.
  4. Integration with Chariot Breach & Attack Simulation (BAS): Our open-source breach and attack simulation tests are written in Go. Goffloader supports and enhances this functionality, making our simulations more robust and versatile.

Example Usage

Goffloader is designed to make loading BOFs or PE files as straightforward as possible by using the go:embed tag. Here’s an example of how to run an embedded executable and display its console output:

import "github.com/praetorian-inc/goffloader/src/pe"
//go:embed hello.exe
var helloBytes [] byte
func main() {
output, _ := pe.RunExecutable(helloBytes, []string{"Arg1", "Arg2", "Arg3"}) fmt.Println(output)
}

You can find full examples for running BOFs or PE files in the cmd folder of our GitHub repository. The ability to run PE files is enabled via the No-Consolation BOF, and you can see an example of executing that here.

Our tests revealed Goffloader can smuggle well-known malware (like Mimikatz) past the latest and greatest endpoint defenses. For now, at least:

 

 

Limitations

While Goffloader offers significant benefits, it currently has a few limitations:

  • The COFFLoader implementation is only for x64 architecture. Support for 32-bit will be coming soon.
  • The PE execution currently involves loading a BOF with hard-coded arguments. More flexible approaches will be supported in future updates.
  • The Beacon API implementation is partial. Although most BOFs use only basic functions like argument parsing and output, there are parts of beacon.h that still need to be implemented. This will be addressed as more BOFs that rely on these APIs are identified.
  • Using this library in its current state will not produce a 0/N detections file on VirusTotal. Currently, there are 2 or 3 detections from the usual false-positive mills. Users should be aware of this when using the library.

Open Source and Community Support

We are open-sourcing Goffloader in support of Praetorian’s Chariot BAS offering. By making this library available to the community, we hope to foster collaboration and innovation in the field of security tooling. We believe that Goffloader will become an invaluable resource for security professionals and enthusiasts alike.

Acknowledgements

We would like to extend our gratitude to the following projects and individuals whose work has been instrumental in the development of Goffloader:

  • Ne0nD0g’s go-coff project for providing the base for the Golang implementation of Cobalt Strike’s Beacon API and the idea to use windows.NewCallback to avoid CGO.
  • TrustedSec’s COFFLoader blog post for their insightful guide on building in-memory loaders.
  • OtterHacker’s excellent COFFLoader blog post for their detailed explanations and examples.
  • Fortra’s No-Consolation BOF for enabling the execution of PE files within Goffloader.
  • The developers of the (now-archived) Go pecoff library for their foundational work in parsing files within Go.

We are excited to see how the community will use and build upon Goffloader. For more information and to get started, visit our GitHub repository.

About the Authors

Michael Weber

Michael Weber

Michael has worked in security as a malware reverse engineer, penetration tester, and offensive security developer for over a decade.

Catch the Latest

Catch our latest exploits, news, articles, and events.

Ready to Discuss Your Next Continuous Threat Exposure Management Initiative?

Praetorian’s Offense Security Experts are Ready to Answer Your Questions

0 Shares
Copy link