Summary
Forge is a “Command Augmentation” payload type that provides a few functions for downloading/creating BOF/.NET commands as new, tab-completable commands within a variety of other payload type’s callbacks. Forge itself can’t be “built”; instead, it offers Mythic-side commands that can then be passed down to various callbacks for execution. These forge commands are automatically injected into all Windows callbacks based on payload types listed in the payload_type_support.json file (more on that further down). Forge offers three kinds of execution for supported payload types:- BOF
- Execute Assembly
- Inline Assembly
Supporting Files
payload_type_support.json
This file identifies which payload types are supported and how to pass execution from forge to them. This takes the following format:forge_support command. Alternatively, you can modify this file to add your own entry to the list. Then run the following commands:
bof
BOF commands created as part of Forge are first-order commands within supported callbacks. For example, if the bof command is “sa-netgroup”, then the corresponding command that will be registered isforge_bof_sa-netgroup.
This allows you to easily group forge* commands together and identify if a command is a BOF or .NET executable. If this BOF takes two arguments, group and server, then they’ll be exposed to the operator like
forge_bof_sa-netgroup -server 127.0.0.1 -group Administrators. You don’t need to worry about the order or types of values, that’ll be handled for you based on the backing bof’s extension.json file (the same as the SliverArmory format).
This command then needs to be passed down to your callback for your payload type to actually execute the BOF. There are four fields that help identify how this works in your payload_type_support.json:
- “bof_command”: “execute_coff”
- which command in your agent should we pass control to. Control goes right to that command’s
create_go_taskingfunction and continues from there like normal.
- which command in your agent should we pass control to. Control goes right to that command’s
- “bof_file_parameter_name”: “bof_file”
- every bof is backed by a file, this is identifying the name of your BOF command’s parameter that expects the file. The value passed to this parameter is the file’s UUID (just like if it was type File)
- “bof_argument_array_parameter_name”: “coff_arguments”
- in Mythic, the ideal way to handle a BOF’s arguments is with a parameter type of TypedArray. This allows us to specify the type of data (int, short, widestring, string, etc) in addition to the data itself in a standard format. Data will be passed along in this stnadard format with standard BOF notations.
- For example:
[ ["i", 5], ["Z", "Administrator"] ]. Your command’s typed array parser will get called with this data.
- For example:
- in Mythic, the ideal way to handle a BOF’s arguments is with a parameter type of TypedArray. This allows us to specify the type of data (int, short, widestring, string, etc) in addition to the data itself in a standard format. Data will be passed along in this stnadard format with standard BOF notations.
- “bof_entrypoint_parameter_name”: “function_name”
- BOFs identy the entrypoint for the program. The vast majority of the time this is
go, but doesn’t technically have to be. This is passed into your payload type’s command and fetched from this BOF’s backingextension.jsonfile.
- BOFs identy the entrypoint for the program. The vast majority of the time this is
net
.NET commands created as part of Forge are first-order commands within supported callbacks. For example, if the .NET is “Rubeus”, then the corresponding command that will be registered isforge_net_Rubeus.
This allows you to easily group forge* commands together and identify if a command is a BOF or .NET executable. Due to the nature of how assemblies are largely used within the offensive community,
these new commands take in a few specific parameters:
- args
- this is the entire args string that’s passed to the assembly. We can’t easily break this up into named parameters because most assemblies just expect a single string as if they were run on the command line.
- version
- this is the version of the assembly you want to execute. This defaults to
4.7_Any, but you can set it to any of the versions associated with @Flangvik’s SharpCollection repository.
- this is the version of the assembly you want to execute. This defaults to
- execution
- This identifies the execution method you want to use with the assembly - execute_assembly (fork-and-run) or inline_assembly (inside your process)
collection_sources.json
This file identifies all the collections that are available along with what kind of commands they are. The initial file looks like this:SharpCollection which has assembly commands and SliverArmory which has bof commands.
Forge processes this file and then looks for their associated sources files, SharpCollection_sources.json and SliverArmory_sources.json files respectively.
*_sources.json
This file outlines the original sources of all the commands that are available under a specific collection. This is an array of entries, where each one has the following fields:- “name”:
- This is the name of the command overall (see this with
forge_communitycommand)
- This is the name of the command overall (see this with
- “command_name”:
- This is the name of the command that gets added to
forge_bof_orforge_net_
- This is the name of the command that gets added to
- “description”:
- This is the description of the command and is displayed in the modal UI and help
- “repo_url”:
- assemblies
- This points to a SharpCollection-like repository for assemblies
- bof
- repo that has a tagged release with a command.tar.gz file that contains the extension.json and .o files
- assemblies
- “custom_download_url”:
- This can be the url of a specific file to download instead of using the SharpCollection or SliverArmory release formats
- assemblies
- This points to the specific download url of the .exe file
- bof
- This points to a specific download url of the command.tar.gz file with the extension.json and .o files
- “custom_version”:
- This can be used to specify a custom version to associate with a .NET execution instead of using one of the versions associated with SharpCollection’s formats
GITHUB_TOKEN with a GitHub pat or any value that you want to use as part of an Authorization header for access. The code to download from the remote repository does the following:
Authors
- @its_a_feature_