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

C | Как получить адрес WinApi функции

Naraku

floppy-диск
Пользователь
Регистрация
21.09.2019
Сообщения
9
Реакции
5
Пытаюсь записать код в память и динамически его выполнить. Сам shell: \x55\x89\xE5\xB8\x20\x00\x00\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x00\xE8\xFC\xFF\xFF\xFF\x89\xEC\x5D\xC3

Код:
push ebp
mov ebp, esp
mov eax, 0x20
push 0x0
push 0x00000000
push 0x00000000
push 0x0
call 0x00000000
mov esp, ebp
pop ebp
ret

Четыре байта с 23й позиции нужно заменить на адрес функции MessageBoxA. Пытаюсь сделать следующим образом:
C:
#include <stdio.h>
#include <Windows.h>

typedef int(__stdcall *myfunc)(void);

int main()
{
    printf("Push <enter> for run shell code\n");
    system("pause");
    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, 0x75, 0xAA, 0x27, 0x30, 0x89, 0xEC, 0x5D, 0xC3 }; //17 18 19 20
    //byte shell[] = { 0x55, 0x89, 0xE5, 0xB8, 0x20, 0x00, 0x00, 0x00, 0x89, 0xEC, 0x5D, 0xC3 };
    char* text = new char[10] { "Test ebat" };
    char* title = new char[6] { "title" };

    LPVOID lpBaseShell = malloc(sizeof(shell));
    if (lpBaseShell)
    {
        memcpy(shell + 11, &title, 4);
        memcpy(shell + 16, &text, 4);

        DWORD dwOldProtect;
        VirtualProtectEx(GetCurrentProcess(), lpBaseShell, sizeof(shell), PAGE_EXECUTE_READWRITE, &dwOldProtect);

        HMODULE hUserDLL = LoadLibrary(L"User32.dll");
        if (hUserDLL)
        {
            LPVOID lpMsgBox = (LPVOID)GetProcAddress(hUserDLL, "MessageBoxA");
            memcpy(shell + 23, lpMsgBox, 4);

            SIZE_T writtenBytes;
            WriteProcessMemory(GetCurrentProcess(), lpBaseShell, shell, sizeof(shell), &writtenBytes);
           
            myfunc mf = (myfunc)lpBaseShell;
            int rez = mf();
        }

        free(lpBaseShell);
    }

    system("pause");
    return 0;
}
Но при таком подходе выкидывает "нарушение прав доступа при исполнении по адресу ". Что, собственно, делаю не так?

UPD: Заголовок не совсем корректно сделал
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Такая проблемка бывает прикомпилиция для x64, на x86 компилиться нормально. Ставишь точку останова на нужной функции, и смотришь на выброс исключений.
 
Такая проблемка бывает прикомпилиция для x64, на x86 компилиться нормально. Ставишь точку останова на нужной функции, и смотришь на выброс исключений.
Компилирую под x86. В коде есть закоментированный шелл, который представляет из себя функцию, возвращаемую число 32. Если ее записать таким же методом, то она отработает прекрасно, однако с вызовом MessageBox возникают проблемы. Исключение выбрасывается при вызове функции MessageBoxA, потому и думал поначалу, что адрес получаю неправильный. Хотя сейчас проверил в отладчике и адрес действительно записывается какой-то левый.

А зачем тебе этот мазохизм? Разве сложно распарсить экспорт либ из под шеллкода?
Дай пример или направление куда копать. Пока не совсем тебя понимаю.
 
Компилирую под x86. В коде есть закоментированный шелл, который представляет из себя функцию, возвращаемую число 32. Если ее записать таким же методом, то она отработает прекрасно, однако с вызовом MessageBox возникают проблемы. Исключение выбрасывается при вызове функции MessageBoxA, потому и думал поначалу, что адрес получаю неправильный. Хотя сейчас проверил в отладчике и адрес действительно записывается какой-то левый.


Дай пример или направление куда копать. Пока не совсем тебя понимаю.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Адрес действительно записывается какой-то левый, немного посмотрел в отладчике и забил. Вообще, надо копать вот в такую сторону:
1. получать апи динамически в самом шеллкоде, а не брать их откуда-то со стороны.
2. не делать лишних действий, можно сразу выделить VirtualAlloc (PAGE_EXECUTE_READWRITE) , скопировать туда ШК и там его модифицировать. Это же учебный пример. Еще можно поставить кодеблокс, в нем можно написать что-то вида:

C++:
#include <stdio.h>
#include <windows.h>

unsigned char sxmul[] = "\x55\x89\xe5\x8b\x45\x08\x0f\xaf\x45\x0c\x5d\xc3";
int main()
{
int (*pfunc)();//int mul (int a, int b)
pfunc = (int (*)())sxmul;
printf("%d\n",pfunc(3,9));

return 0;
}

Т.е. без заморочек с памятью, напрямую вызывать ШК (в реальной малвари такой фокус не пройдет, но пока учишься, нужно концентрироваться на самом ШК, а не на памяти).
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Код не может работать, он неправильный. Дворд должен хранится перевернутым (bswap) и call кодируется не просто "call адрес", а вычисляется относительное смещение. Можно юзать опкод ff15 вместо е8 или не е*ть мозги и делать нормально, получать в самом шеллкоде адреса.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Меняешь ШК на такой
C++:
byte shell[32] = { 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,*/0xFF,0x15, 0x75, 0xAA, 0x27, 0x30, 0x89, 0xEC, 0x5D, 0xC3 }; //17 18 19 20
Потому что call действительно нужно высчитывать, кодировать destination - source - 5, подробнее см. маны интела.

Потом в коде пишешь

Код:
  LPVOID lpMsgBox = (LPVOID)GetProcAddress(hUserDLL, "MessageBoxA");
            LPVOID lplpMbox = &lpMsgBox;
            memcpy(shell + 24, &lplpMbox, 4);

И все работает.
Но еще раз повторюсь, так кодить не надо.
 


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