Git Product home page Git Product logo

bof.net's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bof.net's Issues

DownloadFile() fails for files larger 1MB

Hi, thank you for sharing this great code.

Unfortunately I always receive a

 [-] download [id: -1555981019] closed: Missed start message/metadata.

error in Cobalt when trying to download files larger 1MB. What could be the issue here?

My code on the assembly side for simple testing of the download looks like this:

using BOFNET;
using System.IO;

namespace dlfix
{
    internal class Program
    {
        class DLFIX : BeaconObject
        {

            public DLFIX(BeaconApi api) : base(api) { }

            public override void Go(string[] args)
            {
                BeaconConsole.WriteLine("[+] TESTING DOWNLOAD");

                byte[] filebyte = File.ReadAllBytes(@"C:\temp\Testing");
                MemoryStream stream = new MemoryStream();

                using (var writer = new BinaryWriter(stream))
                {
                    writer.Write(filebyte);
                    stream.Position = 0;
                    DownloadFile("notexisting.bin", stream);
                }

            }
        }
    }
}

Leak of memory for BSTR friendlyName due to missing call to SysFreeString

A BSTR friendlyName is declared but not freed in the main body of getAppDomain and the memory is leaked as a result

    while((hr = icrh->NextDomain(hDomainEnum, &iu)) == S_OK){

!        BSTR friendlyName;   <<< BSTR declared

...

!        hr = appDomain->get_FriendlyName(&friendlyName);   <<< BSTR allocated and returned

        if(friendlyName && wcscmp(friendlyName, appDomainName) == 0){
            iu->Release();
            found = true;
+            SysFreeString on friendlyName
            break;
        }

        hr = appDomain->Load_2(SysAllocString(L"BOFNET"), &assembly);

        if(assembly == nullptr){
            iu->Release();
+            SysFreeString on friendlyName
            continue;
        }

        found = true;
        iu->Release();
+            SysFreeString on friendlyName
        break;
    }

DownloadFile() not working with bofnet_job

Hey,

Really appreciate the effort that's gone into supporting the undocumented BOF functionality.

I've run into an issue with DownloadFile(). It appears to work fine with bofnet_execute but throws a NullReferenceException error with bofnet_job. This may be down to the way I'm using it. If so, would appreciate some code samples on usage if you have the time.

Test Code

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BOFNET;

namespace BOFNET_TestFileDownload
{
    class Program : BeaconObject
    {
        public Program(BeaconApi api) : base(api) { }
        public override void Go(string[] args)
        {
            MemoryStream ms = new MemoryStream();
            using (FileStream file = new FileStream(@"C:\temp\Testing.txt", FileMode.Open, FileAccess.Read))
                file.CopyTo(ms);
            ms.Position = 0;
            DownloadFile("testfile.txt", ms);
            ms.Close();

            BeaconConsole.WriteLine($"[+] File sent!");
        }

        static void Main(string[] args)
        {
        }
    }
}

Output

beacon> bofnet_execute BOFNET_TestFileDownload.Program
[*] Attempting to execute BOFNET BOFNET_TestFileDownload.Program
[+] host called home, sent: 6809 bytes
[*] started download of testfile.txt (24 bytes)
[*] download of testfile.txt is complete
[+] received output:
[+] File sent!

beacon> bofnet_job BOFNET_TestFileDownload.Program
[*] Attempting to start BOFNET BOFNET_TestFileDownload.Program as a job
[+] host called home, sent: 6836 bytes
[+] received output:
[+] Started Task BOFNET_TestFileDownload.Program with job id 4

beacon> bofnet_jobstatus 4
[*] Attempting to execute BOFNET BOFNET.Bofs.Jobs.JobStatus
[+] host called home, sent: 6808 bytes
[+] received output:
Type: Program, Id: 4, Active: False, Console Data: True
Job execution failed with exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at BOFNET.BeaconObject.DownloadFile(String fileName, Stream fileData)
   at BOFNET_TestFileDownload.Program.Go(String[] args)
   at BOFNET.BeaconJob.DoTask(Object args)

[+] Job completed and console drained, removing from active job list

BOF.NET fails to call CoInitializeSecurity which results in impersonation conflicts with other WMI tools

TrustedSec recently updated their Situational Awareness BOF toolkit to support/fix remote WMI queries using tokens created with make_token. See issue: trustedsec/CS-Situational-Awareness-BOF#94

The issue related to the "CoInitializeSecurity" call:

	hr = OLE32$CoInitializeSecurity( //Failure of this function does not necessarily mean we failed to initialize, it will fail on repeated calls, but the values from the original call are retained
	    NULL,
            -1,
            NULL,
            NULL,
            RPC_C_AUTHN_LEVEL_DEFAULT,
            RPC_C_IMP_LEVEL_IMPERSONATE,
            NULL,
            EOAC_NONE,
            NULL);

Specifically the EOAC_NONE flag was changed to EOAC_DYNAMIC_CLOAKING so that subsequent WMI calls would use the thread token (see more here: https://learn.microsoft.com/en-us/windows/win32/api/objidl/ne-objidl-eole_authentication_capabilities)

From the MSDN page on CoInitializeSecurity(https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-coinitializesecurity):

The CoInitializeSecurity function initializes the security layer and sets the specified values as the security default. If a process does not call CoInitializeSecurity, COM calls it automatically the first time an interface is marshaled or unmarshaled, registering the system default security. No default security packages are registered until then.

This function is called exactly once per process, either explicitly or implicitly. It can be called by the client, server, or both.

The issue arises when BOF.NET is initialized in a process before any other COM interface, i.e. before a Situational Awareness BOF that uses WMI has been called.

Because BOF.NET fails to call CoInitializeSecurity, COM calls it automatically and without the requisite flags to allow the use of tokens created with make_token. Subsequently, all WMI related functionalities in the beacon process that require the use of an alternate token will fail and this can't be remedied.

To fix this, I have modified the ICorRuntimeHost function in bofnet_execute.cpp by adding a call to CoInitializeSecurity. An entry for CoInitializeSecurity must be made in utils.h also.

I also added a call to CoUninitialize at the bottom of the function to close the COM library once BOF.NET is done with it. This was causing a further issue with the TrustedSec BOF's which would try to intialize COM and fail because BOF.NET had already initialized it but hadn't closed it.

static ICorRuntimeHost* loadCLR(bool v4){

    BOF_LOCAL(OLE32, CoInitializeEx);
    BOF_LOCAL(OLE32, CoCreateInstance);
    BOF_LOCAL(OLE32, CLSIDFromString);
    BOF_LOCAL(OLE32, CoUninitialize); 
    BOF_LOCAL(OLE32, CoInitializeSecurity);  
    BOF_LOCAL(KERNEL32, LoadLibraryA);

    GUID                    IID_RTH, CLSID_RTH, IID_MH, CLSID_MH, CLSID_RH, IID_RH, IID_RHI;
    HRESULT                 hr;
    ICorRuntimeHost*        result = nullptr;
    ICLRMetaHost*           pMetaHost = nullptr;
    ICLRRuntimeInfo*        pRuntimeInfo = nullptr;
    ICLRRuntimeHost*        pClrRuntimeHost = nullptr;
    CLRCreateInstancePtr    pCLRCreateInstance = nullptr;
    HMODULE                 hMod = NULL;

    CLSIDFromString(L"{cb2f6722-ab3a-11d2-9c40-00c04fa30a3e}", &IID_RTH);
    CLSIDFromString(L"{cb2f6723-ab3a-11d2-9c40-00c04fa30a3e}", &CLSID_RTH);
    CLSIDFromString(L"{d332db9e-b9b3-4125-8207-a14884f53216}", &IID_MH);
    CLSIDFromString(L"{9280188D-0E8E-4867-B30C-7FA83884E8DE}", &CLSID_MH);
    CLSIDFromString(L"{bd39d1d2-ba2f-486a-89b0-b4b0cb466891}", &IID_RHI);
    CLSIDFromString(L"{90f1a06e-7712-4762-86b5-7a5eba6bdb02}", &CLSID_RH);
    CLSIDFromString(L"{90f1a06c-7712-4762-86b5-7a5eba6bdb02}", &IID_RH);

    if( (hMod = LoadLibraryA("mscoree.dll")) != NULL){
        pCLRCreateInstance = (CLRCreateInstancePtr)GetProcAddress(hMod,"CLRCreateInstance");
        if(pCLRCreateInstance == nullptr){
            log("[=]Failed to get v2 ICorRuntimeHost: 0x%x, will try .NET 2 method", hr);
            v4 = false;
        }
    }

    hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);

    hr = CoInitializeSecurity( //Failure of this function does not necessarily mean we failed to initialize, it will fail on repeated calls, but the values from the original call are retained
        NULL,
        -1,
        NULL,
        NULL,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        EOAC_DYNAMIC_CLOAKING,
        NULL);


    if(v4 && (hr = pCLRCreateInstance(CLSID_MH, IID_MH, (LPVOID*)&pMetaHost) == S_OK)){

        if((hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_RHI, (LPVOID*)&pRuntimeInfo)) == S_OK){
            if((hr = pRuntimeInfo->GetInterface(CLSID_RH, IID_RH, (LPVOID*)&pClrRuntimeHost)) == S_OK){;
                hr = pClrRuntimeHost->Start();
                hr = pRuntimeInfo->GetInterface(CLSID_RTH, IID_RTH, (LPVOID *)&result);
            }else{
                log("Failed to get CLR runtime host: 0x%x", hr);
            }
        }else{
            log("Failed to get v4 runtime info: 0x%x", hr);
        }

    }else{
        if( (hr = CoCreateInstance(CLSID_RTH, nullptr, CLSCTX_ALL, IID_RTH,(LPVOID*)&result)) == S_OK){
            hr = result->Start();
        }else{
            log("Failed to get v2 ICorRuntimeHost: 0x%x", hr);
        }
    }
    CoUninitialize();

    return result;
}

Cannot create bofnet_execute.cpp.x64.obj

I have attempted to build the solution and although it successfully created BOFNET.dll and bofnet.cna, it did not create bofnet_execute.cpp.x64.obj. From the cobalt strike server, the cna script needs to be in the same repository as the .obj file.

Therefore, how are we expected to build the bofnet_execute.cpp.x64.obj file?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.