Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Socks5 клиент, как состряпать запрос ? [D7, Win2k, WinXP]


Страницы:   1 2

AHTOLLlKA ©   (2008-07-08 09:37:00) 

инжекюсь в приложение, делаю хук на connect

и пытаюсь переправить программу через sock5 прокси сервер (в программе нет возможности указать чтобы она работала через прокси, вот и приходиться)
вобщем аналог фрикапа...
на сокс4 все сделал.. работало а на сокс5 не могу..
вот функция.. которой подменяю connect

function hconnect(s:dword;sain:PSockAddrIn;slen:integer):integer;stdcall;
var
sh5:TSocks5Header;
sh50:TSocks5Header0;
   uname:string;
   s2in:sockaddr_in;
   prxy_a:string;
   prxy_p:word;
   buff:array[0..16]of char;
   i:dword;

begin

ZeroMemory(@sh50,sizeof(tsocks5header0));
CopyMemory(@s2in,sain,sizeof(s2in));

ZeroMemory(@sh5,sizeof(TSocks5Header));

 prxy_p:=31337;
 prxy_a:='127.0.0.1';
 s2in.sin_addr.S_addr:=inet_addr(pchar(prxy_a));
 s2in.sin_port:=htons(prxy_p);

 UnHookCodeHook(@rd_c);
 result:=connect(s,s2in,slen);

 SetCodeHook(rd_c.Address,@hconnect,@rd_c);
 i:=GetLastError;

if conn=true then
begin
conn:=false;
 sh50.VER:=$05;
 sh50.NMETHODS:=$01;
 sh50.METHODS:=$00;

 send(s,sh50,sizeof(tsocks5header0),0);
 sleep(100);
 recv(s,sh50,sizeof(tsocks5header0),0);

end;

 if sh50.VER=$05 then
 begin
 sh5.VER:=$05;
 sh5.CMD:=$01;
 sh5.RSV:=$00;
 sh5.ATYP:=$01;
 sh5.dIP:=sain^.sin_addr;
 sh5.wPort:=sain^.sin_port;

 send(s,sh5,sizeof(tsocks5header),0);
 sleep(100);
 recv(s,sh5,sizeof(tsocks5header),0);

 end;
end;


кто тыкнет в недочет ?? почему не работает ? вроде как в рфц указано сделал..


  (2009-03-15 12:49:00) [1]

Удалено модератором


  (2009-03-15 12:46:00) [2]

Удалено модератором


Slym   (2008-07-21 14:05:00) [3]

1. он уже смотрел в инди...
AHTOLLlKA   (17.07.08 13:10) [33]
05 01 00 03

и не будет :) он ждет строку а не упакованый в Int ip адрес
ты ему имя или адрес в виде строки отдай а не упакованый ip
Slym ©   (10.07.08 10:50) [21]
Host:=inet_ntoa(name.sin_addr);
 Cmd[0] := $5;   // socks version
 Cmd[1] := $1;   // connect method
 Cmd[2] := $0;   // reserved
 Cmd[3] := $3;   // address type: IP V4 address: X'01'    {Do not Localize}
 Cmd[4] := Length(Host);
  if Length(Host)>0 then
   Move(Host[1], Cmd[5], Length(Host));
 PWord(@Cmd[5+Cmd[4]]):=name.sin_port;
 CmdLen:=5+Cmd[4]+SizeOf(Word);


Eraser   (2008-07-18 15:47:00) [4]

> [0] AHTOLLlKA   (08.07.08 09:37)

в Indy есть нужный компонент, посмотри как сделано и сделай так же.


AHTOLLlKA   (2008-07-17 13:10:00) [5]

05 01 00 03 40 0C A1 B9 14 46
щас такой запрос.. все равно ничего ..


Slym   (2008-07-16 08:52:00) [6]

AHTOLLlKA   (11.07.08 13:33) [30]
разница в:
1. типе - buf[3]: у тебя 1(IP), у людей 3(Domain Name)
2. после порта лишний #0
попробуй Slym ©   (10.07.08 10:50) [21]
и будет тебе конект login.icq.com:5190


AHTOLLlKA   (2008-07-15 14:04:00) [7]

Апну, немогу все еще разобраться, не хватает мне мозгов, никто ни чего не придумал ?


AHTOLLlKA   (2008-07-11 13:33:00) [8]

отснифал..
проблема с пакетом..
авторизация правельная..
а вот это место ..
sh5.VER:=$05;
sh5.CMD:=$01;
sh5.RSV:=$00;
sh5.ATYP:=$01;
sh5.dIP:=sain.sin_addr;
sh5.wPort:=sain.sin_port;


если конект через прокси.. то шлеться так
05 01 00 03 0D 6C 6F 67 69 6E 2E 69 63 71 2E 63 6F 6D 14 46

