Payload Placement

HomeLab

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

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

Introduction

[+] في المقالة اللـ فاتت عرفنا عن ملفات الـ PE والهيكل بتاعها .. وتحديدا جزء الـ Sections ، وعرفنا وظيفة كل سيكشن إيه.

[+] فـ المقالة دي بقي ، هنتكلم عن لو معاك ShellCode ، إزاي تقدر تخليه يتنقل بين السكشنز فـ ملف الـ PE.

[+] وتحديدا هنتكلم عن:

  1. Data Placement
  2. Rdata Placement
  3. Text Placement
  4. Rsrc Placement

تجهيز الـ ShellCode:

[+] قبل مـ نبدأ محتاجين الأول نـ Generate الـ ShellCode اللـ هنشتغل بيه.

[+] هنروح ع الـ Kali Linux machine ، أو أي ماشين عندك عليها الـ Metasploit ، وهنستخدم تحديدا الـ Msfvenom.

[+] هنـ رن الكوماند:

msfvenom -p windows/x64/exec CMD=calc.exe -f c
  • وشرح الكوماند بكل بساطه إنه هيعمل شيل كود وظيفته يفتح الـ Calculator ، والبايلود من نوع exec عشان ينفذ الكود من الـ CMD وع ويندوز نظام الـ 64-bit .. والـ f- دا بقوله إن الكود يكون مناسب لـ لغة برمجة الـ C. (وطبعا تقدر تعمل الشيل كود اللـ انت عاوزه .. انا هنا عملت مجرد مثال بسيط لتوضيع الفكرة ، واللـ بعد كده إنت ودماغك)
ShellCode

وبكدا نكون جاهزين نبدأ.

1. Data Placement:

  1. هنفتح الـ Visual Studio وهنكريت بروچيكت جديد وهنضيف الـ main.c اللـ هنكتب جواه الكود.
  2. Data-Replc
  3. هنضيف المكتبات العادية الـ <windows.h> والـ <stdio.h> .. وهنضيف الشيل كود اللـ عملناه (انا بس غيرت الإسم من buf لـ OurShellCode).
  4. ShellCode2
  5. هنكريت الـ main function ، ومثلا ممكن نطبع الـ address بتاع الشيل كود ده فين فـ الميموري ، وضيفت الـ ()getchar عشان البرنامج ميقفلش ويستني مني أضغط ع أي زرار.
  6. ShellCode3
  7. لو جربت تشغل البرنامج ، اللـ هيحصل إن هيطلعلك العنوان عادي جدا ، مفيش أكشن تاني هيحصل لا. (ملحوظة مهمه: ممكن البرنامج ميشتغلش عشان الـ Windows Defender هيمسكه ، يا توقفه يا تعمل للفولدر كله exclusive)
  8. ولو فاكر من أول مقالة كتبتها وتحديدا جزء الـ Memory Management .. كنا نقدر نوقف البرنامج وناخد العنوان نبحث بيه فـ الميموري .. جربها وهتلاقي الشيل كود.
  9. ShellCode4
  10. تعالي بقي نـ Build البروچيكت اللطيف ده ، وهنعمله ع نمط الـ Release ، ونشوف هل فعلا الشيل كود بتاعنا موجود فـ منطقة الـ [Data.] ولا لا.
  11. ShellCode5
  12. هنفتح الـ PE-Bear ونديله الملف ونحاول ندور فـ السكشنز ، هنلاقي إن فعليا الكود بتاعنا موجود فـ الـ [Data.] ، وعشان نتأكد إن هو فعلا ، إرجع للكود وشوف بداية ونهاية الشيل كود هتلاقيه البداية 0xFC4883 والنهاية 0x786500 .. يعني فعلا إحنا صح.
  13. ShellCode6

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

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

unsigned char OurShellCode[] =
"\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("[-] ShellCode Address: 0x%p", OurShellCode);
  getchar();

  return 0;
}

