Приветствую Вас Гость!
Пятница, 20.04.2018, 06:00
Главная | Регистрация | Вход | RSS

Меню сайта

Статистика


Онлайн всего: 1
Гостей: 1
Пользователей: 0

Рекомендуется

Поиск

Рекомендуется

Друзья сайта

Статьи

Главная » 2011 » Март » 13 » Обнаружение скрытых процессов
17:57
Обнаружение скрытых процессов

Многие пользователи привыкли к тому, что в Windows NT диспетчер задач показывает все процессы, и многие считают, что скрыться от него вообще невозможно. На самом деле, скрыть процесс чрезвычайно просто. Для этого существует множество методов, и их реализации доступны в исходниках.

Остается только удивляться, почему так редки трояны использующие эти методики? Их буквально 1 на 1000 не умеющих скрываться. Я думаю, это объясняется тем, что авторам троянов лень, ведь для этого необязательно писать что-то свое, всегда можно взять готовый исходник и вставить в свою программу. Поэтому следует ожидать, что скоро скрытие процессов будет применяться во всех широко распостраненных рядовых троянах.

 

Естественно, от этого нужно иметь защиту. Производители антивирусов и фаерволлов отстали от жизни, так как их продукты не умеют обнаруживать скрытые процессы. Для этого существует только несколько утилит, из которых единственной бесплатной является Klister (работает только на Windows 2000), а за остальные производители требуют немалых денег. Причем все эти утилиты довольно легко обходятся.

 

Все имеющиеся сейчас программы для обнаружения скрытых процессов построены на каком-то одном принципе, поэтому для их обхода можно придумать метод скрытия от конкретного принципа обнаружения, либо привязываться к одной конкретной программе, что гораздо проще в реализации. Пользователь купивший коммерческую программу не может изменить ее, а поэтому привязка к конкретной программе будет работать достаточно надежно, поэтому этот метод используется в коммерческих руткитах (например hxdef Golden edition). Единственным выходом будет создание бесплатной Opensource программы для обнаружения скрытых процессов в которой будут применены несколько методов обнаружения, что позволит защититься от фундаментальных принципов скрытия, а от привязки к конкретным программам может защититься каждый пользователь, для этого нужно всего лишь взять исходники программы и переделать ее под себя.

 

В этой статье я хочу рассмотреть основные методы обнаружения скрытых процессов, привести примеры кода использующего эти методы и создать в конце законченную программу для обнаружения скрытых процессов, которая удовлетворяла бы всем вышеприведенным требованиям.

 

Обнаружение в User Mode

Для начала рассмотрим простые методы обнаружения, которые могут быть применены в 3 кольце, без использования драйверов. Они основаны на том, что каждый запущенный процесс порождает побочные проявления своей деятельности, по которым его и можно обнаружить. Этими проявлениями могут быть открытые им хэндлы, окна, созданные системные объекты. От подобных методик обнаружения несложно скрыться, но для этого нужно учесть ВСЕ побочные проявления работы процесса. Ни в одном из публичных руткитов это пока еще не сделано (приватные версии к сожалению ко мне не попали). Юзермодные методы просты в реализации, безопасны в применении, и могут дать положительный эффект, поэтому их использованием не стоит пренебрегать.

 

Для начала определимся с форматом данных возвращаемых функциями поиска, пусть это будут связанные списки:

 

type

PProcList = ^TProcList;

TProcList = packed record

NextItem: pointer;

ProcName: array [0..MAX_PATH] of Char;

ProcId: dword;

ParrentId: dword;

end;

 

Получение списка процессов через ToolHelp API

Для начала определим образцовую функцию получающую список процессов, с ее результатами мы будем сравнивать результаты полученные всеми другими способами:

 

{

Получение списка процессов через ToolHelp API.

}

procedure GetToolHelpProcessList(var List: PListStruct);

var

Snap: dword;

Process: TPROCESSENTRY32;

NewItem: PProcessRecord;

begin

Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if Snap INVALID_HANDLE_VALUE then

begin

Process.dwSize := SizeOf(TPROCESSENTRY32);

if Process32First(Snap, Process) then

repeat

GetMem(NewItem, SizeOf(TProcessRecord));

ZeroMemory(NewItem, SizeOf(TProcessRecord));

NewItem^.ProcessId := Process.th32ProcessID;

NewItem^.ParrentPID := Process.th32ParentProcessID;

lstrcpy(@NewItem^.ProcessName, Process.szExeFile);

AddItem(List, NewItem);

until not Process32Next(Snap, Process);

CloseHandle(Snap);

end;

end;

Очевидно, что любой скрытый процесс при таком перечислении найден не будет, поэтому эта функция будет образцовой для отделения скрытых процессов от нескрытых

Получение списка процессов через Native API

Следующим уровнем проверки будет получение списка процессов через ZwQuerySystemInformation (Native API). На этом уровне также врядли что-нибудь обнаружиться, но проверить все-таки стоит.

 

{

Получение списка процессов через ZwQuerySystemInformation.

}

procedure GetNativeProcessList(var List: PListStruct);

var

Info: PSYSTEM_PROCESSES;

NewItem: PProcessRecord;

Mem: pointer;

begin

Info := GetInfoTable(SystemProcessesAndThreadsInformation);

Mem := Info;

if Info = nil then Exit;

repeat

GetMem(NewItem, SizeOf(TProcessRecord));

ZeroMemory(NewItem, SizeOf(TProcessRecord));

lstrcpy(@NewItem^.ProcessName,

PChar(WideCharToString(Info^.ProcessName.Buffer)));

NewItem^.ProcessId := Info^.ProcessId;

NewItem^.ParrentPID := Info^.InheritedFromProcessId;

AddItem(List, NewItem);

Info := pointer(dword(info) + info^.NextEntryDelta);

until Info^.NextEntryDelta = 0;

VirtualFree(Mem, 0, MEM_RELEASE);

end;

 

 

Получение списка процессов по списку открытых хэндлов.

Многие программы скрывающие процесс, не скрывают открытые им хэндлы, следовательно перечислив открытые хэндлы через ZwQuerySystemInformation мы можем построить список процессов.

 

{

Получение списка процессов по списку открытых хэндлов.

Возвращает только ProcessId.

}

procedure GetHandlesProcessList(var List: PListStruct);

var

Info: PSYSTEM_HANDLE_INFORMATION_EX;

NewItem: PProcessRecord;

r: dword;

OldPid: dword;

begin

OldPid := 0;

Info := GetInfoTable(SystemHandleInformation);

if Info = nil then Exit;

for r := 0 to Info^.NumberOfHandles do

if Info^.Information[r].ProcessId OldPid then

begin

OldPid := Info^.Information[r].ProcessId;

GetMem(NewItem, SizeOf(TProcessRecord));

ZeroMemory(NewItem, SizeOf(TProcessRecord));

NewItem^.ProcessId := OldPid;

AddItem(List, NewItem);

end;

VirtualFree(Info, 0, MEM_RELEASE);

end;

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

Просмотров: 1820 | Добавил: Composed | Рейтинг: 0.0/0

Похожие новости:

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]