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

  • Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

Динамический запуск кода

Naraku

New member
13.10.2019
1
0
BIT
0
Вопрос встает следующий: как записать в память своего потока код и вызвать из него функцию?
Предположим имеется следующий код:
Код:
push ebp
mov ebp, esp
mov eax, 0x20
mov esp, ebp
pop ebp
ret
Генерируем из него шелл: \x55\x89\xE5\xB8\x20\x00\x00\x00\x89\xEC\x5D\xC3

Далее из программы вызываю следующим образом:

C:
#include <stdio.h>
#include <Windows.h>

int main()
{
    byte shell[13] = { 0x55, 0x89, 0xE5, 0xB8, 0x20, 0x00, 0x00, 0x00, 0x89, 0xEC, 0x5D, 0xC3 };
    void* ptr = malloc(sizeof(shell));
    int (*func)() = (int (*)())ptr;
    SIZE_T writtenBytes;
    if (ptr != NULL)
    {
        DWORD oldProtect;
        VirtualProtectEx(GetCurrentProcess(), ptr, sizeof(shell), PAGE_EXECUTE_READWRITE, &oldProtect);
        WriteProcessMemory(GetCurrentProcess(), ptr, shell, sizeof(shell), &writtenBytes);
        int rez = func();
        printf("Rezult: %d\n", rez);
    }

    system("pause");
    return 0;
}

С данным типом понятно, все работает прекрасно. Но что, если в функции есть обращение к чему-то извне. К примеру, если функция в своем теле вызывает MessageBox. Как действовать тогда?
Попытал счастье сделав так:
C:
#include <stdio.h>
#include <Windows.h>

int main()
{
    byte shell[31] = { 0x55, 0x89, 0xE5, 0xB8, 0x20, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x68, 0x00, 0x00, 0x00, //12 13 14 15
        0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x00, 0xE8, 0xD4, 0x0A, 0x99, 0x00, 0x89, 0xEC, 0x5D, 0xC3 }; //17 18 19 20
    char* text = new char[10] { "Test ebat" };
    char* title = new char[6] { "title" };
    void* ptr = malloc(sizeof(shell));
    int (*func)() = (int (*)())ptr;
    SIZE_T writtenBytes;
    if (ptr != NULL)
    {
        memcpy(shell + 16, &text, 4);
        memcpy(shell + 11, &title, 4);
        
        HMODULE hUsr = LoadLibrary(L"User32.dll");
        if (krnl)
        {
            LPVOID msgbox = (LPVOID)GetProcAddress(hUsr, "MessageBoxA");
            memcpy(shell + 23, &msgbox, 4);

            memcpy(ptr, shell, sizeof(shell));
            DWORD oldProtect;
            VirtualProtectEx(GetCurrentProcess(), ptr, sizeof(shell), PAGE_EXECUTE_READWRITE, &oldProtect);
            //WriteProcessMemory(GetCurrentProcess(), ptr, shell, sizeof(shell), &writtenBytes);
            int rez = func();
            printf("Rezult: %d\n", rez);
        }
    }

    system("pause");
    return 0;
}

Код:
push ebp
mov ebp, esp
mov eax, 0x20
push 0x0
push 0x00000000 ; of caption
push 0x00000000 ; of title
push 0x0
call 0x00000000 ; address of func MessageBoxA
mov esp, ebp
pop ebp
ret
Но такое не прокатывает, видимо адрес MessageBoxA в нормальном виде так и не был получен. И ладно здесь я правлю байты, вставляя в них адреса, но что, если код будет объемный. Везде менять адреса вряд ли получится, тем более разных функций.

Буду благодарен если приведете пример и подскажите куда копать, дабы разобраться с этим.
 
Мы в соцсетях:

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