![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Socks5 клиент, как состряпать запрос ? [D7, Win2k, WinXP]
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;