# Obfuscating Payloads

Now that we have a successful workflow, we can start messing around with removing Indicators of Compromise (IOCs) and obfuscating our payloads with a variety of methods. We will re-use our Seatbelt example from the previous section

### Module Objectives

* Create a build step to check for Indicators of Compromise (IOC)
* Use Powershell to remove the IOC from our project
* Obfuscate our payload using ConfuserEx
* Check the payload against ThreatCheck
* Obfuscate Go Binaries
* Periodic Scanning with VirusTotal\*

### Required Tools

#### Payloads

We will be using Ligolo-ng and Seatbelt

{% tabs %}
{% tab title="C#" %}

* [Rubeus](https://github.com/GhostPack/Rubeus)
* [Seatbelt](https://github.com/GhostPack/Seatbelt)
* [SafetyKatz](https://github.com/GhostPack/SafetyKatz)
* [SharpLigolo](https://github.com/S3cur3Th1sSh1t/SharpLigolo)
  {% endtab %}

{% tab title="Golang" %}

* [Ligolo-ng](https://github.com/Nicocha30/ligolo-ng)
* [Shellcode Runner](https://github.com/ChrisPritchard/golang-shellcode-runner)
  {% endtab %}
  {% endtabs %}

#### Detection Tools

{% tabs %}
{% tab title="Threat Detection" %}

* [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck)
* [BestEdrOfTheMarket](https://github.com/Xacone/BestEdrOfTheMarket)
* [CrimsonEDR](https://github.com/Helixo32/CrimsonEDR)
  {% endtab %}

{% tab title="File Analysis" %}

* [YARA](https://github.com/virustotal/yara/releases/tag/v4.5.0)
  * [Rules](https://github.com/Securescape/Offensive-Development/tree/main/YARA%20Rules)
    {% endtab %}
    {% endtabs %}

#### Obfuscation

{% tabs %}
{% tab title="C#" %}

* [ConfuserEx](https://github.com/mkaring/ConfuserEx)
* [neo-ConfuserEx](https://github.com/XenocodeRCE/neo-ConfuserEx) - *Use this instead since it's newer*
  {% endtab %}

{% tab title="Golang" %}

* [Garble](https://github.com/burrowers/garble)
  {% endtab %}
  {% endtabs %}

### Installing Detection Tools

{% hint style="info" %}
**Section Objectives**

* Install YARA
  * Download YARA Rules
  * Test our artifact against YARA
* Install and Build ThreatCheck
  * Analyse our artifact with ThreatCheck
  * Detect Bad Bytes
    {% endhint %}

Before we begin, we will need to install some tools that will detect our payload - which we can later use within our build steps to pass or fail the project before publishing an artifact.

#### YARA

YARA is a file analysis tool which dissects and searches for bad characters based on a set of rules. Rules can be downloaded from many sources - for our demo, we have included the rules that we will be using.

Download the binary from the link above, then place it in a reachable directory. I will store all of the tools we're using in `C:\Tools` to keep things organised. After extracting YARA, download the rules from [this repository](https://github.com/Securescape/Offensive-Development/tree/main/YARA%20Rules) and place them inside YARA's root folder. It should look like this

```
Directory: C:\Tools\yara


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         4/24/2024   6:24 PM            735 rubeus.yar
-a----         4/24/2024   6:24 PM            756 safetykatz.yar
-a----         4/24/2024   6:24 PM            750 seatbelt.yar
-a----         4/24/2024   6:24 PM            484 sharpligolo.yar
-a----         2/13/2024  11:02 AM        2417152 yara64.exe
-a----         2/13/2024  11:02 AM        2362880 yarac64.exe
```

Test the rule against a Seatbelt artifact:

<pre class="language-powershell" data-overflow="wrap"><code class="lang-powershell"><strong>PS> .\yara64.exe -s .\seatbelt.yar C:\..\Seatbelt\bin\Release\Seatbelt.exe
</strong>
HackTool_MSIL_SEATBELT_2 C:\BuildAgent\work\8306664e377be4bb\Seatbelt\bin\Release\Seatbelt.exe
</code></pre>

<figure><img src="/files/YhkroFgt3hw7QlG7Rqkx" alt=""><figcaption><p>YARA detecting our payload</p></figcaption></figure>

We can see that YARA found the [hardcoded GUID](https://github.com/GhostPack/Seatbelt/blob/master/Seatbelt/Properties/AssemblyInfo.cs) which is included in Seatbelt's original project - we will need to remove this IOC if we want to be slightly stealthier.

#### ThreatCheck

[ThreatCheck ](https://github.com/rasta-mouse/ThreatCheck)is a tool developed by Daniel Duggan (RastaMouse) which cuts up binaries and detect the exact bytes which AV solutions hate. We can use this tool to detect if anything needs to be patched post obfuscation

To install it, clone the repository to your directory of choice, compile it using Visual Studio 2019 or through `dotnet.exe` - I will be using VS 2019 for this

```bash
git clone https://github.com/rasta-mouse/ThreatCheck.git
mv .\ThreatCheck\ThreatCheck\ ThreatC
echo A | rm -Force .\ThreatCheck\
mv .\ThreatC\ ThreatCheck
```

Open the solution in Visual Studio, then select `Release` and build

<figure><img src="/files/lSF2eozoK06HWOEDRZH5" alt=""><figcaption><p>ThreatCheck Release</p></figcaption></figure>

Once built, you will find the binary in the bin folder&#x20;

`C:\Tools\ThreatCheck\ThreatCheck\bin\Release`

{% hint style="danger" %}
In order for ThreatCheck to work properly, we need to disable Windows Defender on our system so that the data isn't being deleted during analysis
{% endhint %}

```powershell
PS> C:\Tools\ThreatCheck\...\ThreatCheck.exe -f C:\...\Seatbelt.exe
```

<figure><img src="/files/bon9Zm3j6D4X7tkvn4YN" alt=""><figcaption><p>ThreatCheck running against Seatbelt</p></figcaption></figure>

### Removing IOCs using Powershell

Now that we know how basic detections can screw up our payload, let us see how we can bypass them. The first step is removing the hard-coded GUID string in `Seatbelt\Properties\AssemblyInfo.cs` (The same applies for Rubeus and the rest)

In our Seatbelt build configuration, add a new build step and select Powershell, we will use a small script to generate a random GUID, then replace the old one with it *(Slightly modified from* [*Devops for PT*](https://training.zeropointsecurity.co.uk/courses/devops-for-pentesters)*)*

```powershell
# Get relative path of AssemblyInfo.cs
$teamCityProjectName = "%teamcity.projectName%"
$path = ".\$teamCityProjectName\Properties\AssemblyInfo.cs"
Write-Output "Project Path: $path"

# Read file
$content = Get-Content -Path $path -Raw
Write-Output "Original Content:"
Write-Output "$content" 

# Generate a new random GUID
$newGuid = [System.Guid]::NewGuid().ToString()
Write-Output "Random GUID: $newGuid"

# Replace the GUID with our random one (Will work with any GUID)
$content = $content | ForEach-Object { $_ -replace '\[assembly: Guid\("[^"]*"\)\]', "[assembly: Guid(`"$newGuid`")]"}
Write-Output $content

# Overwrite the file
$content | Set-Content -Path $path
```

<figure><img src="/files/pQDg0xNal5bJ9Q3DGF4W" alt=""><figcaption><p>Replace GUID Script</p></figcaption></figure>

Then move the build step above the compilation step using the `Reorder Build Steps` option

<figure><img src="/files/pgvGfDRTmUYo9yU77Npd" alt=""><figcaption><p>Reordering the build step</p></figcaption></figure>

Now, we need to add a parameter to our builder which includes the TeamCity project name using `%system.teamcity.projectName%`

<figure><img src="/files/yom9REi77vvq5daDlUOi" alt=""><figcaption><p>Build Parameter</p></figcaption></figure>

Save this, then build the project. Check the file using YARA afterwards - you should see from the build logs that our GUID changed from `aec32155-d589-4150-8fe7-2900df4554c8` to `a9d35d54-019f-45dd-839d-6243648dcac6`

<figure><img src="/files/LsU6KwOjkIazGNhZF4xf" alt=""><figcaption><p>AssemblyInfo.cs after replacing our IOC</p></figcaption></figure>

We can confirm this change using YARA

<figure><img src="/files/dGglRHuQ3Un7Sav7Xuym" alt=""><figcaption><p>YARA Confirmation</p></figcaption></figure>

...and dnSpy

<figure><img src="/files/Y6gShYYVCMYS9gpY73sT" alt=""><figcaption><p>dnSpy confirmation</p></figcaption></figure>

The Powershell template being used can be re-used for the other [GhostPack](https://github.com/GhostPack) projects. This method is not sufficient to not get detected by ThreatCheck - though our next method will

### Removing IOCs using ConfuserEx

{% hint style="info" %}
**Section Objectives**

* Use ConfuserEx GUI to pack Seatbelt
* Use the different rules given by ConfuserEx
* Check Seatbelt against ThreatCheck before and after obfuscation
* Integrate ConfuserEx CLI into our Build Pipeline
  {% endhint %}

[ConfuserEx](https://github.com/mkaring/ConfuserEx) is a .NET obfuscation tool which hides symbols and makes it difficult to understand what a C# executable does statically. To get started, download the latest binary (ConfuserEx.zip) from the Release page, and save it in your Tools folder (Mine is in `C:\Tools`)

ConfuserEx templates are written in XML , and can be referenced at:

* <https://github.com/mkaring/ConfuserEx/blob/master/docs/ProjectFormat.md>
* <https://github.com/mkaring/ConfuserEx/wiki/Documentation>
* <https://github.com/mkaring/ConfuserEx/wiki/Protections>

A basic template which uses an aggressive preset can be written as follows

{% code overflow="wrap" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<project baseDir="<BASE DIRECTORY>" outputDir="<OUTPUT DIRECTORY>" xmlns="http://confuser.codeplex.com">
    <rule pattern="true" preset="aggressive" inherit="false" />
    <packer id="compressor" />
    <module path="<TARGET FILE>" /> 
</project>
```

{% endcode %}

The `project` element describes where the file will reside after ConfuserEx runs. The `rule` element refers to which rules it should use, `packer` specifies what type of packer ConfuserEx should utilise, and `module` is for the target path. ConfuserEx lets you specify multiple rules and modules, and can cover both DLLs and binary files alike - which can be useful for DLL type payloads.

You can also add more protections listed in the [third link](https://github.com/mkaring/ConfuserEx/wiki/Protections)

```xml
<?xml version="1.0" encoding="utf-8"?>
<project baseDir="<BASE DIRECTORY>" outputDir="<OUTPUT DIRECTORY>" xmlns="http://confuser.codeplex.com">
    <rule pattern="true" preset="aggressive" inherit="false">
        <protection id="anti debug" />
        <protection id="anti dump" />
        <protection id="anti ildasm" />
        <protection id="anti tamper" />
        <protection id="constants" />
        <protection id="ctrl flow" />
        <protection id="invalid metadata" />
        <protection id="resources" />
    </rule>
    <packer id="compressor" />
    <module path="<TARGET FILE>" />
</project>
```

Some protections take additional parameters as well, such as the `anti debug` protection which takes 3 arguments (taken from [here](https://github.com/mkaring/ConfuserEx/wiki/Anti-Debug-Protection))

* `safe`: ConfuserEx would detect debugger/profiler using managed API *(default)*
* `win32`: ConfuserEx would detect debugger/profiler using unmanaged WinAPI (**Incompatible with OS other than Windows**)
* `antinet`: ConfuserEx would detect debugger/profiler using [antinet](https://github.com/0xd4d/antinet) by @0xd4d&#x20;

In XML form, it will look like this

```xml
<protection id="anti debug">
  <argument name="mode" value="win32" />
</protection>
```

This allows us to beef up some of our default rules when it comes to templates and automating the obfuscation process

#### GUI Version

Before creating our pipeline, let's first use the GUI tool to examine the before and after of our Seatbelt executable. This will help us understand what to expect once a build has been completed. We will also testing our executable against ThreatCheck to confirm that it worked

Start the ConfuserEx application located in `C:\Tools\ConfuserEx\ConfuserEx.exe` (the directory you've extracted to), and create a new folder within the Tools directory where you will store the output - I've included our payload from the previous build inside of our output folder for comparison

<figure><img src="/files/ozGG3yv1lG6rb0OILmr1" alt=""><figcaption><p>ConfuserEx GUI page</p></figcaption></figure>

Drag and drop your binary into the modules tab, then click on `Settings`. You should be able to see your binary's name displayed in the list. Click on this, then press the plus button to add a rule. Click on the packer check box as well.

<figure><img src="/files/n0g3utgWIL4Gb5JHAyrD" alt=""><figcaption><p>ConfuserEx Settings</p></figcaption></figure>

Press the Edit button on the left to bring up the rules you want to use - for this, we will be using the basic Aggressive preset - experiment on your own to see what works well for you

<figure><img src="/files/sWO95sjU6EDzNPJ5Jb5O" alt=""><figcaption><p>ConfuserEx Aggressive Preset</p></figcaption></figure>

Click `Done` once you're happy with the settings, then go to the `Protect` tab on the main interface and hit `Protect` to start packing your binary. Once it's complete, run ThreatCheck on your test binary, and the one you've packed to see the difference

<figure><img src="/files/HDDX4mwzAkvqfapUbFEU" alt=""><figcaption><p>ConfuserEx - Running Protect</p></figcaption></figure>

<figure><img src="/files/mtvpihseonhwJtGHzhHQ" alt=""><figcaption><p>Before Obfuscation</p></figcaption></figure>

<figure><img src="/files/HKWVe1E5IAUdym0NkFO0" alt=""><figcaption><p>After Obfuscation</p></figcaption></figure>

You can decrease the detected bytes through other means as well - such as running the executable through a loader, or by using more protections/rules through ConfuserEx.

#### Integrating ConfuserEx into our build pipeline

Instead of doing this manually, we can integrate ConfuserEx's template into our build pipeline with the use of a PowerShell script. Create the following scripts inside the C:\Tools\ConfuserEx directory, and save it as `aggressive_template.ps1`

```powershell
param 
(
[Parameter(Mandatory=$true)] [String]$path, 
[Parameter(Mandatory=$true)] [String]$projectName 
)

$template = @"
<project baseDir="$path" outputDir="$path" xmlns="http://confuser.codeplex.com">
    <rule pattern="true" preset="aggressive" inherit="false">
        <protection id="anti debug" />
        <protection id="anti dump" />
        <protection id="anti ildasm" />
        <protection id="anti tamper" />
        <protection id="constants" />
        <protection id="ctrl flow" />
        <protection id="invalid metadata" />
        <protection id="resources" />
    </rule>
    <packer id="compressor" />
    <module path="$projectName.exe" />
</project>
"@

Write-Output "[+] Using ConfuserEx with $PSCommandPath"

$template | Out-File -FilePath "$path\$projectName.crproj"
C:\Tools\ConfuserEx\Confuser.CLI.exe -n "$path\$projectName.crproj"
```

Where:

* `$path` is where the release directory is
* `$projectName` is the project name

These variables will be used in TeamCity as such:

1. Create a new build step for ConfuserEx using the PowerShell runner

<figure><img src="/files/7wBIIs9EEgiAEdEGTG0q" alt=""><figcaption><p>ConfuserEx build step</p></figcaption></figure>

2. Specify the script file and the arguments TeamCity should execute

```powershell
"%teamcity.build.checkoutDir%\%teamcity.projectName%\bin\Release"
"%teamcity.projectName%"
```

<figure><img src="/files/KF8xpMHZS7R0ydX9ETf5" alt=""><figcaption><p>Script Arguments</p></figcaption></figure>

Run the build step, then verify that it worked by using dnSpy

<figure><img src="/files/6OQTywikIcrjsuAcwhV7" alt=""><figcaption><p>Expected Build Log output</p></figcaption></figure>

<figure><img src="/files/Rb4L5lQtr05NfqPFDJB0" alt=""><figcaption><p>dnSpy results</p></figcaption></figure>

```powershell
PS C:\Tools\SEATBELT - TESTING> C:\ThreatCheck.exe -f "C:\Seatbelt.exe"
[+] No threat found!
```

### Build Tests using ThreatCheck

{% hint style="info" %}
**Section Objectives**

* Integrate ThreatCheck into our build pipeline
* Fail builds that get detected by ThreatCheck
  {% endhint %}

The last step (for now) is to check the artifact against ThreatCheck to make sure that it's properly obfuscated. To do this, we will create a new PowerShell script with the following:

{% code overflow="wrap" %}

```powershell
param 
(
[Parameter(Mandatory=$true)] [String]$path,
[Parameter(Mandatory=$true)] [String]$projectName 
)

Write-Output "[+] Executing Threat Check"
C:\Tools\ThreatCheck\ThreatCheck\bin\Release\ThreatCheck.exe -f "$path\$projectName.exe"
```

{% endcode %}

Then, repeat the previous execution arguments for TeamCity

```powershell
"%teamcity.build.checkoutDir%\%teamcity.projectName%\bin\Release"
"%teamcity.projectName%"
```

<figure><img src="/files/9ycyt4DSz34zbDvFb92S" alt=""><figcaption><p>ThreatCheck Build Step</p></figcaption></figure>

To test our build step we will run our program twice - once with our ConfuserEx step, and once without.

<figure><img src="/files/Op4FOg1bAPjckPI15lbg" alt=""><figcaption><p>Build Step with ConfuserEx obfuscation</p></figcaption></figure>

<figure><img src="/files/dpBeBtrrYIK43cp4arW5" alt=""><figcaption><p>Disabling ConfuserEx build step</p></figcaption></figure>

<figure><img src="/files/TbQY92hFw1qe5zpKnI8A" alt=""><figcaption><p>Threat Check Bad Bytes Detected</p></figcaption></figure>

We can see that there is a fixed message when a bad segment is detected by Threat Check, we can use this to create a filter which fails our build in case the program is not obfuscated

In your build's `Failure Conditions`, add a new failure condition to match the message received - you can also add other messages if ThreatCheck has other failure messages

Text to look for: `[!] Identified end of bad bytes at offset`

<figure><img src="/files/9xvip7OP5ugf4DPa57Pe" alt=""><figcaption><p>Adding Failure Conditions</p></figcaption></figure>

Test this on our last build step to see if it works

<figure><img src="/files/HqV69kGz3v7NBdKW5EM9" alt=""><figcaption><p>Testing our failure condition</p></figcaption></figure>

We can also test this by re-running our build

<figure><img src="/files/7v1jPq63m73EPrEagNsM" alt=""><figcaption><p>Failed Build due to Bad Bytes</p></figcaption></figure>

Re-enable your obfuscation step and you're done! The next steps would be to

1. Publish artifacts to central file share
2. Copy your build step into a global configuration
3. Check artifact hashes against VirusTotal (Using their API) daily to make sure the binaries aren't burned
4. Create a tool to download your artifact onto your operations machine or into your Command and Control team server
5. Your own creativity :)

### VirusTotal Vetting (WIP)

<https://n3nu.medium.com/automating-hash-vetting-using-virustotal-api-v3-ef53a65c2121>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://blog.securescape.cc/offensive-security/red-team/offensive-development/offensive-devops/teamcity/obfuscating-payloads.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