2. Rdata Placement

[+] طب إيه الإختلاف اللـ هنعمله المرادي؟ مُجرد هنزود كلمة const فـ بداية الـ variable بتاع الشيل كود.

  1. هنبدأ بروچيكت جديد بنفس الخطوات اللـ فاتت ، وهنضيف نفس الكود اللـ فات كله.
  2. هنضيف كلمة const:
  3. ShellCode7

[+] بس كدا ؟ طب إزاي ؟؟

فكره منطقة الـ rdata إنها بتتعامل مع القيم الثابته ، فـ عشان ننقل الشيل كود من الـ data للـ rdata هنحتاج نعرفه إن المتغير اللـ عملناه ده ، مبقاش متغير ، قيمته بقت ثابته.

  • طب تعالي نتأكد هل الكلام ده صح ولا لا .. هنـ Build البروچيكت بنفس الطريقة اللـ فاتت.
  • يلا ع الـ PE-Bear .. لا استني ، المرادي هنستخدم تول تانية عشان الـ PE-Bear محدوده شويتين فـ الداتا اللـ بتطلعها ، هنستخدم Total PE .. إفتح البروجيكت ودور فـ السيكشنز ، هتلاقي الشيل كود فعليا فـ الـ [rdata.] .. يعني إحنا صح تاني.
  • ShellCode8

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

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

const unsigned char OurShellCode[] =
"\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("[-] ShellCode Address: 0x%p", OurShellCode);
  getchar();

  return 0;
}

3. Text Placement

[+] هنغير إيه بقي المرادي؟

بُص يسيدي ، مجرد هتضيف سطرين صغيرين بس وهما:

#pragma section(".text")
__declspec(allocate(".text"))

[+] ودي هتجبر الـ compiler إنه ياخد الداتا دي ويحطها فـ سكشن الـ [text.].

ShellCode9
  • يلا بيناا نتأكد .. هنـ Build .. وع الـ Total PE ، هنلاقي إن فعلا الشيل كود موجود فـ منطقة الـ [.text]
  • ShellCode10
  • ولو جربت المرادي ع الـ PE-Bear هيطلعلك نفس النتيجة:
  • ShellCode11

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

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

#pragma section(".text")
__declspec(allocate(".text")) const unsigned char OurShellCode[] =
"\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("[-] ShellCode Address: 0x%p", OurShellCode);
  getchar();

  return 0;
}

4. Rsrc Placement

[+] هنا بقي وصلنا للـ Big Boss ، المنطقة اللـ أغلبية الهكرز الجامدين بيحطوا أي شيل كود تبهم هنا .. طب ليه المنطقة دي تحديدا ؟ هقولك فـ اخر المقالة.

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

تعالي بقي نبدأ الحدوته:

عشان نعمل ده ، محتاجين نرجع للـ Kali Linux machine ، ونخلي الـ Msfvenom تعمل نفس الشيل كود ، بس المرادي تخليه فـ أيقونه ، من خلال الكوماند ده:

msfvenom -p windows/x64/exec CMD=calc.exe -o calc.ico
  • والإختلاف هنا إني خليت الـ Output يكون جوا أيقونة.
Rsrc-Placement

