#include <stdio.h>
#include <Windows.h>
#include <wincrypt.h>
#include <stdlib.h> // for malloc
#include <string.h> // for strcmp
#include <ctype.h> // for tolower
char* IPv4Fuscation(int firstoctet, int secondoctet, int thirdoctet, int fourthoctet)
{
// Allocate memory dynamically to avoid returning a pointer to a local variable
char* ipv4 = (char*)malloc(16); // Enough to hold an IPv4 address in string format
if (ipv4 == NULL)
{
return NULL; // Handle memory allocation failure
}
// Format the IPv4 address
sprintf_s(ipv4, 16, "%d.%d.%d.%d", firstoctet, secondoctet, thirdoctet, fourthoctet);
return ipv4;
}
BOOL IPv4Output(unsigned char* ipShellcode, SIZE_T ipShellcodeSize)
{
// Check if the input is valid
if (ipShellcode == NULL || ipShellcodeSize == 0 || ipShellcodeSize % 4 != 0)
{
printf("Error: Shellcode Code Bytes\\n");
return FALSE;
}
printf("char* Ipv4Array[%d] = { \\n\\t", (int)(ipShellcodeSize / 4));
int counter = 0;
char* IPv4 = NULL;
for (SIZE_T i = 0; i < ipShellcodeSize; i += 4)
{
counter++;
IPv4 = IPv4Fuscation(ipShellcode[i], ipShellcode[i + 1], ipShellcode[i + 2], ipShellcode[i + 3]);
if (IPv4 == NULL)
{
printf("Memory allocation error\\n");
return FALSE;
}
if (i == ipShellcodeSize - 4)
{
// Printing the last IPv4 address
printf("\\"%s\\"", IPv4);
}
else
{
// Printing the IPv4 address
printf("\\"%s\\", ", IPv4);
}
// Free the dynamically allocated IPv4 string after use
free(IPv4);
if (counter % 8 == 0)
{
printf("\\n\\t");
}
}
printf("\\n};\\n\\n");
return TRUE;
}
char* IPv6Fuscation(int firstpartone, int firstparttwo, int secondpartone, int secondparttwo,
int thirdpartone, int thirdparttwo, int fourthpartone, int fourthparttwo,
int fifthpartone, int fifthparttwo, int sixthpartone, int sixthparttwo,
int seventhpartone, int seventhparttwo, int eighthpartone, int eighthparttwo)
{
char* IPv6 = (char*)malloc(128 * sizeof(char)); // Dynamically allocate memory for IPv6 string
if (IPv6 == NULL)
{
printf("Memory allocation failed\\n");
return NULL;
}
// Combining parts to generate the IPv6 address
sprintf_s(IPv6, 128, "%0.2X%0.2X:%0.2X%0.2X:%0.2X%0.2X:%0.2X%0.2X:%0.2X%0.2X:%0.2X%0.2X:%0.2X%0.2X:%0.2X%0.2X",
firstpartone, firstparttwo, secondpartone, secondparttwo,
thirdpartone, thirdparttwo, fourthpartone, fourthparttwo,
fifthpartone, fifthparttwo, sixthpartone, sixthparttwo,
seventhpartone, seventhparttwo, eighthpartone, eighthparttwo);
return IPv6;
}
BOOL GenerateIPv6(unsigned char* pShellcode, SIZE_T ShellcodeSize) {
if (pShellcode == NULL || ShellcodeSize == 0 || ShellcodeSize % 16 != 0)
{
printf("Error In Shellcode Size\\n");
return FALSE;
}
printf("char* Ipv6Array [%d] = { \\n\\t", (int)(ShellcodeSize / 16));
int c = 16, counter = 0;
char* IPv6 = NULL;
for (int i = 0; i < ShellcodeSize; i += 16)
{
IPv6 = IPv6Fuscation(
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 (IPv6 == NULL)
{
return FALSE; // Exit if memory allocation failed
}
if (i == ShellcodeSize - 16)
{
// Printing the last IPv6 address
printf("\\"%s\\"", IPv6);
}
else
{
// Printing the IPv6 address
printf("\\"%s\\", ", IPv6);
}
free(IPv6); // Free dynamically allocated memory
c = 1;
counter++;
// Optional: To beautify the output on the console
if (counter % 3 == 0)
{
printf("\\n\\t");
}
}
printf("\\n};\\n\\n");
return TRUE;
}
char* MACFuscation(int fristpart, int secondpart, int thirdpart, int fourthpart, int fifthpart, int sixthpart)
{
// Dynamiclly Allocating 64 Bytes
char* MAC = (char*)malloc(64 * sizeof(char));
// Combining MAC Address Parts and save it to the MAC Variable
sprintf_s(MAC, 64, "%0.2X-%0.2X-%0.2X-%0.2X-%0.2X-%0.2X", fristpart, secondpart, thirdpart, fourthpart, fifthpart, sixthpart);
return MAC;
}
BOOL GenerateMAC(unsigned char* shellcode, SIZE_T shellcodesize)
{
//Checker
if (shellcode == NULL || shellcodesize == NULL || shellcodesize % 6 != 0)
{
printf("Error In Your Shellcode!\\n");
return EXIT_FAILURE;
}
printf("char* MACAddresses [%d] = { \\n\\t", (int)(shellcodesize / 6));
int c = 6, counter = 0;
char* MAC = NULL;
for (int i = 0; i < shellcodesize; i += 6)
{
MAC = MACFuscation(shellcode[i], shellcode[i + 1], shellcode[i + 2], shellcode[i + 3], shellcode[i + 4], shellcode[i + 5]);
if (MAC == NULL)
{
return FALSE; // Exit if memory allocation failed
}
if (i == shellcodesize - 6)
{
// Printing the last IPv6 address
printf("\\"%s\\"", MAC);
}
else
{
// Printing the IPv6 address
printf("\\"%s\\", ", MAC);
}
free(MAC); // Free dynamically allocated memory
c = 1;
counter++;
// Optional: To beautify the output on the console
if (counter % 3 == 0)
{
printf("\\n\\t");
}
}
printf("\\n};\\n\\n");
return TRUE;
}
char* UUIDFuscation(int firstpartone, int firstparttwo, int secondpartone, int secondparttwo,
int thirdpartone, int thirdparttwo, int fourthpartone, int fourthparttwo,
int fifthpartone, int fifthparttwo, int sixthpartone, int sixthparttwo,
int seventhpartone, int seventhparttwo, int eighthpartone, int eighthparttwo)
{
char* UUID = (char*)malloc(128 * sizeof(char));
if (UUID == NULL)
{
printf("Memory allocation for UUID failed\\n");
return NULL;
}
// Generating the UUID parts and combining them
sprintf_s(UUID, 128,
"%0.2X%0.2X%0.2X%0.2X-%0.2X%0.2X-%0.2X%0.2X-%0.2X%0.2X-%0.2X%0.2X%0.2X%0.2X%0.2X%0.2X",
(unsigned char)secondparttwo, (unsigned char)secondpartone,
(unsigned char)firstparttwo, (unsigned char)firstpartone,
(unsigned char)thirdparttwo, (unsigned char)thirdpartone,
(unsigned char)fourthparttwo, (unsigned char)fourthpartone,
(unsigned char)fifthpartone, (unsigned char)fifthparttwo,
(unsigned char)sixthpartone, (unsigned char)sixthparttwo,
(unsigned char)seventhpartone, (unsigned char)seventhparttwo,
(unsigned char)eighthpartone, (unsigned char)eighthparttwo);
return UUID;
}
BOOL GenerateUUID(char* shellcode, SIZE_T shellcodesize)
{
if (shellcode == NULL || shellcodesize < 16 || shellcodesize % 16 != 0)
{
printf("Error in your shellcode!\\n");
return FALSE;
}
printf("char* UuidArray[%d] = { \\n\\t", (int)(shellcodesize / 16));
char* UUID = NULL;
for (int i = 0; i < shellcodesize; i += 16)
{
UUID = UUIDFuscation(
shellcode[i], shellcode[i + 1], shellcode[i + 2], shellcode[i + 3],
shellcode[i + 4], shellcode[i + 5], shellcode[i + 6], shellcode[i + 7],
shellcode[i + 8], shellcode[i + 9], shellcode[i + 10], shellcode[i + 11],
shellcode[i + 12], shellcode[i + 13], shellcode[i + 14], shellcode[i + 15]
);
if (UUID != NULL)
{
if (i + 16 >= shellcodesize)
{
printf("\\"%s\\"", UUID);
}
else
{
printf("\\"%s\\", ", UUID);
}
free(UUID);
}
}
printf("\\n};\\n\\n");
return TRUE;
}
char* toLowerStr(char* str)
{
for (int i = 0; str[i]; i++)
{
str[i] = tolower(str[i]);
}
return str;
}
unsigned char* readShellcodeFromFile(const char* filename, size_t* shellcodeSize)
{
FILE* file;
if (fopen_s(&file, filename, "rb") != 0 || file == NULL)
{
perror("Error opening file"); // This will print a more detailed error message
return NULL;
}
fseek(file, 0, SEEK_END); // Move to the end of the file
long size = ftell(file); // Get the file size
fseek(file, 0, SEEK_SET); // Move back to the beginning of the file
unsigned char* shellcode = (unsigned char*)malloc(size);
if (shellcode == NULL)
{
perror("Memory allocation failed");
fclose(file); // Don't forget to close the file on error
return NULL;
}
size_t bytesRead = fread(shellcode, 1, size, file);
if (bytesRead != size)
{
perror("Error reading file");
free(shellcode);
fclose(file);
return NULL;
}
fclose(file);
*shellcodeSize = bytesRead;
return shellcode;
}
// Main function with improved argument handling and mode case-insensitivity
int main(int argc, char* argv[])
{
printf("\\t\\t#############################################\\n");
printf("\\t\\t# Welcome To Karma Payload Obfuscator #\\n");
printf("\\t\\t#############################################\\n\\n");
if (argc < 3)
{
printf("Available Modes: \\nXOR \\t(For XOR Encrypting Payload)\\nIPv4 \\t(For IPv4 Fuscating The Payload)\\nIPv6 \\t(For IPv6 Fuscating The Payload)\\nMAC \\t(For MAC Fuscating The Payload)\\nUUID \\t(For UUID Fuscating The Payload)\\n\\n");
printf("Usage: karma.exe mode shellcode.bin\\n");
return EXIT_FAILURE;
}
printf("[*] Choosen Mode: %s\\n", argv[1]);
printf("[*] Shellcode File: %s\\n", argv[2]);
char* mode = toLowerStr(argv[1]);
size_t shellcodeSize;
char* filename = argv[2];
unsigned char* shellcode = readShellcodeFromFile(filename, &shellcodeSize);
printf("[*] Original Payload Size: %d Bytes\\n", shellcodeSize);
if (shellcode == NULL)
{
return EXIT_FAILURE;
}
int newsize = 0;
if (strcmp(mode,"ipv4") == 0)
{
if (shellcodeSize % 4 != 0)
{
printf("[!] Not Optimal Size For IPv4 Fuscation Extending To New Size...\\n");
// Calculate new size
newsize = (shellcodeSize / 4 + 1) * 4;
printf("[*] New Payload Size: %d\\n", newsize);
// Resize shellcode and check for failure
unsigned char* newShellcode = realloc(shellcode, newsize);
if (newShellcode == NULL) {
printf("[!] Memory allocation failed\\n");
free(shellcode); // Free original if realloc fails
return; // Exit or handle error appropriately
}
shellcode = newShellcode; // Update shellcode pointer
// Fill the extra space with NOP instructions (0x90)
memset(shellcode + shellcodeSize, 0x90, newsize - shellcodeSize);
// Calculate number of NOPs added
int nops = newsize - shellcodeSize;
printf("[!] Filled The Payload With %d NOP Instructions\\n", nops);
printf("[+] IPv4 Fuscating the shellcode...\\n");
IPv4Output(shellcode, newsize);
}
else
{
printf("[+] IPv4 Fuscating the shellcode...\\n");
IPv4Output(shellcode, shellcodeSize);
}
}
else if (strcmp(mode, "ipv6") == 0)
{
if (shellcodeSize % 16 != 0)
{
printf("[!] Not Optimal Size For IPv6 Fuscation Extending To New Size...\\n");
// Calculate new size
newsize = (shellcodeSize / 16 + 1) * 16;
printf("[*] New Payload Size: %d\\n", newsize);
// Resize shellcode and check for failure
unsigned char* newShellcode = realloc(shellcode, newsize);
if (newShellcode == NULL) {
printf("[!] Memory allocation failed\\n");
free(shellcode); // Free original if realloc fails
return; // Exit or handle error appropriately
}
shellcode = newShellcode; // Update shellcode pointer
// Fill the extra space with NOP instructions (0x90)
memset(shellcode + shellcodeSize, 0x90, newsize - shellcodeSize);
// Calculate number of NOPs added
int nops = newsize - shellcodeSize;
printf("[!] Filled The Payload With %d NOP Instructions\\n", nops);
printf("[+] IPv6 Fuscating the shellcode...\\n");
GenerateIPv6(shellcode, newsize);
}
else
{
printf("[+] IPv6 Fuscating the shellcode...\\n");
GenerateIPv6(shellcode, shellcodeSize);
}
}
else if (strcmp(mode, "mac") == 0)
{
if (shellcodeSize % 6 != 0)
{
printf("[!] Not Optimal Size For MAC Fuscation Extending To New Size...\\n");
// Calculate new size
newsize = (shellcodeSize / 6 + 1) * 6;
printf("[*] New Payload Size: %d\\n", newsize);
// Resize shellcode and check for failure
unsigned char* newShellcode = realloc(shellcode, newsize);
if (newShellcode == NULL) {
printf("[!] Memory allocation failed\\n");
free(shellcode); // Free original if realloc fails
return; // Exit or handle error appropriately
}
shellcode = newShellcode; // Update shellcode pointer
// Fill the extra space with NOP instructions (0x90)
memset(shellcode + shellcodeSize, 0x90, newsize - shellcodeSize);
// Calculate number of NOPs added
int nops = newsize - shellcodeSize;
printf("[!] Filled The Payload With %d NOP Instructions\\n", nops);
printf("[+] MAC Fuscating the shellcode...\\n");
GenerateMAC(shellcode, newsize);
}
else
{
printf("[+] MAC Fuscating the shellcode...\\n");
GenerateMAC(shellcode, shellcodeSize);
}
}
else if (strcmp(mode, "uuid") == 0)
{
if (shellcodeSize % 16 != 0)
{
printf("[!] Not Optimal Size For UUID Fuscation Extending To New Size...\\n");
// Calculate new size
newsize = (shellcodeSize / 16 + 1) * 16;
printf("[*] New Payload Size: %d\\n", newsize);
// Resize shellcode and check for failure
unsigned char* newShellcode = realloc(shellcode, newsize);
if (newShellcode == NULL) {
printf("[!] Memory allocation failed\\n");
free(shellcode); // Free original if realloc fails
return; // Exit or handle error appropriately
}
shellcode = newShellcode; // Update shellcode pointer
// Fill the extra space with NOP instructions (0x90)
memset(shellcode + shellcodeSize, 0x90, newsize - shellcodeSize);
// Calculate number of NOPs added
int nops = newsize - shellcodeSize;
printf("[!] Filled The Payload With %d NOP Instructions\\n", nops);
printf("[+] UUID Fuscating the shellcode...\\n");
GenerateUUID((char*)shellcode, newsize);
}
else
{
printf("[+] UUID Fuscating the shellcode...\\n");
GenerateUUID((char*)shellcode, shellcodeSize);
}
}
else
{
printf("[!] Invalid Mode!\\n");
return EXIT_FAILURE;
}
free(shellcode);
printf("Thanks For Using Karma!\\n");
return EXIT_SUCCESS;
}