BOF/COFF extension.json Updates for SliverArmory
Is your feature request related to a problem? Please describe.
The extension.json files for SliverArmory's BOF/COFF execution currently captures fields like name, type, and optional, but there's no concept of a "default" argument. Some CNA scripts do additional processing to add in default values to optional parameters, but we lose this context with the extension.json file. An example is this script, https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/849c98a9b97c47de48409411a9f5db5dfaac3185/SA/SA.cna#L202C3-L202C9, which adds in a default value of 3 to the scope field.
This causes issues with operators trying to come from Cobalt Strike with CNAs to things like Sliver's Armory or Mythic's forge capabilities because they suddenly get different "defaults" than in Cobalt Strike. This can potentially cause crashes within the BOF execution or unexpected behavior during a live operation.
Describe the solution you'd like
It would be nice if the extension.json file had an optional default field for each argument that we could use to provide a value if the operator doesn't.
This would be a pie in the sky, but it would also be nice if there was a choices field. I've seen a bunch of different BOFs that take in something like an int and in their description say that the valid values are 0, 1, 2, but there's no consistent way to bubble that data up to the extension.json file in a way that can be used. This would be really handy as we can do some "safety" logic or operational assistance to make sure that operators are providing valid data.
Some CNA scripts do validation of arguments, so it would be nice if we had a way to bring that same sort of argument validation to other C2 platforms via the extension.json. If a BOF/COFF expects the CNA to provide safe defaults or do some sort of validation, then proper validation might not happen in the BOF/COFF itself, leading to more instability and issues outside of Cobalt Strike.
Describe alternatives you've considered
If we don't have this data captured in the extension.json file, then I'm not sure where else we'd be able to put it so that we can leverage it in other frameworks. The current process of SliverArmory is to compile the files and host the .o and .json files as releases, so we lose the context of any CNA scripts or raw code to examine as well. I think it makes the most sense to include these sorts of fields within the extension.json for consistency.
My 2 cents:
It would be nice if the extension.json file had an optional default field for each argument that we could use to provide a value if the operator doesn't.
Agreed, this shouldn't be too hard to implement. IIRC the main issue I had with that is that a lot of BOFs don't respect the POSIX syntax for positional vs optional arguments. This becomes an issue when we're trying to map things using the CLI library we use, were you can't have a positional argument without a value, and can't mix positional and optional arguments (unless we're passing them as flags, which we could potentially do). This is the main reason behind the optional field in the manifest. Keep in mind that every command in an extension manifest will be translated to a CLI command by the Sliver client.
This would be a pie in the sky, but it would also be nice if there was a choices field. I've seen a bunch of different BOFs that take in something like an int and in their description say that the valid values are 0, 1, 2, but there's no consistent way to bubble that data up to the extension.json file in a way that can be used. This would be really handy as we can do some "safety" logic or operational assistance to make sure that operators are providing valid data. Some CNA scripts do validation of arguments, so it would be nice if we had a way to bring that same sort of argument validation to other C2 platforms via the extension.json. If a BOF/COFF expects the CNA to provide safe defaults or do some sort of validation, then proper validation might not happen in the BOF/COFF itself, leading to more instability and issues outside of Cobalt Strike.
CNA is using the sleep language, giving it more liberties and opportunities for scripting. JSON, which we're using for extension manifests is more restrictive in that regard (not being a scripting language), so we can't really have data validation in the manifest itself, it needs to be in the program that will parse it. Having an optional choices field seems reasonable though.
@its-a-feature appreciate the feedback! We have added a default field to extensions in master, if you want to check it out (https://github.com/BishopFox/sliver/pull/1925).
Eg, with a slightly modified sa-nslookup that includes two optional arguments and defaults:
"arguments": [
{
"name": "hostname",
"desc": "Hostname to resolve",
"type": "string",
"optional": false
},
{
"name": "server",
"desc": "DNS Server to use",
"type": "string",
"optional": true,
"default": "8.8.8.8"
},
{
"name": "type",
"desc": "DNS record type (A, AAAA, or ANY), see https://docs.microsoft.com/en-us/windows/win32/dns/dns-constants for the actual values",
"type": "short",
"optional": true,
"default": 1
}
We can execute with:
sliver (FUZZY_MATHEMATICS) > sa-nslookup -h
Command:sa-nslookup HOSTNAME [SERVER] [TYPE]
About:Makes a dns query. NOTE: Some situations are limited due to observed crashes
Arguments:
HOSTNAME (string): Hostname to resolve
SERVER (string): [OPTIONAL]DNS Server to use
TYPE (short): [OPTIONAL]DNS record type (A, AAAA, or ANY), see https://docs.microsoft.com/en-us/windows/win32/dns/dns-constants for the actual values
Usage:
sa-nslookup HOSTNAME [SERVER] [TYPE] [flags]
Flags:
-h, --help help for sa-nslookup
-s, --save Save output to disk
-t, --timeout int command timeout in seconds (default 60)
sliver (FUZZY_MATHEMATICS) > sa-nslookup -- -hostname google.com
-server:8.8.8.8 (default)
-type:1 (default)
[*] Tasked beacon FUZZY_MATHEMATICS (62a71b17)
[*] Beacon 1f959fc6 FUZZY_MATHEMATICS - tcp(127.0.0.1:45806)->2601:84:c880:61d0:7dc3:1e21:c52:bc62 (DESKTOP-9FSJA1P) - windows/amd64 - Fri, 11 Apr 2025 19:23:25 UTC
[+] FUZZY_MATHEMATICS completed task 62a71b17
[*] Successfully executed sa-nslookup (coff-loader)
[*] Got output:
A google.com 142.250.65.174
sliver (FUZZY_MATHEMATICS) > sa-nslookup -- -server 1.1.1.1 -hostname google.com
-type:1 (default)
[*] Tasked beacon FUZZY_MATHEMATICS (4f67ef6a)
[+] FUZZY_MATHEMATICS completed task 4f67ef6a
[*] Successfully executed sa-nslookup (coff-loader)
[*] Got output:
A google.com 142.251.40.206