[+] تعالي أقولك إزاي هنضيف الأيقونه دي جوا الـ Visual Studio:

  1. هتفتح الـ Visual Studio وتعمل بروجيكت جديد ، وتضيف الـ main.c:
  2. Rsrc-Placement2
  3. هتضيف الشيل كود بتاعنا فـ المسار بتاع البرجيكت اللـ شغالين عليه حاليا .. بالنسبالي هو فـ المسار ده:
  4. Rsrc-Placement3
  5. هنروح لمنطقة الـ Resource Files وبعدين Right-click > add > New item > Show All Temples > Resource > Resource File > Add.
  6. Rsrc-Placement4
  7. بعد كدا هيظهر منطقة الأيقونات ، هتعمل Right-click > Add Resource > Import > All Files (*.*) > choose calc.ico > OPEN_EXISTING
  8. Rsrc-Placement5
  9. هتكتب نوع الـ Reasource ان دا RsrcData (أوأي إسم زي مـ تحب) ، وبكدا الأيقونه هتظهرلك بكل محتواها.
  10. Rsrc-Placement6
  11. بعدين ارجع للـ main.c ، واقفل الـ Resource View .. هتلاقي إن انضاف جزء جديد اسمه Resource.h .. هتضيفه فـ الكود بالشكل ده:
  12. Rsrc-Placement7

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

  1. أول حاجه هنحتاج نعرف الأيقونه دي مكانها فين ، عشان كدا أول عملية هنستخدمها هي الـ ()FindResourceW ، ودي دورها إنها بتدور جوا الـ Resources ع ملف معين.
  2. دلوقتي عرفنا المكان .. محتاجين بقي نعرف حجمها قد ايه .. وهنستخدم ()SizeofResource.
  3. بعد كدا هنحتاج نحمل الأيقونة دي فـ الميموري .. وهنستخدم ()LoadResource.
  4. آخر جزء وهو محتاجين نوصل للمحتوي اللـ جوا الأيقونه ، اللـ هو الشيل كود بتاعنا .. وهنستخدم ()LockResource.

[+] يلا بينا هنبدأ شرح الكود:

  • أول جزء فـ الكود .. عرفت متغير اسمه hRsrc من نوع HRSRC وحطيت فيه NULL كـ بداية .. وبيتخزن فيه الراجع من العملية ()FindResourceW.
HRSRC hRsrc = NULL;

hRsrc = FindResourceW(NULL, MAKEINTRESOURCE(IDR_RSRCDATA1), RT_RCDATA);
if (hRsrc == NULL) {
  printf("[!] FindResourceW Failed With Error : %d \n", GetLastError());
  return -1;

}
  • استخدمت ()FindResourceW ، ودي اللـ اتكلمنا عنها فوق .. وعشان تفهم استخدامها صح تقدر تشوف الـ Documentation بتاعها من [هنا].
  • Rsrc-Placement8
  • عشان تجيب الـ ID بتاع الأيقونه .. هتطلع ع Resource.h وتضغط Ctrl + Left-Click .. وهيظهرلك تعريف الأيقونه.
  • Rsrc-Placement9
  • أخر جزئية فـ الكود وهي IF Statement .. لو العملية فشلت بترجع NULL وعرفنا معلومة زي دي بناءا ع الـ Documentation.
  • Rsrc-Placement10
  • تاني جزء فـ الكود وهو إني بجيب حجم الأيقونه .. وهنا عرفت متغير اسمه sPayloadSzize من نوع SIZE_T وحطيت فيه NULL ، ودا بيتخزن فيه الراجع من العملية ()SizeofResource.
SIZE_T sPayloadSzize = NULL;

sPayloadSzize = SizeofResource(NULL, hRsrc);
if (hRsrc == 0) {
  printf("[!] SizeofResource Failed With Error : %d \n", GetLastError());
  return -1;

}
  • وزي اللـ فاتت ، تقدر تشوف الـ Documentation من [هنا] عشان تعرف الـ parameters والـ Return Value.
  • Rsrc-Placement11

وبكدا المفروض تكون فهمت الفكرة ومش محتاج أشرح الجزئين الباقيين لإنهم زي بعض.

  • دا الجزء التالت من الكود .. ومن [هنا] تقدر ترجع للـ Documentation.
HGLOBAL hGlobal = NULL;

hGlobal = LoadResource(NULL, hRsrc);
if (hGlobal == NULL) {
  printf("[!] LoadResource Failed With Error : %d \n", GetLastError());
  return -1;

}
  • الجزء الرابع والـ Documentation من [هنا].
PVOID pPayloadAddress = NULL;

pPayloadAddress = LockResource(hGlobal);
if (pPayloadAddress == NULL) {
  printf("[!] LockResource Failed With Error : %d \n", GetLastError());
  return -1;

}

[+] بكدا يكون الكود خلص .. الكود النهائي:

ضيفت مجرد عملتين طباعة بحيث نشوف عنوان الأيقونه .. وحجم الشيل كود بتاعنا.

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

int main() {
  HRSRC hRsrc = NULL;
  SIZE_T sPayloadSzize = NULL;
  HGLOBAL hGlobal = NULL;
  PVOID pPayloadAddress = NULL;

  hRsrc = FindResourceW(NULL, MAKEINTRESOURCE(IDR_RSRCDATA1), RT_RCDATA);
  if (hRsrc == NULL) {
    printf("[!] FindResourceW Failed With Error : %d \n", GetLastError());
    return -1;

  }

  sPayloadSzize = SizeofResource(NULL, hRsrc);
  if (hRsrc == 0) {
    printf("[!] SizeofResource Failed With Error : %d \n", GetLastError());
    return -1;

  }

  hGlobal = LoadResource(NULL, hRsrc);
  if (hGlobal == NULL) {
    printf("[!] LoadResource Failed With Error : %d \n", GetLastError());
    return -1;

  }

  pPayloadAddress = LockResource(hGlobal);
  if (pPayloadAddress == NULL) {
    printf("[!] LockResource Failed With Error : %d \n", GetLastError());
    return -1;

  }


  printf("[i] pPayloadAddress var : 0x%p \n", pPayloadAddress);
  printf("[i] sPayloadSize var : %ld \n", sPayloadSize);
  getchar();

  return 0;
}
  • يلا نـ Build ، ونشوف ع Total PE .. هنلاقي إن الشيل كود بتاعنا فعلا موجود.
  • Rsrc-Placement12

هنتكلم دلوقتي عن الصلاحيات للأماكن اللـ ذكرناهم فوق:

الصلاحيات السيكشن
Read - Write data
Read rdata
Read - Execute text
Read rsrc

[+] طب هل الصلاحيات دي مهمة ؟ بمعني إني لو حطيت الشيل كود فـ منطقة زي الـ rsrc اللـ هي بصلاحيات قراءة فقط .. ، معني كده إنه مش هيشتغل؟

  • فـ الحقيقة .. دي مش مشكلة أصلا .. يعني لو هتحط الشيل فـ أي مكان فيهم مش هتفرق .. لإن لو فاكر فـ أول مقالة لما استخدمنا الـ ()HeapAlloc عشان نحجز مكان فـ الميموري .. واستخدمنا كمان ()memcpy عشان ننقل الكود بتاعنا للمنطقة المحجوزة فـ الميموري.
  • نقدر بنفس الطريقة ناخد الشيل كود اللـ موجود فـ مكان زي الـ rsrc واللـ بصلاحيات قراءة .. ونحجزلة مكان فـ الميموري وننقله هناك .. وكمان نقدر وقتها نديله صلاحيات زي الـ Execute .. وهنعرف إزاي نعمل ده فـ المقالات الجاية.

[+] طب ليه الهاكرز بيحبوا منطقة الـ rsrc ؟

قولتلك فوق إن هتعرف فـ آخر المقالة ، وجه الوقت أقولك .. بيفضلوا المكان ده لإن :

  • مناطق الـ data والـ rdata ، محدودين من نحية الحجم .. يعني لو الشيل كود بتاعك حجمه كبير فـ صعب يتحط فـ المنطقتين دول.
  • وبالنسبة لمنطقة الـ text ، ودي بتكون متراقبة بشكل كبير من برامج الـ Antivirus ، لإن فيها صلاحيات Execute ، فـ مش أنسب حاجه تحط الشيل كود بتاعك فيها.

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

References

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