• Welcome to Valhalla Legends Archive.
 

SOCKS4A [Plain English?] HELP!?

Started by NetNX, February 10, 2005, 07:50 PM

Previous topic - Next topic

NetNX

hey everyone... can someone explain to me how to work socks4a because it makes only some sence to me and i wouldnt know how to start coding that :-/

http://archive.socks.permeo.com/protocol/socks4a.protocol

i get that have to send chr(0) & chr(0) & chr(0) & X

im not sure what i should send for X or how to resolve the destination :-/

BaDDBLooD

There are only two kinds of people who are really fascinating: people who know absolutely everything, and people who know absolutely nothing.

OnlyMeat

Quote from: NetNX on February 10, 2005, 07:50 PM
hey everyone... can someone explain to me how to work socks4a because it makes only some sence to me and i wouldnt know how to start coding that :-/

http://archive.socks.permeo.com/protocol/socks4a.protocol

i get that have to send chr(0) & chr(0) & chr(0) & X

im not sure what i should send for X or how to resolve the destination :-/

SOCKS4 is actually quite simple one packet is all that is required.

Here is a proxy client class i wrote for my bots, it might help give you an idea of how it works.


// Socks versions
#define SOCKS_VER_4 0x04
#define SOCKS_VER_5 0x05

// Packet ID's
#define PKT_PROXY_CONNECT 0x01

// Proxy 5 specific
#define PKT_PROXY5_METHODSELECT 0x00
#define PKT_PROXY5_REQUEST_REPLY 0x01

// Proxy 4 specific
#define PKT_PROXY4_REQUEST_REPLY 0x00

// Command results
#define CONNECT_RESULT_OK 0x00
#define CONNECT_PROXY4_RESULT_OK 0x5a
//#define CONNECT_RESULT_FAIL 0x5b
//#define CONNECT_RESULT_IDENTFAIL 0x5c
//#define CONNECT_RESULT_INVALIDIDENT 0x5d

CProxyClient::CProxyClient(void)
{
m_nProxyType = PT_NONE;
Init();
}

CProxyClient::~CProxyClient(void)
{
}

void CProxyClient::Connect(LPCSTR lpServer, UINT nPort)
{
Init();

// Redirect to the proxy server
if ( m_nProxyType != PT_NONE )
{
m_sDestServer = lpServer;
m_nDestPort   = nPort;

CSocketEx::FastConnect(m_sProxy,m_nProxyPort);
}
else
CSocketEx::Connect(lpServer,nPort);
}

// Initiate proxy connection sequence
void CProxyClient::ProxyConnect(LPCSTR lpServer)
{
// Address validation
if ( strlen(lpServer) == 0 || strlen(lpServer) > MAX_SERVER )
{
OnException(E_INVALID_GATEWAY);
return;
}

SetTimeOut(PROXY_CONNECT_TIMEOUT);

// Select proxy protocol
switch ( m_nProxyType )
{
case PT_SOCKS4:
SOCKS4_RequestConnect();
break;
case PT_SOCKS5:
SOCKS5_SelectMethod();
break;
}
}

// Request SOCKS 4 connection
void CProxyClient::SOCKS4_RequestConnect()
{
UINT nAddr = inet_addr(m_sDestServer);

CPacket Packet;

Packet  << (BYTE)SOCKS_VER_4 // SOCKS version number
    << (BYTE)PKT_PROXY_CONNECT // Command
    << (USHORT)htons(m_nDestPort) // Port in network byte order
    << (UINT)nAddr // IP Address
<< (BYTE)0x00;

Packet.Send(GetSocket());
}

// Select SOCKS 5 method
void CProxyClient::SOCKS5_SelectMethod()
{
CPacket Packet;

Packet  << (BYTE)SOCKS_VER_5 // SOCKS version number
<< (BYTE)0x01 // No. Methods
<< (BYTE)0x00; // Methods

Packet.Send(GetSocket());
}

// Override the default event dispatching
void CProxyClient::DispatchEvent(USHORT nEvent)
{
if ( m_nProxyType == PT_NONE )
{
// Do default base class implementation
CSocketEx::DispatchEvent(nEvent);
return;
}

switch ( nEvent )
{
case FD_CONNECT:
ConnectComplete();
ProxyConnect(m_sDestServer);
break;
case FD_READ:
if ( m_bProxyComplete )
OnNetworkRead();
else
OnProxyRead();
break;
default:
// Do default base class implementation
CSocketEx::DispatchEvent(nEvent);
}
}

