Текущий архив: 2006.04.09;
Скачать: CL | DM;
ВнизКонтроль компонентов Найти похожие ветки
← →
not_dev (2006-01-20 12:39) [0]Доброе время суток, Мастера.
Интересует организация контроля компонентов а-ля Outpost. Не мог ли бы вы растолковать каким образом он это осуществляет? Перехват чего обычно используется, каким образом отследить изменение памяти чужой программы со стороны агрессора? Я понимаю что вопросов много, но хотя бы наведить на мысль, подтолкните )
--
С уважением, not_dev
← →
Rouse_ © (2006-01-20 13:58) [1]Ничего не понял. Какие такие компоненты контролирует Outpost?
← →
not_dev (2006-01-20 14:16) [2]ммм... контроль компонентов сторонних приложений во избежание injectирования и т.д., в аутпосте сделано чтобы модули, находящиеся в контексте ie, к примеру, не могли навредить машине.
← →
Игорь Шевченко © (2006-01-20 15:18) [3]Rouse_ © (20.01.06 13:58) [1]
Поставь outpost, узнаешь, какие компоненты :)
← →
Игорь Шевченко © (2006-01-20 15:19) [4]
> Перехват чего обычно используется, каким образом отследить
> изменение памяти чужой программы со стороны агрессора?
Обычно используется перехват WriteProcessMemory и CreateRemoteThread, тем более, что Outpost устанваливает свои драйверы ядра, в этом случае задача централизованного перехвата несколько упрощается.
← →
not_dev (2006-01-20 15:38) [5]можно ли не выходя в ring0 осуществлять более менее нормальный перехват подобных изменений?
по поводу WriteProcessMemory и CreateRemoteThread спасибо. что обычно еще используют агрессоры?
в кратце опиуш проблему. есть клиен-серверное ПО, цель агрессора увеличить возможности и функционал клиента. внедрение происходит по нескольким направлением, непосредственное изменение поведения клиента, вмешательство в передачу данных на сервер и т.д.
← →
Игорь Шевченко © (2006-01-20 15:59) [6]not_dev (20.01.06 15:38) [5]
> что обычно еще используют агрессоры?
Не могу сказать, сам не агрессор.
> есть клиен-серверное ПО, цель агрессора увеличить возможности
> и функционал клиента. внедрение происходит по нескольким
> направлением, непосредственное изменение поведения клиента,
> вмешательство в передачу данных на сервер и т.д.
Проверка контрольных сумм не спасет ?
← →
not_dev (2006-01-20 17:30) [7]все что могу и так контролирую на целостность (MD5).
проблема в том что изменения производятся в памяти клиента. а так же за счет перекрытия некоторых WinAPI функций.
к примеру, ряд агрессоров перекрывает QueryPerformanceCounter, изменяя в n-раз результат. что-то приблизительно в таком духе:library speed;
uses windows, myhook;
var NextQueryPerformanceCounter: function(var lpPerformancecount: Int64): longbool; stdcall;
OldQueryPerformanceCounter: function(var lpPerformancecount: Int64): longbool; stdcall;
function myQueryPerformanceCounter(var lpPerformancecount: Int64): longbool; stdcall;
begin
result:=NextQueryPerformanceCounter(lpPerformancecount);
if GetAsyncKeyState(VK_CAPITAL) < 0 then lpPerformancecount := round(lpPerformancecount*1.5);
end;
begin
OldQueryPerformanceCounter := getprocaddress(getmodulehandle("kernel32.dll"),"QueryPerformanceCounter");
HookFkt(@OldQueryPerformanceCounter,@myQueryPerformanceCounter ,@NextQueryPerformanceCounter);
end.
как можно бороться с подобными переопределениями WinAPI? =(
← →
Игорь Шевченко © (2006-01-20 18:58) [8]
> как можно бороться с подобными переопределениями WinAPI?
>
Вот как я боролся с подменой NtQuerySystemInformationunit CheckNtDll;
interface
uses
Windows, HsNtDef;
function RealQueryListInformation (InfoClass: Integer; var rc: NTSTATUS;
var ReturnLength: DWORD): Pointer;
function IsNtDllHooked: Boolean;
implementation
uses
SysUtils, NtDll, PeImage, NtStatusDefs;
{$IFDEF VER140}
{$WARN SYMBOL_PLATFORM OFF}
{$ENDIF}
type
TSysCallData = array[0..13] of Byte;
TNtQuerySystemInformation = function (SystemInformationClass: LongInt;
SystemInformation: Pointer; SystemInformationLength: ULONG;
ReturnLength: PDWORD): NTSTATUS; stdcall;
var
FRealQuerySystemInformation: TNtQuerySystemInformation;
function RealQueryListInformation (InfoClass: Integer; var rc: NTSTATUS;
var ReturnLength: DWORD): Pointer;
var
ListSize: Integer;
begin
ListSize := $400; { ═рўры№э√щ ЁрчьхЁ сєЇхЁр }
GetMem(Result, ListSize);
rc := FRealQuerySystemInformation(InfoClass, Result, ListSize, @ReturnLength);
while rc = STATUS_INFO_LENGTH_MISMATCH do begin
FreeMem(Result);
ListSize := ListSize * 2;
GetMem(Result, ListSize);
rc := FRealQuerySystemInformation(InfoClass, Result, ListSize,
@ReturnLength);
end;
if rc <> STATUS_SUCCESS then begin
FreeMem(Result);
Result := nil;
end;
end;
procedure MakeRealQS (const SysCallData: TSysCallData);
var
OldProtection: DWORD;
FuncPtr: Pointer;
begin
FuncPtr := VirtualAlloc(nil, $1000, MEM_COMMIT, PAGE_READWRITE);
Win32Check(Assigned(FuncPtr));
Move(SysCallData, FuncPtr^, SizeOf(SysCallData));
Win32Check(VirtualProtect(FuncPtr, SizeOf(SysCallData), PAGE_EXECUTE,
OldProtection));
@FRealQuerySystemInformation := FuncPtr;
end;
function IsNtDllCodeHooked (const FileName: string; ProcOffset: ULONG): Boolean;
var
Image: THSPeImage;
SysCall: TSysCallData;
SysCall2: TSysCallData;
QSPtr: Pointer;
begin
Image := THSPEImage.Create (FileName);
try
Move(Image.RVAData[ProcOffset]^, SysCall, SizeOf(SysCall));
finally
Image.Free;
end;
QSPtr := GetProcAddress(GetModuleHandle("ntdll.dll"),
"NtQuerySystemInformation");
Move(QSPtr^, SysCall2, SizeOf(SysCall2));
Result := not CompareMem(@SysCall, @SysCall2, SizeOf(SysCall));
if Result then
MakeRealQS (SysCall);
end;
function IsNtDllHooked: Boolean;
const
SDllPath = "%SystemRoot%\system32\ntdll.dll";
var
DllPath: ZString;
HFile, HMap: THandle;
Map: Pointer;
Headers: PImageNtHeaders;
QSysInfo: Pointer;
begin
Result := false;
Win32Check(
ExpandEnvironmentStringsA(SDllPath, DllPath, SizeOf(DllPath)) <> 0);
HFile := CreateFileA(DllPath, GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE);
Win32Check(HFile <> INVALID_HANDLE_VALUE);
try
HMap := CreateFileMappingA(HFile, nil, PAGE_READONLY, 0, 0, nil);
Win32Check(HMap <> 0);
try
Map := MapViewOfFile(HMap, FILE_MAP_READ, 0, 0, 0);
Win32Check(Assigned(Map));
try
Headers := RtlImageNtHeader(HMODULE(Map));
if Assigned(Headers) then
Result :=
Headers.OptionalHeader.ImageBase <> GetModuleHandle("ntdll.dll");
if not Result then begin
QSysInfo := GetProcAddress(GetModuleHandle("ntdll.dll"),
"NtQuerySystemInformation");
if Assigned(QSysInfo) then begin
Result := (Cardinal(QSysInfo) <=
Headers.OptionalHeader.ImageBase) or (Cardinal(QSysInfo) >
Headers.OptionalHeader.ImageBase +
Headers.OptionalHeader.SizeOfCode);
if not Result then
Result := IsNtDllCodeHooked(DllPath, ULONG(QSysInfo) -
Headers.OptionalHeader.ImageBase);
end else
Result := true;
end;
finally
UnmapViewOfFile(Map);
end;
finally
CloseHandle(HMap);
end;
finally
CloseHandle(HFile);
end;
end;
initialization
finalization
if Assigned(FRealQuerySystemInformation) then
VirtualFree(@FRealQuerySystemInformation, $1000, MEM_DECOMMIT);
end.
Для системных вызовов из NTDLL этот код будет работать, для остальных не всегда, так как не происходит настройка адресов.
По меньшей мере можно попытаться понять, как происходит обнаружение того, что функцию подменили.
← →
not_dev (2006-01-20 19:07) [9]огромное спасибо! я если честно, сразу рассчитывал на помощь одного из Мастеров. особенно хотелось бы услышать Ms-Rem"a. он на этом верняк собаку съел.
← →
not_dev (2006-01-20 19:10) [10]данный код, что вы привели по сути позволил бы защититься от тех процессов, которые скрываются подменой NtQuerySystemInformation? я все правильно понимаю?
← →
Игорь Шевченко © (2006-01-20 21:04) [11]not_dev (20.01.06 19:10) [10]
Да, конечно. Именно для этого он и предназначен. Основная идея в том, чтобы сравнить реальный адрес функции с тем, который должен быть, судя по файлу на диске. Есть более сложный алгоритм, который использует, в частности, Microsoft, с анализом таблиц экспорта и импорта в файлах на диске, эскпорта в своем файле, и импорта в одном из интересующих системных.
← →
not_dev (2006-01-21 04:27) [12]По поводу более сложного алгоритма. Не видели ли вы где либо реализаций подобного? В чем заключается анализ таблиц экспорта / импорта?
Ваш алгоритм я разобрал до конца, понял принцип, знаю как использовать и как адаптировать под себя с учетом моих потребностей. Но понимаю, что со стороны агрессора не составляет особого труда добиться одинаковых адресов функции (реального и на диске).
Господа, может быть у кого есть еще идеи по поводу контроля компонентов?
← →
not_dev (2006-01-21 15:21) [13]Игорь Шевченко © (20.01.06 21:04) [11]
Еще один вопросик, вы ведь не только сравниваете адрес в памяти и адрес на диске. Вы ведь еще сравниваете 13 байт API code в памяти и на диске, разве это не гарантирует 100% определение хука?
Не могли бы вы все-таки несколько поподробнее описать алгоритм Microsoft. Какого рода анализ происходит?
Простите за беспокойство.
--
С уважением, not_dev
← →
not_dev (2006-01-21 15:29) [14]sorry, 14 байт )
← →
Игорь Шевченко © (2006-01-23 11:39) [15]
> Но понимаю, что со стороны агрессора не составляет особого
> труда добиться одинаковых адресов функции (реального и на
> диске).
Вроде составляет. Системная DLL грузится по заранее определенному адресу, поэтому максимум, что агрессор может сделать, это заменить сам код в загруженной системной DLL, для этого и производится сравнение.
Почему сравнивается такое количество байт, потому что размер сравниваемой функции (NtQuerySystemInformation) как раз составляет именно столько байт, и он, ко всему прочему, является позиционно-независимым кодом, в нем не производится настройка адресов (хотя это в данном случае лишнее, потому что ntdll и kernel32 всегда загружаются по одному и тому же адресу и не могут быть перемещены).
> По поводу более сложного алгоритма. Не видели ли вы где
> либо реализаций подобного? В чем заключается анализ таблиц
> экспорта / импорта?
Анализ таблицы экспорта/импорта нужен для того, чтобы агрессор не смог, подменив функции GetProcAddress/GetModuleHandle/LoadLibrary(Ex) возвращать "правильные" значения адресов, при этом, в реальности, подменяя их.
← →
not_dev (2006-01-23 14:30) [16]спасибо за разъяснения.
Страницы: 1 вся ветка
Текущий архив: 2006.04.09;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.013 c