ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2

ANTICHAT — форум по информационной безопасности, OSINT и технологиям

ANTICHAT — русскоязычное сообщество по безопасности, OSINT и программированию. Форум ранее работал на доменах antichat.ru, antichat.com и antichat.club, и теперь снова доступен на новом адресе — forum.antichat.xyz.
Форум восстановлен и продолжает развитие: доступны архивные темы, добавляются новые обсуждения и материалы.
⚠️ Старые аккаунты восстановить невозможно — необходимо зарегистрироваться заново.
Вернуться   Форум АНТИЧАТ > Программирование > С/С++, C#, Delphi, .NET, Asm
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Socks-сервер WinSock
  #1  
Старый 13.06.2010, 20:59
Faost
Новичок
Регистрация: 11.07.2009
Сообщений: 20
Провел на форуме:
39998

Репутация: 2
Отправить сообщение для Faost с помощью ICQ
По умолчанию Socks-сервер WinSock

Т.к. в моей пред.теме о socks никто ничем помочь не смог, создаю еще одну.

Проблема заключается в некорректности работы сокс-сервера через соксификаторы.

Для наглядности, чтоб было максимально понятно написал простейший socks4 сервер с подробнейшими комментариями (Delphi, WinSock + WinApi).

Качаем соксификатор, настраиваем в нем socks4 (Сервер: 127.0.0.1, порт: 8080).


Качаем исходник socks4-сервера (залил для большей наглядности)

Компилируем, запускаем, заходим на mail.ru - страница грузится очень долго (конца загрузки дождаться мне так и не удалось), хотя тот же гугл, да и вконтакт (по крайней мере на "Поиске людей") работают норм.

Так вот, нужна подсказка, из-за чего это происходит и как это исправить.

Код:
Код:
program Socks4;
uses
  Windows,
  WinSock;

const IpToListen = '127.0.0.1';


 function OurBrowserListening(p: pointer): DWORD; stdcall;
  var BSock: TSocket;
      vn, cd, UserID: byte;
      answer: array[1..8] of byte;
      buf: pointer;
      addr: sockaddr_in;
      TargetSock: TSocket;
      fset: tfdset;
      i: integer;
      avail_bytes: integer;
      time_out: timeval;
      label 2, 3;
 begin
  BSock:= Cardinal(p); //BSock - браузер (подключеный клиент)


  TargetSock:= socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  //TargetSock - таргет (цель, конечный хост)
  if TargetSock = INVALID_SOCKET then ExitThread(0);
  ZeroMemory(@addr, sizeof(addr));
  addr.sin_family:= PF_INET;

//Теперь нужно принять данные от браузера (клиента):
// +----+----+----+----+----+----+----+----+----+----+....+----+
// | VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|
// +----+----+----+----+----+----+----+----+----+----+....+----+
//   1    1      2              4           variable       1

  recv(BSock, vn, sizeof(vn), 0); //принимаем версию socks - 4
  recv(BSock, cd, sizeof(cd), 0); //принимаем команду - 1 (connect)
  if cd <> $01 then goto 2;  //если не connect, то перейти к метке 2
  recv(BSock, addr.sin_port, 2, 0); //принимаем порт таргета (цели)
  recv(BSock, addr.sin_addr.S_addr, 4, 0); //принимаем ip таргета (цели)
  repeat
  recv(BSock, UserID, sizeof(UserID), 0);
  until UserID = $00; //принимаем UserID, оканчивающийся NULL-байтом


  //пытаемся соединиться с таргетом
  if connect(TargetSock, addr, sizeof(addr)) <> 0 then
  begin //если не удалось, то:
2:ZeroMemory(@answer, sizeof(answer));
  answer[1]:= $00; //должен быть 0
  answer[2]:= $5B; //$5B - ошибка
  send(BSock, answer, sizeof(answer), 0); //посылаем ответ браузеру (клиенту)
  goto 3;
  end;


//Теперь нужно послать ответ браузеру (клиенту)
//  +----+----+----+----+----+----+----+----+
//  | VN | CD | DSTPORT |      DSTIP        |
//  +----+----+----+----+----+----+----+----+
//     1    1      2              4
  ZeroMemory(@answer, sizeof(answer));
  answer[1]:= $00; //должен быть 0
  answer[2]:= $5A; //$5A - коннект к таргету успешен
  send(BSock, answer, sizeof(answer), 0); //посылаем ответ браузеру (клиенту)


