"А главное - никогда не подключайтесь телнетом к атакуемой машине!" - из одного хакерского мануала. 

Думаю ты сам догадался почему - как-то неприятно оставлять в логах свой IP, от этого твоя безопасность может "чуть-чуть" пострадать :)) Ты
предложишь использовать SOCKS-сервера? Но во-первых их надо еще и найти, а во-вторых, даже если сервак является анонимным, то он все равно ведет логи, да к тому же может выполнять прямо противоположенную задачу - не обеспечивать анонимность, а служить для отлова хакеров, спаммеров и прочих социально опасных элементов 🙂 Поэтому самым верным с точки зрения человека со здоровой параноей будет поставить такой "прокси" лично для себя. Программа ставится на удаленную машину, например на заломанный тобой бесхозный сервак, или на какой-нить комп, стоящий во многочисленных Инет-центрах, инет-кафе/салонах/кабаках/борделях - добавить по вкусу :)) Правда в этом случае придется позаботиться о незаметности программы, но это уже совсем другая история. Пока же мы рассмотрим теорию и (самое главное :)) -- практику построения такой программы )

Для этого тебе понадобиться Дельфя (от 4-ой версии и выше), руки и голова
(очень желательно чтобы с мозгом :))  Запускаем Дельфю, затем File-New Application. На форму лепим два компонента из категории "Internet" - Client Socket и Server Socket - c которыми у нас и пойдет основная работа. Как следует из названий, эти элементы формы -
клиентский и серверный сокеты соответственно. Чем они хороши - что для КАЖДОГО события сокета можно задать свою процедуру, не нужно заморачиваться с WinAPI'шными функциями типа
WSAAsyncSelect, опеределяющими состояния сокета. А событий этих много - особенно для серверного сокета. Нам же, вследствие простоты ваяемой нами проги, будут нужны лишь некоторые из них. 

Рассмотрим алгоритм. Нам нужно, чтобы сервак ждал когда к нему подключиться клиент, устанавливал
соединение с тем хостом, который будет нужен клиенту, и далее выполнять лишь сугубо
посреднические функции :)) В самом начале нужно сервак запустить - а он будет запускаться сразу, по активации формы - для этого в списке
объектов выберем Form1, в графе Events (cобытия) кликнем по пункту "OnActivate". Появится новая процедура, пока пустая, которая и будет запускать наш сервер. 

procedure TForm1.FormActivate(Sender: TObject);
var hw:HWND;

begin

//этим мы определяем порт сервера. 
ServerSocket1.Port:=8765;
// даем команду на старт работы
ServerSocket1.Active:=true;

//что ниже - для того, чтобы убрать окно, дабы оно не мозолило глаза
//hw - определитель окна. Мы считываем активное на данный момент окно
//GetActiveWindow, а окно проги будет активным, потому как запущено только 
//что, а затем убираем его с экрана - функцией Windows.ShowWindow, где 
//второй параметр(тот что SW_HIDE) показывает, что надо сделать с окном - 
//показать, если оно спрятано, и соответственно
наоборот. Нам нужно второе

hw:=Windows.GetActiveWindow;
Windows.ShowWindow(hw,SW_HIDE);

end;

Теперь сервер запущен. Будем принимать данные от клиента, который собственно и будет использовать этот сервак. Прежде чем коннектиться к удаленному серваку, нужно передать программе IP
адрес и порт того сервака. А для этого наш "прокси" должен их принять. Донести столь важные
сведения до прокси можно очень простым способом, не прибегая ни к кому левому программному обеспечению, а воспользовавшись telnet'ом. Передается это просто - 
набираешь сначала IPшник, а потом с новой строки - порт, и опять таки Enter, показывая что ввод окончен.
Рассмотрим механизм их приема. Для приема данных от клиента у серверного сокета есть процедура [SocketName]ClientRead. Опять - выбираешь среди объектов ServerSocket1, затем в событиях выбираешь OnClientRead и одним нажатием мыши создаешь новую процедуру. 

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
q,t:boolean;

begin
//Принимаем данные от клиента. 
ss:=Socket.ReceiveText;

//если еще не произошло подключение - тогда ждем ввода
адреса

