Programm im Speicher erzeugen und ausführen



  • mittlerweile habe ich es geschafft, kernel32 funktionen erfolgreich
    umzubiegen. allerdings scheint weder CreateProcess noch LoadLibrary
    auf dateifunktionen wie CreateFile zurückzugreifen. 😞

    wie machen die das? ich versuche grade die ntdll funktionen zu hooken.
    vielleicht klappt das ja.



  • du musst dazu nicht zwingend createprocess umschreiben,es sind nur folgende schritte nötig:

    - .exe einlesen (optional)
    - entsprechend speicher allocieren für dos/ntheader
    - header in allocierten speicher kopieren,sections richtig erstellen
    - STARTUPINFO/PROCESS_INFORMATION/CONTEXT richtig setzen
    - CreateProcess aufrufen

    poc code dazu:

    //--------------------------------------------------------
    // Dynamic Process Forking of Portable Executable
    // Author : Vrillon / Venus
    // Date   : 07/14/2008
    //--------------------------------------------------------
    /*********************************************************/
    /* With this header, you can create and run a process    */
    /* from memory and not from a file.                      */
    /*********************************************************/
    
    #ifdef WIN32
        #include <windows.h>
    #else
        #error Process Forking Requires a Windows Operating System
    #endif
    
    #include <stdio.h>
    
    /////////////////////////////////////////////////////////////
    // NtUnmapViewOfSection (ZwUnmapViewOfSection)
    // Used to unmap a section from a process.
    typedef long int (__stdcall* NtUnmapViewOfSectionF)(HANDLE,PVOID);
    NtUnmapViewOfSectionF NtUnmapViewOfSection = (NtUnmapViewOfSectionF)GetProcAddress(LoadLibrary("ntdll.dll"),"NtUnmapViewOfSection");
    
    /////////////////////////////////////////////////////////////
    // Fork Process
    // Dynamically create a process based on the parameter 'lpImage'. The parameter should have the entire
    // image of a portable executable file from address 0 to the end.
    bool ForkProcess(LPVOID lpImage)
    {
        // Variables for Process Forking
        long int                lWritten;
        long int                lHeaderSize;
        long int                lImageSize;
        long int                lSectionCount;
        long int                lSectionSize;
        long int                lFirstSection;
        long int                lPreviousProtection;
        long int                lJumpSize;
    
        bool                    bReturnValue;
    
        LPVOID                    lpImageMemory;
        LPVOID                    lpImageMemoryDummy;
    
        IMAGE_DOS_HEADER        dsDosHeader;
        IMAGE_NT_HEADERS        ntNtHeader;
        IMAGE_SECTION_HEADER    shSections[512 * 2];
    
        PROCESS_INFORMATION        piProcessInformation;
        STARTUPINFO                suStartUpInformation;
    
        CONTEXT                    cContext;
    
        // Variables for Local Process
        FILE*                    fFile;
        char*                    pProcessName;
    
        long int                lFileSize;
        long int                lLocalImageBase;
        long int                lLocalImageSize;
    
        LPVOID                    lpLocalFile;
    
        IMAGE_DOS_HEADER        dsLocalDosHeader;
        IMAGE_NT_HEADERS        ntLocalNtHeader;
    
        /////////////////////////////////////////////////////////////////
        // End Variable Definition
    
        bReturnValue = false;
    
        pProcessName = new char[MAX_PATH];
        ZeroMemory(pProcessName,MAX_PATH);
    
        // Get the file name for the dummy process
        if(GetModuleFileName(NULL,pProcessName,MAX_PATH) == 0)
        {
            delete [] pProcessName;
            return bReturnValue;
        }
    
        // Open the dummy process in binary mode
        fFile = fopen(pProcessName,"rb");
        if(!fFile)
        {
            delete [] pProcessName;
            return bReturnValue;
        }
    
        fseek(fFile,0,SEEK_END);
    
        // Get file size
        lFileSize = ftell(fFile);
    
        rewind(fFile);
    
        // Allocate memory for dummy file
        lpLocalFile = new LPVOID[lFileSize];
        ZeroMemory(lpLocalFile,lFileSize);
    
        // Read memory of file
        fread(lpLocalFile,lFileSize,1,fFile);
    
        // Close file
        fclose(fFile);
    
        // Grab the DOS Headers
        memcpy(&dsLocalDosHeader,lpLocalFile,sizeof(dsLocalDosHeader));
    
        if(dsLocalDosHeader.e_magic != IMAGE_DOS_SIGNATURE)
        {
            delete [] pProcessName;
            delete [] lpLocalFile;
            return bReturnValue;
        }
    
        // Grab NT Headers
        memcpy(&ntLocalNtHeader,(LPVOID)((long int)lpLocalFile+dsLocalDosHeader.e_lfanew),sizeof(dsLocalDosHeader));
    
        if(ntLocalNtHeader.Signature != IMAGE_NT_SIGNATURE)
        {
            delete [] pProcessName;
            delete [] lpLocalFile;
            return bReturnValue;
        }
    
        // Get Size and Image Base
        lLocalImageBase = ntLocalNtHeader.OptionalHeader.ImageBase;
        lLocalImageSize = ntLocalNtHeader.OptionalHeader.SizeOfImage;
    
        // Deallocate
        delete [] lpLocalFile;
    
        // Grab DOS Header for Forking Process
        memcpy(&dsDosHeader,lpImage,sizeof(dsDosHeader));
    
        if(dsDosHeader.e_magic != IMAGE_DOS_SIGNATURE)
        {
            delete [] pProcessName;
            return bReturnValue;
        }
    
        // Grab NT Header for Forking Process
        memcpy(&ntNtHeader,(LPVOID)((long int)lpImage+dsDosHeader.e_lfanew),sizeof(ntNtHeader));
    
        if(ntNtHeader.Signature != IMAGE_NT_SIGNATURE)
        {
            delete [] pProcessName;
            return bReturnValue;
        }
    
        // Get proper sizes
        lImageSize = ntNtHeader.OptionalHeader.SizeOfImage;
        lHeaderSize = ntNtHeader.OptionalHeader.SizeOfHeaders;
    
        // Allocate memory for image
        lpImageMemory = new LPVOID[lImageSize];
        ZeroMemory(lpImageMemory,lImageSize);
    
        lpImageMemoryDummy = lpImageMemory;
    
        lFirstSection = (long int)(((long int)lpImage+dsDosHeader.e_lfanew) + sizeof(IMAGE_NT_HEADERS));
    
        memcpy(shSections,(LPVOID)(lFirstSection),sizeof(IMAGE_SECTION_HEADER)*ntNtHeader.FileHeader.NumberOfSections);
        memcpy(lpImageMemoryDummy,lpImage,lHeaderSize);
    
        // Get Section Alignment
        if((ntNtHeader.OptionalHeader.SizeOfHeaders % ntNtHeader.OptionalHeader.SectionAlignment) == 0)
        {
            lJumpSize = ntNtHeader.OptionalHeader.SizeOfHeaders;
        }
        else
        {
            lJumpSize  = (ntNtHeader.OptionalHeader.SizeOfHeaders/ntNtHeader.OptionalHeader.SectionAlignment);
            lJumpSize += 1;
            lJumpSize *= (ntNtHeader.OptionalHeader.SectionAlignment);
        }
    
        lpImageMemoryDummy = (LPVOID)((long int)lpImageMemoryDummy + lJumpSize);
    
        // Copy Sections To Buffer
        for(lSectionCount = 0; lSectionCount < ntNtHeader.FileHeader.NumberOfSections; lSectionCount++)
        {
            lJumpSize = 0;
            lSectionSize = shSections[lSectionCount].SizeOfRawData;
    
            memcpy(lpImageMemoryDummy,(LPVOID)((long int)lpImage + shSections[lSectionCount].PointerToRawData),lSectionSize);
    
            if((shSections[lSectionCount].Misc.VirtualSize % ntNtHeader.OptionalHeader.SectionAlignment)==0)
            {
                lJumpSize = shSections[lSectionCount].Misc.VirtualSize;
            }
            else
            {
                lJumpSize  = (shSections[lSectionCount].Misc.VirtualSize/ntNtHeader.OptionalHeader.SectionAlignment);
                lJumpSize += 1;
                lJumpSize *= (ntNtHeader.OptionalHeader.SectionAlignment);
            }
    
            lpImageMemoryDummy = (LPVOID)((long int)lpImageMemoryDummy + lJumpSize);
        }
    
        ZeroMemory(&suStartUpInformation,sizeof(STARTUPINFO));
        ZeroMemory(&piProcessInformation,sizeof(PROCESS_INFORMATION));
        ZeroMemory(&cContext,sizeof(CONTEXT));
    
        suStartUpInformation.cb = sizeof(suStartUpInformation);
    
        // Create Process
        if(CreateProcess(NULL,pProcessName,NULL,NULL,false,CREATE_SUSPENDED,NULL,NULL,&suStartUpInformation,&piProcessInformation))
        {
            cContext.ContextFlags = CONTEXT_FULL;
            GetThreadContext(piProcessInformation.hThread,&cContext);
    
            // Check image base and image size
            if(lLocalImageBase == (long int)ntNtHeader.OptionalHeader.ImageBase && lImageSize <= lLocalImageSize)
            {
                VirtualProtectEx(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSize,PAGE_EXECUTE_READWRITE,(unsigned long*)&lPreviousProtection);
            }
            else
            {
                if(!NtUnmapViewOfSection(piProcessInformation.hProcess,(LPVOID)((DWORD)lLocalImageBase)))
                    VirtualAllocEx(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSize,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
            }
    
            // Write Image to Process
            if(WriteProcessMemory(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lpImageMemory,lImageSize,(unsigned long*)&lWritten))
            {
                bReturnValue = true;
            }
    
            // Set Image Base
            if(WriteProcessMemory(piProcessInformation.hProcess,(LPVOID)((long int)cContext.Ebx + 8),&ntNtHeader.OptionalHeader.ImageBase,4,(unsigned long*)&lWritten))
            {
                if(bReturnValue == true)
                    bReturnValue = true;
            }
    
            if(bReturnValue == false)
            {
                delete [] pProcessName;
                delete [] lpImageMemory;
                return bReturnValue;
            }
    
            // Set the new entry point
            cContext.Eax = ntNtHeader.OptionalHeader.ImageBase + ntNtHeader.OptionalHeader.AddressOfEntryPoint;
    
            SetThreadContext(piProcessInformation.hThread,&cContext);
    
            if(lLocalImageBase == (long int)ntNtHeader.OptionalHeader.ImageBase && lImageSize <= lLocalImageSize)
                VirtualProtectEx(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSize,lPreviousProtection,0);
    
            // Resume the process
            ResumeThread(piProcessInformation.hThread);
        }
    
        delete [] pProcessName;
        delete [] lpImageMemory;
    
        return bReturnValue;    
    }
    
    /////////////////////////////////////////////////////////////
    // Fork Process From Resource
    // Dynamically create a process from a resource file.
    bool ForkProcessFromResource(int iResource,char* pResourceSection)
    {
        HGLOBAL        hResData;
        HRSRC        hResInfo;
    
        LPVOID        lpRes;
        LPVOID        lpMemory;
        long int    lSize;
    
        HMODULE        hModule;
    
        bool bReturn;
    
        hModule = GetModuleHandle(0);
        bReturn = false;
    
        if(!hModule)
            return bReturn;
    
        hResInfo = FindResource(hModule, MAKEINTRESOURCE(iResource), pResourceSection);
        if(!hResInfo)
        {
            return bReturn;
        }
    
        hResData = LoadResource(hModule, hResInfo);
        if(!hResData)
        {
            return bReturn;
        }
    
        lpRes = LockResource(hResData);
        if(!lpRes)
        {
            FreeResource(hResData);
            return bReturn;
        }
    
        lSize = SizeofResource(hModule, hResInfo);
    
        lpMemory = new LPVOID[lSize];
        ZeroMemory(lpMemory,lSize);
    
        memcpy (lpMemory, lpRes, lSize);
    
        bReturn = ForkProcess(lpMemory);
    
        FreeResource(hResData);
        delete [] lpMemory;
    
        return bReturn;
    }
    


  • puh ganz schön viel code. warum greift der den nicht auf die datei zu?
    schließlich übergibst du ihm ja einen (eigenen) dateipfad?



  • helferlein schrieb:

    warum greift der den nicht auf die datei zu? schließlich übergibst du ihm ja einen (eigenen) dateipfad?

    Grob gesagt erzeugt das Snippet "irgendeinen" Prozess und brezelt dann seine "RAM-EXE" rein.



  • wird bei diesem "irgenteinem" prozess nicht aber auf die platte zurückgegriffen?



  • Ja, wird auch. Ist gewissermaßen "Hijacking". Insofern ist es nicht grade im Sinne des OT.



  • wo wird da eine exe von der HD geladen ?
    oder hab ich da was nicht gesehen?



  • zweiter parameter von CreateProcess....



  • heutemalwasanderes schrieb:

    wo wird da eine exe von der HD geladen ?

    Er lädt sich selbst als "dummy process" ("irgendeiner" geht auch):

    if(GetModuleFileName(NULL,pProcessName,MAX_PATH) == 0) ...
    
    (...)
    
    // Zugriff! -> verloren,verloren,hihihi :)
    if(CreateProcess(NULL,pProcessName,NULL,NULL,false,CREATE_SUSPENDED, ...
    


  • Da findet man wie man.bis win 10 rams in echtzeit lesen kann


Anmelden zum Antworten