//Теперь следует непосредственно перенаправление данных от браузера к
//таргету и наоборот
  while true do
  begin //while true do

   FD_ZERO(fset);
   FD_SET(BSock, fset);
   FD_SET(TargetSock, fset);
   time_out.tv_sec:= 8; //установим таймаут на select в 8 секунд
   time_out.tv_usec:= 0;


   if select(0, @fset, nil, nil, @time_out) <= 0 then
   goto 3;
   //если есть данные от браузера и/или таргета, то:




   if FD_IsSet(BSock, fset) then //если есть данные от браузера, то:
   begin
   avail_bytes:= 0;
   ioctlsocket(BSock, FIONREAD, avail_bytes); //читаем кол-во пришедших байт
   buf:= VirtualAlloc(nil, avail_bytes, MEM_COMMIT, PAGE_READWRITE); //освобождаем под них память
   i:= recv(BSock, buf^, avail_bytes, 0); //принимаем их от браузера
   if i <= 0 then //если ошибка/соединение закрыто, то:
   begin
   VirtualFree(buf, 0, MEM_RELEASE);
   goto 3;
   end;
   send(TargetSock, buf^, i, 0); //передаем клиенту
   VirtualFree(buf, 0, MEM_RELEASE); //освобождаем память
   end;


   if FD_IsSet(TargetSock, fset) then //если есть данные от таргета, то:
   begin
   avail_bytes:= 0;
   ioctlsocket(TargetSock, FIONREAD, avail_bytes); //читаем кол-во пришедших байт
   buf:= VirtualAlloc(nil, avail_bytes, MEM_COMMIT, PAGE_READWRITE); //освобождаем под них память
   i:= recv(TargetSock, buf^, avail_bytes, 0); //принимаем их от таргета
   if i <= 0 then //если ошибка/соединение закрыто, то:
   begin
   VirtualFree(buf, 0, MEM_RELEASE);
   goto 3;
   end;
   send(BSock, buf^, i, 0);
   VirtualFree(buf, 0, MEM_RELEASE); //освобождаем память
   end;



  end;  //while true do


  3:
     CloseSocket(BSock);       //закрываем сокет браузера
     CloseSocket(TargetSock); //закрываем сокет таргета

 Result:= 0;
 ExitThread(0); //выходим из потока
 end;




 var sock, ClientSock: TSocket;
     wdata: TWSAData;
     saddr: sockaddr_in;
     id: DWORD;
     label 1;
begin
if WSAStartup(MAKEWORD(1, 1), wdata) <> 0 then ExitProcess(0);
sock:= socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if sock = INVALID_SOCKET then ExitProcess(0);

ZeroMemory(@saddr, sizeof(saddr));
saddr.sin_family:= PF_INET;
saddr.sin_port:= htons(8080); //будем слушать на 8080 порту
saddr.sin_addr.S_addr:= inet_addr(IpToListen); //127.0.0.1
if bind(sock, saddr, sizeof(sockaddr_in)) <> 0 then ExitProcess(0);
if listen(sock, SOMAXCONN) <> 0 then ExitProcess(0);

1:
ClientSock:= accept(sock, nil, nil);
CreateThread(nil, 0, @OurBrowserListening, pointer(ClientSock), 0, id);
goto 1; //Если подключился, ждем подключения снова.

WSACleanup();



end.
Я так думаю, что проблема зарыта где-то уже на этапе перенаправления данных от браузера к таргету и наоборот, но где именно - не могу найти никак, скоро на стену полезу. Надеюсь на вашу помощь.

Тому, кто поможет, скромное вознаграждение размером в 20$. Очень надеюсь на вас, а то я уже сломал мозг.
 
Ответить с цитированием

  #2  
Старый 14.06.2010, 18:37
Faost
Новичок
Регистрация: 11.07.2009
Сообщений: 20
Провел на форуме:
39998

Репутация: 2
Отправить сообщение для Faost с помощью ICQ
По умолчанию

Неужели на ачате совсем не осталось знающих людей? Может тогда посоветуете подходящий форум?
 
Ответить с цитированием

  #3  
Старый 14.06.2010, 18:56
Ra$cal
Постоянный
Регистрация: 16.08.2006
Сообщений: 640
Провел на форуме:
1354067

Репутация: 599


По умолчанию

попробуй на васме спросить. здесь мало кто таким программингом занимается. В основм хттпвебреквест, на делфе сделать проверку 20 радиобатонов через ифы, итп.
 
Ответить с цитированием

  #4  
Старый 14.06.2010, 19:10
fluffylion
Познающий
Регистрация: 22.02.2010
Сообщений: 30
Провел на форуме:
188597

Репутация: 15
По умолчанию

Faost, как вариант можно разбить обработчик сессии на 2 потока, в одном передавать данные от браузера к таргету, в другом от таргета к браузеру
 
Ответить с цитированием

  #5  
Старый 14.06.2010, 19:23
Faost
Новичок
Регистрация: 11.07.2009
Сообщений: 20
Провел на форуме:
39998

Репутация: 2
Отправить сообщение для Faost с помощью ICQ
По умолчанию

Ra$cal, спасибо, попробую. Только не побьют ли меня там за делфийский код...)
А то билдер долго качать и устанавливать, чтоб проверить, так ли переписал на C.
fluffylion, я и так пробовал, проблема аналогичная.
 
Ответить с цитированием

  #6  
Старый 14.06.2010, 19:35
Ra$cal
Постоянный
Регистрация: 16.08.2006
Сообщений: 640
Провел на форуме:
1354067

Репутация: 599


По умолчанию

не побьют, но помогать будут медленнее =) накидай алгоритм словесный примерный лучше. я вот тоже даже не пытался смотретоь на код, ибо делфи.
 
Ответить с цитированием

  #7  
Старый 14.06.2010, 21:43
bons
Участник форума
Регистрация: 20.12.2007
Сообщений: 295
Провел на форуме:
1777055

Репутация: 347
По умолчанию

компилить и отлаживать код не пытался, так что просто опишу что я заметил, просматривая это:
- когда принимаешь заголовок socks не проверяешь количество принятых байт
- неправльная работа с select. Проблемы с mail.ru полагаю из-за этого. Ты не проверяешь возможность того что селект возвратил управление по таймауту. Ты не обновляешь набор сокетов перед использованием селекта. Короче, читай маны...
- зачем-то использованы одновременно потоки и select
- VirtualAlloc для выделения буфера памяти каждый раз при приеме данных очень круто и оптимально... вообще выделяемая этой функцией память округляется до страницы(64 кб). Почему бы не использовать буфер в стеке?
- когда таргет закрывает соединение, надо сначала отправить все данные в его буфере клиенту, а потом уже корректно завершить соединение с помощью shutdown а не обрывать его.

стиль:
- зачем goto? тут можно было бы и без него
- нет отступов адекватных


дополнительные советы:
если будут еще проблемы, попробуй использовать сниффер для отладки...

PS за такой код на васме точно побьют
 
Ответить с цитированием

  #8  
Старый 14.06.2010, 22:00
slesh
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


Отправить сообщение для slesh с помощью ICQ
По умолчанию

дажа разбиратсья влом, глядя на этот код.
Оформление нулевое и ужасный код.
 
Ответить с цитированием

  #9  
Старый 14.06.2010, 22:14
Faost
Новичок
Регистрация: 11.07.2009
Сообщений: 20
Провел на форуме:
39998

Репутация: 2
Отправить сообщение для Faost с помощью ICQ
По умолчанию

Цитата:
- когда принимаешь заголовок socks не проверяешь количество принятых байт
Ну это само собой, что нужно проверять, это все отлажено - тут проблем не возникает, поэтому для большей минимальности убрал проверку.
Цитата:
- неправльная работа с select. Проблемы с mail.ru полагаю из-за этого. Ты не проверяешь возможность того что селект возвратил управление по таймауту. Ты не обновляешь набор сокетов перед использованием селекта.
Насчет таймаута - я ставил даже на "бесконечное" ожидание - select(0, @fset, nil, nil, nil), проблема абсолютно идентична. Кроме того, маил.ру ну полюбасу ответит в течении 8сек на 1 запрос.
Цитата:
Ты не обновляешь набор сокетов перед использованием селекта
FD_ZERO(fset);
FD_SET(BSock, fset);
FD_SET(TargetSock, fset);
Цитата:
зачем-то использованы одновременно потоки и select
В главном потоке сервер слушает подключившихся клиентов, причем слушать след.клиента надо сразу после подключения первого.
Цитата:
VirtualAlloc для выделения буфера памяти каждый раз при приеме данных очень круто и оптимально... вообще выделяемая этой функцией память округляется до страницы(64 кб). Почему бы не использовать буфер в стеке?
Учту.
Цитата:
когда таргет закрывает соединение, надо сначала отправить все данные в его буфере клиенту, а потом уже корректно завершить соединение с помощью shutdown а не обрывать его.
А какие данные то отправлять, если они передаются ему по мере поступления от таргета? Как только таргет отправил данные, они отправились клиенту (браузеру). Если таргет вместо того, чтобы отправить данные, разрывает соединение, то что еще остается передать браузеру? Насчет shutdown - пробовал, результат тот же(

Цитата:
зачем goto? тут можно было бы и без него
можно было. Мне кажется, для форумчан использование goto очень-очень наглядно. Иначе, с множеством begin;end было бы жесть.
Цитата:
Оформление нулевое и ужасный код.
Насчет оформления - да тут и оформлять то собственно нечего, в коде нет и 200 строк. Насчет кода - поправь меня, скажи где что КРИТИЧЕСКИ криво (не учитывая goto, проверку того, в чем я уверен и что ошибочным в ходе ПРАВИЛЬНОГО теста быть не может - например, заголовков сокс. Также не считаю критически кривым кучу ExitProcess в начале, т.к. мне кажется, что это поспособствовало бы лучшему пониманию, чем множество begin;end). Ребята, вы же понимаете, что это не исходник на продажу/не для всеобщего использования в повседневной жизни, поэтому о каких программерских тонкостях типа goto может идти речь?
P.S.
Цитата:
Да, я злой и грубый, а что остается еще делать видя этот кривой код и радостные лица тех, кто его написал.
Лицо у меня далеко не радостное

Последний раз редактировалось Faost; 14.06.2010 в 22:33..
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
FAQ по Прокси gars0n Авторские статьи 4 12.04.2010 14:01
Общие сведения о Ftp уязвимостях. ReVOLVeR Чужие Статьи 0 15.09.2006 19:27
Скрытие ip через socks сервер Fol Чаты 5 24.11.2003 15:11



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