а если через мой запрос то так
05 01 00 01 40 0C C8 59 14 46 00


Slym   (2008-07-11 12:01:00) [9]

Slym ©   (11.07.08 11:59) [28]
либо ты недокациваешь/перекачиваешь ответ прокселя...
 case Cmd[3] of
  1: CmdLen := 4 + 2;
  3: CmdLen := Cmd[4]+2;
  4: CmdLen := 16 + 2;
 end;
 if recv(s,(@Cmd[5])^,CmdLen,0)<>CmdLen then
   Abort;


Slym   (2008-07-11 11:59:00) [10]

Тогда брать портмап или снифер, натравливать FreeCap и потом анализировать "заранее верный" поток данных фрикапа


AHTOLLlKA   (2008-07-11 09:21:00) [11]

=( что то не помогает ((
теперь без ошибок.. но все равно не конект ((


Slym   (2008-07-11 05:00:00) [12]

Slym ©   (11.07.08 4:58) [25]
Move(Host[1], @name.sin_port, SizeOf(Word));

в "блокноте" писал... надо:
Move(name.sin_port, Cmd[5+Cmd[4]], SizeOf(Word));


Slym   (2008-07-11 04:58:00) [13]

AHTOLLlKA   (10.07.08 10:59) [23]
result:=TConnectProc(rd_c)(s,s2in,SizeOf(s2in));

Замени на свой способ вызова "реальной" функции
AHTOLLlKA   (10.07.08 10:59) [23]
PWord(@Cmd[5+Cmd[4]]):=name.sin_port; Left side cannot be assegned to

PWord(@Cmd[5+Cmd[4]]) ^:=name.sin_port; а так?
или
Move(Host[1], @name.sin_port, SizeOf(Word));


AHTOLLlKA   (2008-07-10 11:51:00) [14]


> umbra ©   (10.07.08 10:58) [22]
> а логи сервера почитать? :)

эм.. сервер тож примитивный, щас попробую добавть логирование ;)


AHTOLLlKA   (2008-07-10 10:59:00) [15]

 result:=TConnectProc(rd_c)(s,s2in,SizeOf(s2in));
Invalid typecast

PWord(@Cmd[5+Cmd[4]]):=name.sin_port;
Left side cannot be assegned to


umbra   (2008-07-10 10:58:00) [16]

а логи сервера почитать? :)


Slym   (2008-07-10 10:50:00) [17]

попробуй передать ip адрес как в [19]посте:
function hconnect(s: TSocket; var name: TSockAddr; namelen: Integer):integer;stdcall;
type TConnectProc= function (s: TSocket; var name: TSockAddr; namelen: Integer): Integer; stdcall;
type
TSocks5AuthReq = packed record
  VER,NMETHODS,METHODS: byte;
end;
TSocks5AuthResp = packed record
  VER,METHOD: byte;
end;
const
Socks5AuthReqDef:TSocks5AuthReq=(VER:$5;NMETHODS:$1;METHODS:$0);
var
s2in:sockaddr_in;
AuthResp:TSocks5AuthResp;
Cmd:array[0..255] of byte;
CmdLen:integer;
Host:string;
begin
try
  s2in.sin_family := PF_INET;
  s2in.sin_addr.S_addr:=inet_addr(pchar('127.0.0.1'));
  s2in.sin_port:=htons(31337);

  result:=TConnectProc(rd_c)(s,s2in,SizeOf(s2in));
  if result=SOCKET_ERROR then exit;
  if send(s,(@Socks5AuthReqDef)^,sizeof(Socks5AuthReqDef),0)<>sizeof(Socks5AuthReqDef  ) then
    Abort;
  if recv(s,AuthResp,sizeof(AuthResp),0)<>sizeof(AuthResp) then
    Abort;
  if (AuthResp.VER<>$05) or (AuthResp.METHOD=$00) then
    Abort;

  Host:=inet_ntoa(name.sin_addr);
  Cmd[0] := $5;   // socks version
  Cmd[1] := $1;   // connect method
  Cmd[2] := $0;   // reserved
  Cmd[3] := $3;   // address type: IP V4 address: X'01'    {Do not Localize}
  Cmd[4] := Length(Host);
  if Length(Host)>0 then
    Move(Host[1], Cmd[5], Length(Host));
  PWord(@Cmd[5+Cmd[4]]):=name.sin_port;
  CmdLen:=5+Cmd[4]+SizeOf(Word);

  if send(s,(@Cmd)^,sizeof(CmdLen),0)<>sizeof(CmdLen) then
    Abort;
  if recv(s,(@Cmd)^,5,0)<>sizeof(5) then
    Abort;
  if Cmd[1]<>0 then
    Abort;
  case Cmd[3] of
   1: CmdLen := 4 + 2;
   3: CmdLen := Cmd[4]+2;
   4: CmdLen := 16 + 2;
  end;
  if recv(s,(@Cmd[5])^,CmdLen,0)<>CmdLen then
    Abort;

except
  shutdown(s,SD_BOTH);
  closesocket(s);
  result:=SOCKET_ERROR;
end;
end;


AHTOLLlKA   (2008-07-10 08:33:00) [18]

уф.. добрался до компа..
вобщем делаю так потом

 if (sh50.VER=$05) and (sh50.NMETHODS=$00) then
 begin
 sh5.VER:=$05;
 sh5.CMD:=$01;
 sh5.RSV:=$00;
 sh5.ATYP:=$01;
 sh5.dIP:=sain.sin_addr;
 sh5.wPort:=sain.sin_port;

 send(s,sh5,sizeof(tsocks5header),0);
 sleep(100);
 recv(s,sh5,sizeof(tsocks5header),0);

 if sh5.cmd=$00 then messagebox(0,'sh5.cmd=$00','',0);
 if sh5.cmd=$01 then messagebox(0,'sh5.cmd=$01','',0);
 if sh5.cmd=$02 then messagebox(0,'sh5.cmd=$02','',0);
 if sh5.cmd=$03 then messagebox(0,'sh5.cmd=$03','',0);
 if sh5.cmd=$04 then messagebox(0,'sh5.cmd=$04','',0);
 if sh5.cmd=$05 then messagebox(0,'sh5.cmd=$05','',0);
 if sh5.cmd=$06 then messagebox(0,'sh5.cmd=$06','',0);
 if sh5.cmd=$07 then messagebox(0,'sh5.cmd=$07','',0);
 if sh5.cmd=$08 then messagebox(0,'sh5.cmd=$08','',0);
 if sh5.cmd=$09 then messagebox(0,'sh5.cmd=$09','',0);
 end;


срабатывает $01
теость
o  X'01' ошибка SOCKS-сервера

блин... как так =((


AHTOLLlKA   (2008-07-08 14:17:00) [19]

пасиба, но как бэ код примерный мжно найти в
Source\Indy\IdSocks.pas

procedure TIdSocksInfo.MakeSocks5Connection(const AHost: string; const APort: Integer);
var
 len, pos: Integer;
 tempBuffer: array [0..255] of Byte;
 ReqestedAuthMethod,
 ServerAuthMethod: Byte;
 tempPort: Word;
begin
 // defined in rfc 1928
 if Authentication = saNoAuthentication then begin
   tempBuffer[2] := $0   // No authentication
 end else begin
   tempBuffer[2] := $2;  // Username password authentication
 end;

 ReqestedAuthMethod := tempBuffer[2];
 tempBuffer[0] := $5;     // socks version
 tempBuffer[1] := $1;     // number of possible authentication methods

 len := 2 + tempBuffer[1];
 FIOHandler.Send(tempBuffer, len);
 try
   FIOHandler.Recv(tempBuffer, 2); // Socks server sends the selected authentication method
 except
   On E: Exception do begin
     raise EIdSocksServerRespondError.Create(RSSocksServerRespondError);
   end;
 end;

 ServerAuthMethod := tempBuffer[1];
 if (ServerAuthMethod <> ReqestedAuthMethod) or (ServerAuthMethod = $FF) then begin
   raise EIdSocksAuthMethodError.Create(RSSocksAuthMethodError);
 end;

 // Authentication process
 if Authentication = saUsernamePassword then begin
   tempBuffer[0] := 1; // version of subnegotiation
   tempBuffer[1] := Length(Username);
   pos := 2;
   if Length(Username) > 0 then begin
     Move(Username[1], tempBuffer[pos], Length(Username));
   end;
   pos := pos + Length(Username);
   tempBuffer[pos] := Length(Password);
   pos := pos + 1;
   if Length(Password) > 0 then begin
     Move(Password[1], tempBuffer[pos], Length(Password));
   end;
   pos := pos + Length(Password);

   FIOHandler.Send(tempBuffer, pos); // send the username and password
   try
     FIOHandler.Recv(tempBuffer, 2);    // Socks server sends the authentication status
   except
     On E: Exception do begin
       raise EIdSocksServerRespondError.Create(RSSocksServerRespondError);
     end;
   end;

   if tempBuffer[1] <> $0 then begin
     raise EIdSocksAuthError.Create(RSSocksAuthError);
   end;
 end;

 // Connection process
 tempBuffer[0] := $5;   // socks version
 tempBuffer[1] := $1;   // connect method
 tempBuffer[2] := $0;   // reserved
 // for now we stick with domain name, must ask Chad how to detect
 // address type
 tempBuffer[3] := $3;   // address type: IP V4 address: X'01'    {Do not Localize}
                        //               DOMAINNAME:    X'03'    {Do not Localize}
                        //               IP V6 address: X'04'    {Do not Localize}
 // host name
 tempBuffer[4] := Length(AHost);
 pos := 5;
 if Length(AHost) > 0 then begin
   Move(AHost[1], tempBuffer[pos], Length(AHost));
 end;
 pos := pos + Length(AHost);
 // port
 tempPort := GStack.WSHToNs(APort);
 Move(tempPort, tempBuffer[pos], SizeOf(tempPort));
 pos := pos + 2;

 FIOHandler.Send(tempBuffer, pos); // send the connection packet
 try
   FIOHandler.Recv(tempBuffer, 5);    // Socks server replies on connect, this is the first part
 except
   raise EIdSocksServerRespondError.Create(RSSocksServerRespondError);
 end;

 case tempBuffer[1] of
   0: ;// success, do nothing
   1: raise EIdSocksServerGeneralError.Create(RSSocksServerGeneralError);
   2: raise EIdSocksServerPermissionError.Create(RSSocksServerPermissionError);
   3: raise EIdSocksServerNetUnreachableError.Create(RSSocksServerNetUnreachableError);
   4: raise EIdSocksServerHostUnreachableError.Create(RSSocksServerHostUnreachableError);
   5: raise EIdSocksServerConnectionRefusedError.Create(RSSocksServerConnectionRefusedError) ;
   6: raise EIdSocksServerTTLExpiredError.Create(RSSocksServerTTLExpiredError);
   7: raise EIdSocksServerCommandError.Create(RSSocksServerCommandError);
   8: raise EIdSocksServerAddressError.Create(RSSocksServerAddressError);
   else
      raise EIdSocksUnknownError.Create(RSSocksUnknownError);
 end;

 // type of destination address is domain name
 case tempBuffer[3] of
   // IP V4
   1: len := 4 + 2; // 4 is for address and 2 is for port length
   // FQDN
   3: len := tempBuffer[4] + 2; // 2 is for port length
   // IP V6
   4: len := 16 + 2; // 16 is for address and 2 is for port length
 end;

 try
   // Socks server replies on connect, this is the seconf part
   FIOHandler.Recv(tempBuffer[5], len-1);
 except
   raise EIdSocksServerRespondError.Create(RSSocksServerRespondError);
 end;
end;


проглядел вроде по идее так же... хз


Slym   (2008-07-08 13:34:00) [20]

вот накатал... но не проверял
function hconnect(s: TSocket; var name: TSockAddr; namelen: Integer):integer;stdcall;
type TConnectProc= function (s: TSocket; var name: TSockAddr; namelen: Integer): Integer; stdcall;
type
 TSocks5AuthReq = packed record
   VER,NMETHODS,METHODS: byte;
 end;
 TSocks5AuthResp = packed record
   VER,METHOD: byte;
 end;
const
 Socks5AuthReqDef:TSocks5AuthReq=(VER:$5;NMETHODS:$1;METHODS:$0);

type
 TSocks5Cmd = packed record
   VER, CMD, RSV, ATYP: byte;
   dIP: in_addr;
   wPort: word;
 end;

var
 s2in:sockaddr_in;
 AuthResp:TSocks5AuthResp;
 Cmd:TSocks5Cmd;
begin
 try
   s2in.sin_family := PF_INET;
   s2in.sin_addr.S_addr:=inet_addr(pchar('127.0.0.1'));
   s2in.sin_port:=htons(31337);

   result:=TConnectProc(rd_c)(s,s2in,SizeOf(s2in));
   if result=SOCKET_ERROR then exit;

   if send(s,(@Socks5AuthReqDef)^,sizeof(Socks5AuthReqDef),0)<>sizeof(Socks5AuthReqDef ) then
     Abort;
   if recv(s,AuthResp,sizeof(AuthResp),0)<>sizeof(AuthResp) then
     Abort;
   if (AuthResp.VER<>$05) or (AuthResp.METHOD=$00) then
     Abort;

   with Cmd do
   begin
     VER:=$05;
     CMD:=$01;
     RSV:=$00;
     ATYP:=$01;
     dIP:=name.sin_addr;
     wPort:=name.sin_port;
   end;

   if send(s,(@Cmd)^,sizeof(Cmd),0)<>sizeof(Cmd) then
     Abort;
   if recv(s,(@Cmd)^,sizeof(Cmd),0)<>sizeof(Cmd) then
     Abort;
   if Cmd.CMD<>0 then
     Abort;

 except
   shutdown(s,SD_BOTH);
   closesocket(s);
   result:=SOCKET_ERROR;
 end;
end;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо