SharpGen icon indicating copy to clipboard operation
SharpGen copied to clipboard

Add args to Main/Execute definition

Open dcsync opened this issue 6 years ago • 4 comments

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

dcsync avatar Nov 13 '18 03:11 dcsync

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 😃)

cobbr avatar Dec 12 '18 19:12 cobbr

bump @dcsync

cobbr avatar Mar 11 '19 20:03 cobbr

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.

dcsync avatar Apr 22 '19 04:04 dcsync

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.

dcsync avatar Apr 22 '19 04:04 dcsync