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

Думаю ты сам догадался почему — как-то неприятно оставлять в логах свой 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 — т.е. такой, чтобы на него случайно не наткнулись какие-нить левые юзеры, сканящие сети в поисках прокси и прочего. 

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

Оставить мнение

Check Also

Жизнь без антивируса. Как побороть малварь голыми руками и обезопасить себя на будущее

На вопрос «Какой антивирус вы используете на своей виндовой машине?» многие безопасники (в…