Инъекция DLL с CreateRemoteThread
если вы посмотрите на следующий рабочий код простой инъекции DLL:
//Open the target process with read , write and execute priviledges
Process = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_VM_OPERATION, FALSE, ID);
//Get the address of LoadLibraryA
LoadLibrary = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
// Allocate space in the process for our DLL
Memory = (LPVOID)VirtualAllocEx(Process, NULL, strlen(dll)+1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
// Write the string name of our DLL in the memory allocated
WriteProcessMemory(Process, (LPVOID)Memory, dll, strlen(dll)+1, NULL);
// Load our DLL
CreateRemoteThread(Process, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibrary, (LPVOID)Memory, NULL, NULL);
//Let the program regain control of itself
CloseHandle(Process);
меня смущает то, что GetProcAddress
возвращает LoadLibraryA
fucntion адрес текущий процесс, как вы можете передать его в качестве параметра CreateRemoteThread
и ожидать целевого процесса, чтобы запустить его?
4 ответов
Он работает случайно. Это очень общая авария, Microsoft делает много усилий, чтобы гарантировать, что DLL операционной системы, как kernel32.dll, имеют базовый адрес,который не конфликтует с любыми другими DLL. Более добавочно увеличено kernel32.dll загружается очень рано при инициализации процесса настолько низкие шансы, что он должен бороться, чтобы получить свой предпочтительный базовый адрес.
вам легко сойдет с рук. Примечательно, что это и пошло не так в прошлом было обновление безопасности XP, которое вызвало gdi32.dll, чтобы переместиться и сделать много машин падают при загрузке. Правильный способ довольно болезненный, CreateToolhelp32Snapshot () + Module32First/Next (), чтобы найти смещение перемещения не большая радость. Честно говоря, вы, вероятно, не должны делать этого вообще, если операционная система "странная".
LoadLibraryA
проживает в kernel32.dll
модуль, который всегда загружается в каждый процесс, а также быть загружены по одному адресу в каждом процессе.
рандомизация макета адресного пространства (ASLR)-это функция предотвращения эксплойтов, обрабатываемая Windows, и она позволяет перемещать адреса, чтобы предотвратить злоумышленников от определения адреса для использования чего-либо в памяти (останавливает жесткое кодирование адресов/смещений). Однако модули Windows меняют адреса только за сеанс.
Если у вас есть процесс, который использует kernel32.dll (не все процессы используют kernel32.dll, и я объясню это дальше через несколько минут), адрес подпрограммы может быть 55AA1122 в качестве примера (это недопустимый пример адреса). Теперь следующий процесс с kernel32.dll, будет иметь тот же адрес для 55AA1122 для той же процедуры, что и предыдущий.... Только если оба процесса имеют одинаковую архитектуру.
32-разрядные процессы будут иметь одинаковые адреса для kernel32.dll экспорт, среди других модулей Windows экспорт тоже (например, NTDLL, USER32 и т.д.). 64-разрядные процессы будут иметь разные адреса для 32-разрядных процессов, однако 64-разрядные процессы также будут иметь одинаковые адреса для модулей Windows!
создание удаленного потока не было "несчастным случаем", Microsoft намеренно реализовала его. Почему? Microsoft часто использует его во время самих Windows, а также для асинхронных вызовов процедур. Microsoft также исправляет вещи часто для своих собственных процедур как анти-реверсивный трюк, или если они теряют исходный код для своих собственных проектов, ха-ха.
Теперь относительно kernel32.библиотека DLL загружается в процесс он загружается только в процессы, которые используют Win32 API. Это включает в себя 99% программ в мире, однако можно скомпилировать собственный процесс, который не будет его использовать. Однако это заставит вас полностью использовать собственный API и API Win32, а также процесс Windows под названием smss.ехе делает именно это. Вы также можете скомпилировать собственные библиотеки DLL, которые даже не имеют обычной процедуры записи DLL Win32 API.
короче говоря, адреса для подпрограмм модуля Windows изменение один раз за загрузку. Он будет поддерживать то же самое до следующей перезагрузки, и так далее. 32-разрядные процессы имеют свои общие адреса модулей Windows для каждого процесса, как и 64-разрядные процессы. Таким образом нельзя использовать LoadLibraryA адрес 64-разрядного процесса при ориентации DLL инъекции для 32-разрядного процесса, если вы не используете 32-разрядный Kernel32.dll LoadLibraryA адрес. Лучшей идеей было бы использовать LdrLoadDll в любом случае или просто инъекцию кода оболочки отражающего DLL-загрузчика.
при запуске Visual Studio создайте пустой проект, добавьте новый main.cpp файл, записываю:
#include <windows.h>
void main()
{
}
а затем скомпилируйте эту программу, не ожидайте, что созданный исполняемый файл ничего не делает, это не так.
возможно, компилятор Visual C++ не записал ни одной команды в объектном файле, потому что в исходном коде нет команды, но компоновщик записал в начале основной процедуры исполняемого файла LoadLibrary
звонки user32.dll
, kernel32.dll
, gdi32.dll
и т. д.
поэтому каждое приложение, написанное в Visual Studio C++, изначально делает много одинаковых вызовов LoadLibrary
на того же, независимо от того, каким был исходный код этого исполняемого файла.
исходный код определяет только команды, которые должны прийти после LoadLibrary
звонки.
таким образом, каждое приложение Visual Studio C++ загружает LoadLibrary
of kernel32.dll
в начале исполнения и так LoadLibrary
есть же запись точка или адрес во всех процессах относительно адреса процесса.
теоретически вы можете сделать инжектор, вредоносная программа, которая пытается ввести вашу программу, потерпеть неудачу, если вы свяжете некоторые kernel32.lib, который не загружает kernel32.
инжектор не может заставить вашу программу динамически во время выполнения загружать некоторую dll, если ваша программа не может динамически во время выполнения загрузить dll, потому что процедура что предполагает сделать это,LoadLibrary
, не присутствует в памяти процесса.
поэтому удаленный поток созданный инжектором не может выполнить LoadLibrary
этого нет в памяти жертвы.
но это возможно, что злоумышленник будет VirtualAllocEx создать некоторый блок в памяти жертвы, WriteProcessMemory некоторый исполняемый код, а затем CreateRemoteThread для его выполнения.