if not(t) then begin
if not(q) then
if (byte(ss[1])=13) then begin
//если нажат Enter - пишем данные в строку адреса
и можем переходить
//к ожиданию ввода номера порта

q:=true;
end
else
//иначе - пишем принятые символы в строку адреса.
s1:=s1+ss;

//если уже введена строка адреса, ждем ввода номера порта
if (q) then
if (byte(ss[1])=13) then begin
// если ввели порт - идем дальше

t:=true;
//пишем, что прием данных для подключения выполнен.
//теперь нам нужно подключиться к удаленному серваку.
//присваиваем адрес
ClientSocket1.Address:=s1;
//присваеваем порт
ClientSocket1.Port:=StrToInt(s2);
//преобразовываем строку символов в целое число, являющиеся
//номером порта
//И - пытаемся подключиться.
//Примечание - удаленный сервак должен быть отпиногован и иметь открытый //порт, к которому идет коннект.
ClientSocket1.Active:=true;

end;
else
s2:=s2+ss;
//если нет - пишем символы в строку порта. 

end else
//если все установлено - 
//просто перенаправляем данные удаленному серваку от подключенного юзера

end;

Теперь нам нужно установить, удачно ли завершилась попытка подключения к удаленному серваку. Для этого просмотрим события клиентского сокета, в частности событие OnConnect - и
когда он будет выполнен - передадим клиенту, что соединение установлено - юзер примет эту строку телнетом. 

procedure TForm1.ClientSocket1Connecting(Sender: TObject;
Socket: TCustomWinSocket);
begin
ServerSocket1.Socket.Connections[0].SendText('Connect OK');
//Connection[0] - выбираем, какое из соединений использовать, но так как
//у нас только один канал, то и будет использовано первое по списку
// соединение - с номером 0. СТрока 'Connect OK' функцией SendText будет
//послана клиенту

end;

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

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
begin
//читаем данные с удаленного сервака
ss:=Socket.ReceiveText;
//и посылаем их клиенту:
ServerSocket1.Socket.Connections[0].SendText(ss);

end;

А теперь рассмотрим, что делать при дисконнекте, если удаленный сервак отключил соединение - изредка такое бывает 🙂 - может ты его завалил.
За это отвечает событие клиентского сокета OnDisconnect:

procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
//мы просто посылаем извещение юзеру о том, что связь с удаленным серваком
 //прервалась
ServerSocket1.Socket.Connections[0].SendText('Remote server disconnect');
//пишем, что соединение прервалось
t:=false;
//юзер должен будет опять вводить IP и порт.
// в принципе, можно сделать так, чтобы юзер тоже отключался если происходит 
//разрыв с удаленным серваком, а потом снова подключался к проски - разрыв 
//делается функцией Disconnect

end;

Теперь - о дисконнекте со стороны юзера. Ты же должен будешь подключаться несколько раз, и к разным сервакам, поэтому нужно грамотно отработать процедуру корректного отключения и возращения прокси в первоначальное состояние ожидания, а это сделать очень просто - достаточно присвоить переменной, отвечающей за установкой соединений, значение false.
Для этого рассмотрим событие серверного сокета OnClientDisconnect:

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
// теперь сервак будет ждать нового подключения
t:=false;
// и вырубим старое подключение:
СlientSocket1.Active:=false;

end;

Пару слов о переменных - ss,s1 и s2 - строкового типа, и должны описываться глобально, чтобы могли использоваться во многих процедурах. Служебные переменные t и q - логические типа
boolean. Теперь ты видишь, что работа с сокетами в дельфях гораздо проще, чем обычными АПИшными функциями - каждое из состояний сокета у тебя как на ладони. И самое главное, хотя здесь это почти не упоминалось - возможность многоканальных подключений к серверу, и выделения под каждое из подключений своего сокета, уже готового для работы с данными, и даже своего потока. А теперь представь, сколько было бы хлопот с обычным описанием сокетов "ручками", не говоря уж о многоканальности. Так что прогресс не стоит на месте 🙂

И еще пара слов о самой программе - лучше выбирать порт прокси, к которому будет подключаться клиент, не стандартным типа
80 или 1080, а что-то вроде 8776 - т.е. такой, чтобы на него случайно не наткнулись какие-нить левые юзеры, сканящие сети в поисках прокси и прочего. 

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

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии