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

wininet при инъекции процесса

0x60b1iN

RAM
Пользователь
Регистрация
04.12.2020
Сообщения
114
Реакции
21
Доброго времени суток,

Подскажите пожалуйста необразованному. Используется wininet для самых обыкновенных запросов, при инъекции процесса при первом вызове функции из либы вининета аварийное завершение. При работе в основном процессе без проблем выполняется код. Скорее всего причина в выделении памяти, которое происходит внутри функции. Подозреваю, что если кто-то ответит, то скажет дебажить процесс в который происходит инъекция :) Но все же, я хотел бы знать ваше мнение, стоит вообще использовать вининет при подобных задачах, или писать кастомный модуль для работы через хттп. И можно вообще юзать вининет в инжектированном процессе? Благодарю за внимание.
1609013586752.png
 
Пожалуйста, обратите внимание, что пользователь заблокирован
А что за эксепшн? Очень странная конструкция с разименованием указателя, зачем она здесь вообще не понятно, вероятно происходит разименование нулевого указателя.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Или только через LoadLibrary явно подгружать?
Смотря, как инжектишь.
 
А что за эксепшн? Очень странная конструкция с разименованием указателя, зачем она здесь вообще не понятно, вероятно происходит разименование нулевого указателя.
Смотри, я не могу получить эксепшн, так как код выполняется в другом процессе, в который инъекция происходит, может и могу, но я профан, не знаю как :) Просто процесс в который инжектируется PE завершается. Однозначно не нулевой указатель, так как при инициализации класса аллокация судя по всему проходит успешно. Код рабочий, хоть и не красивый, работает как положено если стартовать в без инъекции в отдельном процессе.
1609015173341.png
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Как именно происходит инжект и что инжектится (шеллкод, етц)?
Какая ОС?

Из скрина ничего неясно, кроме того , что автор юзает божественный ООП.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Просто процесс в который инжектируется PE завершается.
То есть ты просто ткнул пальцем в небо, когда выкладывал этот фрагмент кода?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Из скрина ничего неясно, кроме того , что автор юзает божественный ООП.
На куче выделять 4-8 байт для хендла HINTERNET - это пиздос.
 
Как именно происходит инжект и что инжектится (шеллкод, етц)?
Какая ОС?

Из скрина ничего неясно, кроме того , что автор юзает божественный ООП.
OS - Windows 10 x64

Инъекция текущего модуля. Код ниже
C++:
#include "Injector.h"
Injector::Injector(){
  
}
Injector::~Injector(){
  
}
void Injector::Inject(LPVOID funk, DWORD pId){
    HANDLE hProc = NULL;
    hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);
    if (!hProc) {
        std::cout << "[-] Could not open target process\n";
        exit(EXIT_FAILURE);
    }
    std::cout << "[+] Opened process " << pId << std::endl;
    PVOID ImageBase = GetModuleHandle(NULL);
    if (!ImageBase) {
        std::cout << "[-] Could not get image base\n";
        exit(EXIT_FAILURE);
    }
    std::cout << "[+] Got image base\n";
    PIMAGE_DOS_HEADER dosHeader = NULL;
    dosHeader = (PIMAGE_DOS_HEADER)ImageBase;
    if (!dosHeader) {
        std::cout << "[-] Could not get dos header\n";
        exit(EXIT_FAILURE);
    }
    std::cout << "[+] Got DOS header\n";
    PIMAGE_NT_HEADERS ntHeader = NULL;
    ntHeader = (PIMAGE_NT_HEADERS)((PUCHAR)ImageBase + dosHeader->e_lfanew);
    if (!ntHeader) {
        std::cout << "[-] Could not get image NT headers\n";
        exit(EXIT_FAILURE);
    }
    std::cout << "[+] Got NT headers\n";
    PVOID64 allocMem = NULL;
    allocMem = VirtualAllocEx(hProc, NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (!allocMem) {
        std::cout << "[-] Could not get image NT headers\n";
        exit(EXIT_FAILURE);
    }
    std::cout << "[+] Allocated memory in target process\n";
    PVOID64 buffer = NULL;
    buffer = VirtualAlloc(NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (!buffer) {
        std::cout << "[-] Could not allocate memory for buffer\n";
        exit(EXIT_FAILURE);
    }
    std::cout << "[+] Allocated memory for buffer\n";
    memcpy(buffer, ImageBase, ntHeader->OptionalHeader.SizeOfImage);
    std::cout << "[+] Copied image to buffer\n";
    PIMAGE_BASE_RELOCATION baseRelocation = NULL;
    baseRelocation = (PIMAGE_BASE_RELOCATION)((PUCHAR)buffer + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
    if (!baseRelocation) {
        std::cout << "[-] Could not get image base relocation\n";
        exit(EXIT_FAILURE);
    }
    std::cout << "[+] Got image base relocation\n";

    ULONG64 Delta = NULL;
    Delta = (ULONG64)allocMem - (ULONG64)ImageBase;
    if (!Delta) {
        std::cout << "[-] Could not calculate allocated image size\n";
        exit(EXIT_FAILURE);
    }
    ULONG64 Count = 0, i = 0, *p = NULL;
    PUSHORT Offset = NULL;
    while (baseRelocation->VirtualAddress) {
        if (baseRelocation->SizeOfBlock == sizeof(IMAGE_BASE_RELOCATION)) {
            Count = (baseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION) / sizeof(USHORT));
            Offset = (PUSHORT)baseRelocation + 1;
            for (i = 0; i < Count; i++) {
                if (Offset) {
                    p = (PULONG64)((PUCHAR)buffer + baseRelocation->VirtualAddress + (Offset & 0x0FFF));
                    *p += Delta;
                }
            }
        }
        baseRelocation = (PIMAGE_BASE_RELOCATION)((PUCHAR)baseRelocation + baseRelocation->SizeOfBlock);
    }
    BOOL bWrite = false;
    bWrite = WriteProcessMemory(hProc, allocMem, buffer, ntHeader->OptionalHeader.SizeOfImage, NULL);
    if (!bWrite) {
        std::cout << "[-] Failed to write ProcMem\n";
        VirtualFreeEx(hProc, allocMem, 0, MEM_RELEASE);
        CloseHandle(hProc);
        exit(EXIT_FAILURE);
    }
    std::cout << "[+] Written ProcMem\n";
    VirtualFree(buffer, 0, MEM_RELEASE);
    std::cout << "[+] Cleared buffer\n";
    HANDLE hThread = NULL;
    hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)((PUCHAR)funk + Delta), NULL, 0, NULL);
    if (!hThread) {
        std::cout << "[-] Failed to create thread\n";
        VirtualFreeEx(hProc, allocMem, 0, MEM_RELEASE);
        CloseHandle(hProc);
        exit(EXIT_FAILURE);
    }
    GetLastError();
    std::cout << "[+] Created thread in target proc\n";
    std::cout << "[*] Waiting for thread to terminate...\n";
    WaitForSingleObject(hThread, INFINITE);
    std::cout << "[*] Thread either terminated or force continued\n";
    VirtualFreeEx(hProc, allocMem, 0, MEM_RELEASE);
    std::cout << "[+] Cleaned allocated memory\n[*] Cleaning up...\n";
    delete ImageBase;
    delete dosHeader;
    delete ntHeader;
    delete allocMem;
    delete buffer;
    delete baseRelocation;
    delete Offset;
    CloseHandle(hProc);
    CloseHandle(hThread);
    //return 0;
}
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
Инъекция текущего модуля
Я слепожарый, или тут нет настройки таблицы импорта?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
VirtualFreeEx(hProc, allocMem, 0, MEM_RELEASE);
Что тут allocMem? Ты особождаешь память, которую ты выделил под инжектируемый образ в целевом процессе?

А, не важно, из-за того, что ты не удосужился запостить код нормально, он нихера нормально не читается.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Скорее всего у целевого приложения в импорте нету wininet.dll. Нужно явно загружать

Если заметишь технику у крипторов, то они обрабатывают релоки, таблицу иморта etc.

А так, в теории возможно, чтоб инжекнутый код работал с wininet
 
Пожалуйста, обратите внимание, что пользователь заблокирован
OS - Windows 10 x64

Инъекция текущего модуля. Код ниже
#include "Injector.h"
Injector::Injector(){

}
Injector::~Injector(){

}
void Injector::Inject(LPVOID funk, DWORD pId){
HANDLE hProc = NULL;
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);
if (!hProc) {
std::cout << "[-] Could not open target process\n";
exit(EXIT_FAILURE);
}
std::cout << "[+] Opened process " << pId << std::endl;
PVOID ImageBase = GetModuleHandle(NULL);
if (!ImageBase) {
std::cout << "[-] Could not get image base\n";
exit(EXIT_FAILURE);
}
std::cout << "[+] Got image base\n";
PIMAGE_DOS_HEADER dosHeader = NULL;
dosHeader = (PIMAGE_DOS_HEADER)ImageBase;
if (!dosHeader) {
std::cout << "[-] Could not get dos header\n";
exit(EXIT_FAILURE);
}
std::cout << "[+] Got DOS header\n";
PIMAGE_NT_HEADERS ntHeader = NULL;
ntHeader = (PIMAGE_NT_HEADERS)((PUCHAR)ImageBase + dosHeader->e_lfanew);
if (!ntHeader) {
std::cout << "[-] Could not get image NT headers\n";
exit(EXIT_FAILURE);
}
std::cout << "[+] Got NT headers\n";
PVOID64 allocMem = NULL;
allocMem = VirtualAllocEx(hProc, NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!allocMem) {
std::cout << "[-] Could not get image NT headers\n";
exit(EXIT_FAILURE);
}
std::cout << "[+] Allocated memory in target process\n";
PVOID64 buffer = NULL;
buffer = VirtualAlloc(NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!buffer) {
std::cout << "[-] Could not allocate memory for buffer\n";
exit(EXIT_FAILURE);
}
std::cout << "[+] Allocated memory for buffer\n";
memcpy(buffer, ImageBase, ntHeader->OptionalHeader.SizeOfImage);
std::cout << "[+] Copied image to buffer\n";
PIMAGE_BASE_RELOCATION baseRelocation = NULL;
baseRelocation = (PIMAGE_BASE_RELOCATION)((PUCHAR)buffer + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
if (!baseRelocation) {
std::cout << "[-] Could not get image base relocation\n";
exit(EXIT_FAILURE);
}
std::cout << "[+] Got image base relocation\n";

ULONG64 Delta = NULL;
Delta = (ULONG64)allocMem - (ULONG64)ImageBase;
if (!Delta) {
std::cout << "[-] Could not calculate allocated image size\n";
exit(EXIT_FAILURE);
}
ULONG64 Count = 0, i = 0, *p = NULL;
PUSHORT Offset = NULL;
while (baseRelocation->VirtualAddress) {
if (baseRelocation->SizeOfBlock == sizeof(IMAGE_BASE_RELOCATION)) {
Count = (baseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION) / sizeof(USHORT));
Offset = (PUSHORT)baseRelocation + 1;
for (i = 0; i < Count; i++) {
if (Offset) {
p = (PULONG64)((PUCHAR)buffer + baseRelocation->VirtualAddress + (Offset & 0x0FFF));
*p += Delta;
}
}
}
baseRelocation = (PIMAGE_BASE_RELOCATION)((PUCHAR)baseRelocation + baseRelocation->SizeOfBlock);
}
BOOL bWrite = false;
bWrite = WriteProcessMemory(hProc, allocMem, buffer, ntHeader->OptionalHeader.SizeOfImage, NULL);
if (!bWrite) {
std::cout << "[-] Failed to write ProcMem\n";
VirtualFreeEx(hProc, allocMem, 0, MEM_RELEASE);
CloseHandle(hProc);
exit(EXIT_FAILURE);
}
std::cout << "[+] Written ProcMem\n";
VirtualFree(buffer, 0, MEM_RELEASE);
std::cout << "[+] Cleared buffer\n";
HANDLE hThread = NULL;
hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)((PUCHAR)funk + Delta), NULL, 0, NULL);
if (!hThread) {
std::cout << "[-] Failed to create thread\n";
VirtualFreeEx(hProc, allocMem, 0, MEM_RELEASE);
CloseHandle(hProc);
exit(EXIT_FAILURE);
}
GetLastError();
std::cout << "[+] Created thread in target proc\n";
std::cout << "[*] Waiting for thread to terminate...\n";
WaitForSingleObject(hThread, INFINITE);
std::cout << "[*] Thread either terminated or force continued\n";
VirtualFreeEx(hProc, allocMem, 0, MEM_RELEASE);
std::cout << "[+] Cleaned allocated memory\n[*] Cleaning up...\n";
delete ImageBase;
delete dosHeader;
delete ntHeader;
delete allocMem;
delete buffer;
delete baseRelocation;
delete Offset;
CloseHandle(hProc);
CloseHandle(hThread);
//return 0;
}
прошу, пожалуйста, умоляю... Вставляйте код в тэг. Кровь из глаз
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Скорее всего у целевого приложения в импорте нету wininet.dll. Нужно явно загружать
Из-за ASLR любая DLL может быть загружена по другому адресу, нежели в текущем процессе (ну кроме ntdll и kernel32 и еще некоторых библиотек). Ну или ее может и не быть в целевом процессе вообще, да.

Будет забавно еще, если выяснится, что он инжектит из 64-битного процесса в 32-битный, или наоборот.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Скорее всего да, в импорте нет вининет, и вызов функции вызывает ошибку, т.к. идет обращение хз куда.
Попробуйте получать апи динамически (loadlib + getproc)
 
Из-за ASLR любая DLL может быть загружена по другому адресу, нежели в текущем процессе (ну кроме ntdll и kernel32 и еще некоторых библиотек). Ну или ее может и не быть в целевом процессе вообще, да.

Будет забавно еще, если выяснится, что он инжектит из 64-битного процесса в 32-битный, или наоборот.
та не 64 в 64 ? Я понял причину
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Спасибо за помощь
Так получилось исправить?

Вообще, если пишешь в студии: запусти проект в режиме отладки, и пошагово трейси (ф11-10) до вызова этих самых вининет функций. Дальше переключись на вкладку Disasm и там также по ф11 перейди туда, куда идет вызов функции (call чето-там). Так проще искать ошибки, так как будет видно, куда указывает функция - на уровне асма это call, т.е. jmp, т.е. грубо говоря goto какой-то адрес, который должен быть заполнен загрузчиком при запуске процесса. И обычно при инжектах юзают шк, динамически получая апи.
 
Так получилось исправить?

Вообще, если пишешь в студии: запусти проект в режиме отладки, и пошагово трейси (ф11-10) до вызова этих самых вининет функций. Дальше переключись на вкладку Disasm и там также по ф11 перейди туда, куда идет вызов функции (call чето-там). Так проще искать ошибки, так как будет видно, куда указывает функция - на уровне асма это call, т.е. jmp, т.е. грубо говоря goto какой-то адрес, который должен быть заполнен загрузчиком при запуске процесса. И обычно при инжектах юзают шк, динамически получая апи.
Юзаю VS Code. Еще нет, не исправил, но уже знаю с чем нужно работать, попробую явно загружать. А как пошагово трейсить если процесс уже заинжектился? Я же могу отлаживать только процесс до инъекции. Вининет вызовы происходят после запуска удаленного потока.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Я же могу отлаживать только процесс до инъекции
Поставить в коде int3 (_debugbreak()) перед вызовом, аттачиться отладчиком и смотреть.
 


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