void CProxyClient::OnProxyRead()
{
int nLen = m_ProxyPktBuf.Read(GetSocket());
DispatchPacket(m_ProxyPktBuf.GetData(), nLen);

// Cleanup
m_ProxyPktBuf.Clear();
}

void CProxyClient::DispatchPacket(char* pszBuf, int nLen)
{
BYTE byResult = *(BYTE*)(pszBuf+0x01);

switch ( m_nProxyType  )
{
case PT_SOCKS4:
switch ( m_nNextOp )
{
case PKT_PROXY4_REQUEST_REPLY:
m_bProxyComplete = TRUE;
OnProxyConnect(((byResult == CONNECT_PROXY4_RESULT_OK)?0x00:byResult));
break;
}
break;
case PT_SOCKS5:

switch ( m_nNextOp )
{
case PKT_PROXY5_METHODSELECT:
OnMethodSelect(byResult);
break;
case PKT_PROXY5_REQUEST_REPLY:
m_bProxyComplete = TRUE;
OnProxyConnect(byResult);
break;
}
}
}

void CProxyClient::OnMethodSelect(BYTE byResult)
{
if ( byResult != CONNECT_RESULT_OK )
{
OnException(E_PROXY_FAILED);
return;
}

UINT nAddr = inet_addr(m_sDestServer);

// Send connect packet
CPacket Packet;

Packet << (BYTE)SOCKS_VER_5 // SOCKS version
   << (BYTE)PKT_PROXY_CONNECT // Command
   << (BYTE)0x00 // Reserved
   << (BYTE)0x01 // ipv4
   << nAddr // IP Address
   << (USHORT)htons(m_nDestPort); // Port in network byte order

Packet.Send(GetSocket());

m_nNextOp++;
}

void CProxyClient::OnProxyConnect(BYTE byResult)
{
if ( byResult != CONNECT_RESULT_OK )
{
OnException(E_PROXY_FAILED);
return;
}

KillTimeOut();
OnConnect();
}

void CProxyClient::Init()
{
m_bProxyComplete = FALSE;
m_nNextOp = 0;
}

shadypalm88

It doesn't seem to me like anyone has answered NetNX's question yet.  He's asking about SOCKS 4A, an extension to SOCKS 4 that allows clients to request the server to resolve an address for them.

OK, so, a normal SOCKS4 CONNECT request looks like this (big-endian (network) byte order):
(BYTE) Version Number (4)
(BYTE) Command (1 for Connect)
(WORD) Destination Port
(DWORD) Destination Address
(STRING) User ID


In SOCKS4A, the Destination Address is set to a special value: an IP address that cannot actually exist, signalling to a compliant server that the client needs it to resolve the address.  You set the destination address to 0.0.0.x, where x is any number greater than 0 (so, for example, 0.0.0.1 will work).

So, a SOCKS 4A connect request is formatted like:
(BYTE) Version Number (4)
(BYTE) Command (1 for Connect)
(WORD) Destination Port
(DWORD) Fake IP (like 0x00000001; 0.0.0.1)
(STRING) User ID
(STRING) Destination Address (like "useast.battle.net" minus the quotes)

NetNX

shady, man you rock :) but i got another question..

Will a normal socks4 server login using 4a protocol? like how should i configure that i get what ur saying but like if i have a list of proxy... how might i work that? like just try socks4 and if it fails do socks4a?

shadypalm88

Quote from: NetNX on February 14, 2005, 08:30 AM
how might i work that? like just try socks4 and if it fails do socks4a?
If your bot already looks up the destination server's hostname (it can do SOCKS4 requests with domain names and not just IP's), there's really not any advantage to using SOCKS4A.

If you want to use 4A, you should try 4A first and then if it fails do normal SOCKS4.

NetNX

well i have all these random port proxys and bugsy seems to think that they wont accept a normal sock4 protocol connection... is this not probable because sometimes i feel like alot of people really dont know what they are talking about...?

and i would send useast.battle.net after the normal information to connect right?