SharpGen
SharpGen copied to clipboard
Add args to Main/Execute definition
This allows code within the Main/Execute function to take arguments.
I'm mostly interested in adding this because arguments passed to Cobalt Strike's bexecute_assembly
function don't show up in Environment.GetCommandLineArgs()
for some reason. For example:
beacon> client cat /tmp/args.cs
foreach (string arg in args) {
Console.WriteLine(" - " + arg);
}
Console.WriteLine("");
foreach (string arg in Environment.GetCommandLineArgs()) {
Console.WriteLine(" - " + arg);
}
beacon> sharpgen-execute-file /tmp/args.cs arg1 arg2 arg3
[*] Tasked beacon to execute C# code from: /tmp/args.cs
[+] host called home, sent: 936007 bytes
[+] received output:
- arg1
- arg2
- arg3
- C:\Users\user3\Desktop\beacon.exe
Hey @dcsync, having a little trouble understanding this one as well.
I see you changed the WrapperFunctionFormat
. Could you provide a practical example where it would be beneficial for that embedded class to accept arguments? You may have to share what sharpgen-execute-file
is doing for me to totally understand (sorry I'm slow 😃)
bump @dcsync
Hi Ryan! Sorry for the late response. My original intent behind adding arguments to WrapperFunctionFormat
was to enable the development of a C# build cache.
I actually just finished integrating the build cache I was working on, along with a wrapper for SharpGen, into PyCobalt. Thanks to SharpGen I've managed to mostly replace PowerShell with C# in my personal set of Cobalt Strike scripts.
Here's an example PyCobalt beacon alias I put together to demonstrate how I tend to use arguments:
@aliases.alias('cat', 'View files')
def _(bid, *files):
code = """
foreach (string file in args) {
var text = System.IO.File.ReadAllText(file);
System.Console.Write(text);
}
"""
aggressor.btask(bid, 'Tasked beacon to get contents of: {}'.format(', '.join(files)))
# compiles `code`, executes it on beacon `bid` with `files` as arguments
sharpgen.execute(bid, code, files)
By passing arguments to Main()
instead of generating C# code based on the arguments the code itself stays the same, allowing sharpgen.execute()
to find a previously-built binary in the build cache.
I ended up putting together an external wrapper function which is probably a better solution for me.
Thanks for releasing SharpGen by the way! It's exactly what I was looking for in an inline C# compiler.
I was trying to put together some C# compilation helpers for Cobalt Strike with msbuild before but it was a bit of a mess. SharpGen has made things quite a bit easier.