slesh
12.06.2007, 22:53
На этот раз я выкладываю исходник весьма полезного модуля для работы с sock5 прокси.
Модуль очень маленький и не сильно увеличивает размер проги. т.к. юзает на прямую winsock.
Вот прога - демонстрация возможности модуля.
Короче суть проги:
Обычный телнет, но тока пашуший через socks5 прокси.
Основные характеристики:
1) консольная прога. вес в чистом виде 22,5 кила
2) работа как и с виндовым прокси, тока в параметрах еще указывается IP и порт прокси
3) поддержка DNS в указании адреса. (не прокси сервера)
4) нет авторизации. Но модуль предусматривает работу с авторизацией.
6) зависимость: windows,winsock.
Исходник проги:
program Project1;
{$APPTYPE CONSOLE}
uses
windows,winsock,socksfunc;
var
mysocket:dword;
socks:socks_cfg;
thID:dword;
res:integer;
s:string;
x:integer;
function is_ip(s:string):boolean;
var
x:integer;
begin
result:=true;
for x:=1 to length(s) do
case s[x] of
'0'..'9','.':;
else result:=false;
end;
end;
procedure showhelp;
begin
writeln('SOCKS TELNET');
writeln('(C) SLESH (slesh-2000@yandex.ru) 2007');
writeln('Usage: SST SOCKS_IP SOCKS_PORT REMOTE_IP\REMOTE_HOST REMOTE_PORT');
writeln('Example: SST 127.0.0.1 1080 www.ya.ru 80');
halt;
end;
procedure reads;
var
y:integer;
readbuf:string;
begin
setlength(readbuf,255);
repeat
y:=recv(mysocket,readbuf[1],255,0);
write(copy(readbuf,1,y));
until y<=0;
halt;
end;
begin
s:=paramstr(1);
if s='' then showhelp;
if is_ip(s)=false then
begin
writeln('[-] SOCKS_IP ERROR');
exit;
end;
socks.SOCKS_IP:=s;
s:=paramstr(2);
if s='' then showhelp;
val(s,socks.SOCKS_PORT,x);
if x<>0 then
begin
writeln('[-] SOCKS_PORT ERROR');
exit;
end;
s:=paramstr(3);
if is_ip(s) then socks.REMOTE_IP:=s else socks.REMOTE_HOST:=s;
s:=paramstr(4);
if s='' then showhelp;
val(s,socks.REMOTE_PORT,x);
if x<>0 then
begin
writeln('[-] REMOTE_PORT ERROR');
exit;
end;
write('Connecting...');
res:=SOCKSConnect(socks,mysocket);
if res<>0 then begin
writeln('[-] Error: ',GetSOCKSErrorText(res));
exit;
end;
writeln('[+] Connect OK');
CreateThread(nil, 0, @reads, nil, 0, thID); // установка потока
repeat
readln(s);
s:=s+#13#10;
send(mysocket,s[1],length(s),0);
until 0=1;
end.
Исходник модуля для работы с socks5 (создавался пол года назад. поэтому слугка крив)
Иходник хоть и кривоват (много лишнего)
просто нет времяни переделывать его по новому, но всёже для обычного коннекта его вполне достаточно.
// Модуль для работы с SOCKS5 серверами
// В модуле реализована только одна функция - TCP CONNECT
// Так же поддержка авторизации
// Автор: SLESH (SLESH-2000@yandex.ru ICQ:266-334-734)
// Зависимости: winsock, sysutils
// Использование:
// GetSOCKSErrorText(err:integer):string; - возвращает описание кода ошибки
// SOCKSConnect(socks:socks_cfg; var sock:tsocket):integer; - функция подключения через прокси
// Параметры: Информация для подключения, сокет в который будет записан дискриптор подключения
// Возвращает код. Если 0 - ОК, Иначе ошибка - Описание через GetSOCKSErrorText
// Адрес сервера к которому нужно подключиться через SOCKS5 задается через IP-адрес или Host
// Особенности: нет необходимости создавать сокет, иничиализировать библиотеку сокетов,
// настраивать параметры подключения. Все это делает функция SOCKSConnect. при удачном
// выполнении этой функции переменная sock будет содержать дискриптор подключения.
// который можно будет использовать в функциях send и recv
unit SocksFunc;
interface
uses windows,winsock;
type
tsocks_query_method=record
VER,LEN,MTD:byte;
end;
tsocks_reply_method=record
VER,MTD:byte;
end;
tsocks_query=record
VER,CMD,RSV,ATYP:byte;
data:array[0..257] of byte;
end;
tsocks_reply=record
VER,REP,RSV,ATYP:byte;
data:array[0..257] of byte;
end;
socks_cfg=record
SOCKS_IP:string;
SOCKS_PORT:word;
SOCKS_LOGIN:string;
SOCKS_PASS:string;
REMOTE_IP:string;
REMOTE_HOST:string;
REMOTE_PORT:word;
end;
function GetSOCKSErrorText(err:integer):string;
function SOCKSConnect(socks:socks_cfg; var sock:thandle):integer;
var
WSData:TWSAData;
implementation
function strtoint(s:string):integer;
var
i:integer;
begin
val(s,i,i);
result:=i;
end;
function GetSOCKSErrorText(err:integer):string;
begin
case err of
$1:result:='SOCKS-server error';
$2:result:='Connect forbidden';
$3:result:='Network is not accessible';
$4:result:='Host is not accessible';
$5:result:='Refusal in connection';
$6:result:='TTL timeout';
$7:result:='Command not support';
$8:result:='Address type not support';
-1,$9..$FF:result:='Unknown error';
-2:result:='Socks-server RFC error';
-3:result:='Socks-server requires authorized';
-4:result:='Login or Password incorrect';
-5:result:='Connect to SOCKS-proxy error';
-6:result:='Create socket error';
end;
end;
function SOCKSConnect(socks:socks_cfg; var sock:thandle):integer;
var
sqm:tsocks_query_method;
srm:tsocks_reply_method;
sq:tsocks_query;
sr:tsocks_reply;
sp:array[0..512] of char;
s:string;
auth:boolean;
x:integer;
ca:sockaddr_in;
begin
sock:=socket(AF_INET, SOCK_STREAM, 0);
if sock=windows.ERROR_INVALID_HANDLE then begin
result:=-6;
exit;
end;
ca.sin_family:=AF_INET;
ca.sin_port:=htons(socks.SOCKS_PORT);
ca.sin_addr.s_addr:=inet_addr(Pansichar(socks.SOCK S_IP));
if connect(sock,ca,sizeof(ca))=-1 then begin
result:=-5;
closesocket(sock);
exit;
end;
if (socks.SOCKS_LOGIN<>'') and (socks.SOCKS_PASS<>'') then auth:=true else auth:=false;
result:=-1;
sqm.VER:=$05;
sqm.LEN:=$01;
if auth=true then sqm.MTD:=$2 else sqm.MTD:=$00;
send(sock,sqm,3,0);
recv(sock,srm,2,0);
if srm.VER<>$05 then
begin
result:=-2;
exit;
end;
if auth=true then
begin
if srm.MTD<>$2 then
begin
result:=-3;
exit;
end;
end else
begin
if srm.MTD<>$0 then
begin
result:=-3;
exit;
end;
end;
if auth=true then
begin
s:=#01+chr(length(socks.SOCKS_LOGIN))+socks.SOCKS_ LOGIN+chr(length(socks.SOCKS_PASS))+socks.SOCKS_PA SS;
for x:=0 to length(s)-1 do sp[x]:=s[x+1];
send(sock,sp,length(s),0);
recv(sock,srm,sizeof(srm),0);
if srm.VER<>$01 then
begin
result:=-2;
exit;
end;
if srm.MTD<>00 then
begin
result:=-4;
exit;
end;
end;
sq.VER:=$05;
sq.CMD:=$01;
sq.RSV:=$00;
if socks.REMOTE_IP<>'' then begin
sq.ATYP:=$01;
s:=socks.REMOTE_IP;
sq.data[0]:=strtoint(copy(s,1,pos('.',s)-1));
delete(s,1,pos('.',s));
sq.data[1]:=strtoint(copy(s,1,pos('.',s)-1));
delete(s,1,pos('.',s));
sq.data[2]:=strtoint(copy(s,1,pos('.',s)-1));
delete(s,1,pos('.',s));
sq.data[3]:=strtoint(s);
sq.data[4]:=socks.REMOTE_PORT div 256;
sq.data[5]:=socks.REMOTE_PORT-sq.data[4]*256;
send(sock,sq,10,0);
end;
if socks.REMOTE_HOST<>'' then begin
sq.ATYP:=$03;
sq.data[0]:=length(socks.REMOTE_HOST);
for x:=1 to length(socks.REMOTE_HOST) do sq.data[x]:=ord(socks.REMOTE_HOST[x]);
sq.data[length(socks.REMOTE_HOST)+1]:=socks.REMOTE_PORT div 256;
sq.data[length(socks.REMOTE_HOST)+2]:=socks.REMOTE_PORT-sq.data[length(socks.REMOTE_HOST)+1]*256;
send(sock,sq,4+length(socks.REMOTE_HOST)+1+2,0);
end;
recv(sock,sr,sizeof(sr),0);
if sr.VER<>$05 then
begin
result:=-2;
exit;
end;
result:=sr.REP;
end;
begin
if WSAStartup($202, WSData)=-1 then begin
writeln('[-] Error: WSAStartup');
exit;
end;
end.
Модуль очень маленький и не сильно увеличивает размер проги. т.к. юзает на прямую winsock.
Вот прога - демонстрация возможности модуля.
Короче суть проги:
Обычный телнет, но тока пашуший через socks5 прокси.
Основные характеристики:
1) консольная прога. вес в чистом виде 22,5 кила
2) работа как и с виндовым прокси, тока в параметрах еще указывается IP и порт прокси
3) поддержка DNS в указании адреса. (не прокси сервера)
4) нет авторизации. Но модуль предусматривает работу с авторизацией.
6) зависимость: windows,winsock.
Исходник проги:
program Project1;
{$APPTYPE CONSOLE}
uses
windows,winsock,socksfunc;
var
mysocket:dword;
socks:socks_cfg;
thID:dword;
res:integer;
s:string;
x:integer;
function is_ip(s:string):boolean;
var
x:integer;
begin
result:=true;
for x:=1 to length(s) do
case s[x] of
'0'..'9','.':;
else result:=false;
end;
end;
procedure showhelp;
begin
writeln('SOCKS TELNET');
writeln('(C) SLESH (slesh-2000@yandex.ru) 2007');
writeln('Usage: SST SOCKS_IP SOCKS_PORT REMOTE_IP\REMOTE_HOST REMOTE_PORT');
writeln('Example: SST 127.0.0.1 1080 www.ya.ru 80');
halt;
end;
procedure reads;
var
y:integer;
readbuf:string;
begin
setlength(readbuf,255);
repeat
y:=recv(mysocket,readbuf[1],255,0);
write(copy(readbuf,1,y));
until y<=0;
halt;
end;
begin
s:=paramstr(1);
if s='' then showhelp;
if is_ip(s)=false then
begin
writeln('[-] SOCKS_IP ERROR');
exit;
end;
socks.SOCKS_IP:=s;
s:=paramstr(2);
if s='' then showhelp;
val(s,socks.SOCKS_PORT,x);
if x<>0 then
begin
writeln('[-] SOCKS_PORT ERROR');
exit;
end;
s:=paramstr(3);
if is_ip(s) then socks.REMOTE_IP:=s else socks.REMOTE_HOST:=s;
s:=paramstr(4);
if s='' then showhelp;
val(s,socks.REMOTE_PORT,x);
if x<>0 then
begin
writeln('[-] REMOTE_PORT ERROR');
exit;
end;
write('Connecting...');
res:=SOCKSConnect(socks,mysocket);
if res<>0 then begin
writeln('[-] Error: ',GetSOCKSErrorText(res));
exit;
end;
writeln('[+] Connect OK');
CreateThread(nil, 0, @reads, nil, 0, thID); // установка потока
repeat
readln(s);
s:=s+#13#10;
send(mysocket,s[1],length(s),0);
until 0=1;
end.
Исходник модуля для работы с socks5 (создавался пол года назад. поэтому слугка крив)
Иходник хоть и кривоват (много лишнего)
просто нет времяни переделывать его по новому, но всёже для обычного коннекта его вполне достаточно.
// Модуль для работы с SOCKS5 серверами
// В модуле реализована только одна функция - TCP CONNECT
// Так же поддержка авторизации
// Автор: SLESH (SLESH-2000@yandex.ru ICQ:266-334-734)
// Зависимости: winsock, sysutils
// Использование:
// GetSOCKSErrorText(err:integer):string; - возвращает описание кода ошибки
// SOCKSConnect(socks:socks_cfg; var sock:tsocket):integer; - функция подключения через прокси
// Параметры: Информация для подключения, сокет в который будет записан дискриптор подключения
// Возвращает код. Если 0 - ОК, Иначе ошибка - Описание через GetSOCKSErrorText
// Адрес сервера к которому нужно подключиться через SOCKS5 задается через IP-адрес или Host
// Особенности: нет необходимости создавать сокет, иничиализировать библиотеку сокетов,
// настраивать параметры подключения. Все это делает функция SOCKSConnect. при удачном
// выполнении этой функции переменная sock будет содержать дискриптор подключения.
// который можно будет использовать в функциях send и recv
unit SocksFunc;
interface
uses windows,winsock;
type
tsocks_query_method=record
VER,LEN,MTD:byte;
end;
tsocks_reply_method=record
VER,MTD:byte;
end;
tsocks_query=record
VER,CMD,RSV,ATYP:byte;
data:array[0..257] of byte;
end;
tsocks_reply=record
VER,REP,RSV,ATYP:byte;
data:array[0..257] of byte;
end;
socks_cfg=record
SOCKS_IP:string;
SOCKS_PORT:word;
SOCKS_LOGIN:string;
SOCKS_PASS:string;
REMOTE_IP:string;
REMOTE_HOST:string;
REMOTE_PORT:word;
end;
function GetSOCKSErrorText(err:integer):string;
function SOCKSConnect(socks:socks_cfg; var sock:thandle):integer;
var
WSData:TWSAData;
implementation
function strtoint(s:string):integer;
var
i:integer;
begin
val(s,i,i);
result:=i;
end;
function GetSOCKSErrorText(err:integer):string;
begin
case err of
$1:result:='SOCKS-server error';
$2:result:='Connect forbidden';
$3:result:='Network is not accessible';
$4:result:='Host is not accessible';
$5:result:='Refusal in connection';
$6:result:='TTL timeout';
$7:result:='Command not support';
$8:result:='Address type not support';
-1,$9..$FF:result:='Unknown error';
-2:result:='Socks-server RFC error';
-3:result:='Socks-server requires authorized';
-4:result:='Login or Password incorrect';
-5:result:='Connect to SOCKS-proxy error';
-6:result:='Create socket error';
end;
end;
function SOCKSConnect(socks:socks_cfg; var sock:thandle):integer;
var
sqm:tsocks_query_method;
srm:tsocks_reply_method;
sq:tsocks_query;
sr:tsocks_reply;
sp:array[0..512] of char;
s:string;
auth:boolean;
x:integer;
ca:sockaddr_in;
begin
sock:=socket(AF_INET, SOCK_STREAM, 0);
if sock=windows.ERROR_INVALID_HANDLE then begin
result:=-6;
exit;
end;
ca.sin_family:=AF_INET;
ca.sin_port:=htons(socks.SOCKS_PORT);
ca.sin_addr.s_addr:=inet_addr(Pansichar(socks.SOCK S_IP));
if connect(sock,ca,sizeof(ca))=-1 then begin
result:=-5;
closesocket(sock);
exit;
end;
if (socks.SOCKS_LOGIN<>'') and (socks.SOCKS_PASS<>'') then auth:=true else auth:=false;
result:=-1;
sqm.VER:=$05;
sqm.LEN:=$01;
if auth=true then sqm.MTD:=$2 else sqm.MTD:=$00;
send(sock,sqm,3,0);
recv(sock,srm,2,0);
if srm.VER<>$05 then
begin
result:=-2;
exit;
end;
if auth=true then
begin
if srm.MTD<>$2 then
begin
result:=-3;
exit;
end;
end else
begin
if srm.MTD<>$0 then
begin
result:=-3;
exit;
end;
end;
if auth=true then
begin
s:=#01+chr(length(socks.SOCKS_LOGIN))+socks.SOCKS_ LOGIN+chr(length(socks.SOCKS_PASS))+socks.SOCKS_PA SS;
for x:=0 to length(s)-1 do sp[x]:=s[x+1];
send(sock,sp,length(s),0);
recv(sock,srm,sizeof(srm),0);
if srm.VER<>$01 then
begin
result:=-2;
exit;
end;
if srm.MTD<>00 then
begin
result:=-4;
exit;
end;
end;
sq.VER:=$05;
sq.CMD:=$01;
sq.RSV:=$00;
if socks.REMOTE_IP<>'' then begin
sq.ATYP:=$01;
s:=socks.REMOTE_IP;
sq.data[0]:=strtoint(copy(s,1,pos('.',s)-1));
delete(s,1,pos('.',s));
sq.data[1]:=strtoint(copy(s,1,pos('.',s)-1));
delete(s,1,pos('.',s));
sq.data[2]:=strtoint(copy(s,1,pos('.',s)-1));
delete(s,1,pos('.',s));
sq.data[3]:=strtoint(s);
sq.data[4]:=socks.REMOTE_PORT div 256;
sq.data[5]:=socks.REMOTE_PORT-sq.data[4]*256;
send(sock,sq,10,0);
end;
if socks.REMOTE_HOST<>'' then begin
sq.ATYP:=$03;
sq.data[0]:=length(socks.REMOTE_HOST);
for x:=1 to length(socks.REMOTE_HOST) do sq.data[x]:=ord(socks.REMOTE_HOST[x]);
sq.data[length(socks.REMOTE_HOST)+1]:=socks.REMOTE_PORT div 256;
sq.data[length(socks.REMOTE_HOST)+2]:=socks.REMOTE_PORT-sq.data[length(socks.REMOTE_HOST)+1]*256;
send(sock,sq,4+length(socks.REMOTE_HOST)+1+2,0);
end;
recv(sock,sr,sizeof(sr),0);
if sr.VER<>$05 then
begin
result:=-2;
exit;
end;
result:=sr.REP;
end;
begin
if WSAStartup($202, WSData)=-1 then begin
writeln('[-] Error: WSAStartup');
exit;
end;
end.