http://www.cesdn.net/document/show.aspx?sn=00000000000000000001
Penetration proxy server programming
During the network program design, we often have to deal with various types of proxy servers. For example, in the enterprise network through the agent to access the Internet online server, the general proxy server supports several common proxy protocol standards, such as SOCKS4, SOCKS5, HTTP proxy, where SOCKS5 requires user authentication, and the agent is relatively complicated. After reviewing the RFC documentation and related information, I summarize some of the program blocks of TCP protocol penetrating the proxy server, I hope to help everyone.
// Use the structure
Struct Sock4Req1
{
CHAR VN;
CHAR CD;
UNSIGNED SHORT Port;
UNSIGNED Long ipaddr;
Char other [1];
}
Struct sock4ans1
{
CHAR VN;
CHAR CD;
}
Struct Sock5Req1
{
CHAR VER;
Char nmethods;
CHAR Methods [255];
}
Struct Sock5ans1
{
CHAR VER;
CHAR METHOD;
}
Struct Sock5Req2
{
CHAR VER;
CHAR CMD;
CHAR RSV;
CHAR ATYP;
Char other [1];
}
Struct Sock5ans2
{
CHAR VER;
CHAR REP;
CHAR RSV;
CHAR ATYP;
Char other [1];
}
Struct Authreq
{
CHAR VER;
Char ulen;
CHAR Name [255];
CHAR PLEN;
CHAR Pass [255];
}
Struct Authans
{
CHAR VER;
Char status;
}
/ / Agent by SOCKS4 mode
IF (! Clientsock.Connect (g_proxyinfo.m_strproxyip, g_proxyinfo.m_nproxyport))
{
m_Serror = _t ("Cannot connect to the proxy server!");
Clientsock.close ();
Return False;
}
CHAR BUFF [100];
MEMSET (BUFF, 0, 100);
Struct Sock4Req1 * m_ProxyReq;
M_ProxyReq = (struct sock4req1 *) BUFF;
M_ProxyReq-> vn = 4;
M_ProxyReq-> CD = 1;
M_ProxyReq-> Port = NTOHS (GetPort ());
M_ProxyReq-> ipaddr = inet_addr (GetServerHostName ());
Clientsock.send (BUFF, 9);
Struct Sock4ans1 * m_proxyans;
M_Proxyans = (Struct Sock4ans1 *) BUFF;
MEMSET (BUFF, 0, 100);
Clientsock.Receive (BUFF, 100);
IF (m_proxyans-> vn! = 0 || m_proxyans-> cd! = 90)
{
m_Serror = _t ("" Unsecured by the agent connection master! ");
Clientsock.close ();
Return False;
}
// Agent by SOCKS5 mode
IF (! clientsock.connect (g_proxyinfo.m_stroxyip, g_proxyinfo.m_nproxyport)) {
m_Serror = _t ("Cannot connect to the proxy server!");
Clientsock.close ();
Return False;
}
Char buff [600];
Struct Sock5Req1 * m_proxyreq1;
M_ProxyReq1 = (struct sock5req1 *) BUFF;
M_ProxyReq1-> VER = 5;
M_ProxyReq1-> nmethods = 2;
M_ProxyReq1-> Methods [0] = 0;
M_ProxyReq1-> Methods [1] = 2;
Clientsock.send (BUFF, 4);
Struct sock5ans1 * m_proxyans1;
M_Proxyans1 = (Struct Sock5ans1 *) BUFF;
MEMSET (BUFF, 0, 600);
Clientsock.Receive (BUFF, 600);
IF (M_Proxyans1-> Ver! = 5 || (m_Proxyans1-> Method! = 0 && m_Proxyans1-> Method! = 2))
{
m_Serror = _t ("" Unsecured by the agent connection master! ");
Clientsock.close ();
Return False;
}
IF (m_proxyans1-> method == 2)
{
INT NUSERLEN = Strlen (g_proxyinfo.m_strproxyuser);
INT NPASSLEN = Strlen (g_proxyinfo.m_strproxypass);
Struct Authreq * m_authreq;
M_AUTHREQ = (Struct Authreq *) BUFF;
m_authreq-> ver = 1;
m_authreq-> ulen = NUSERLEN;
STRCPY (M_AuThReq-> Name, g_proxyinfo.m_strproxyuser);
m_authreq-> plen = npasslen;
STRCPY (m_authreq-> pass, g_proxyinfo.m_strproxypass);
Clientsock.send (BUFF, 513);
Struct Authans * m_authans;
M_authans = (struct authans *) BUFF;
MEMSET (BUFF, 0, 600);
Clientsock.Receive (BUFF, 600);
IF (M_Authans-> Ver! = 1 || m_authans-> status! = 0)
{
m_Serror = _t ("Proxy server user authentication is not successful!");
Clientsock.close ();
Return False;
}
}
Struct Sock5Req2 * m_ProxyReq2;
M_ProxyReq2 = (Struct Sock5Req2 *) BUFF;
M_ProxyReq2-> VER = 5;
M_ProxyReq2-> cmd = 1;
M_ProxyReq2-> RSV = 0;
M_ProxyReq2-> atyp = 1;
Unsigned long tmplong = inet_addr (getServerHostName ());
Unsigned short port = ntoHs (getPort ()); Memcpy (m_proxyreq2-> other, & tmplong, 4);
Memcpy (M_ProxyReq2-> Other 4, & Port, 2);
Clientsock.send (buff, Sizeof (Struct Sock5Req2) 5;
Struct sock5ans2 * m_proxyans2;
MEMSET (BUFF, 0, 600);
M_Proxyans2 = (struct sock5ans2 *) BUFF;
Clientsock.Receive (BUFF, 600);
IF (M_Proxyans2-> Ver! = 5 || m_proxyans2-> rep! = 0)
{
m_Serror = _t ("" Unsecured by the agent connection master! ");
Clientsock.close ();
Return False;
}
// Agent by http mode
IF (! Clientsock.Connect (g_proxyinfo.m_strproxyip, g_proxyinfo.m_nproxyport))
{
m_Serror = _t ("Cannot connect to the proxy server!");
Clientsock.close ();
Return False;
}
Char buff [600];
Sprintf (BUFF, "% S% S:% D% S", "Connect", GetServerHostName (), getport (), "http / 1.1 / r / nuser-agent: myApp / 0.1 / r / n / R / N ");
Clientsock.send (BUFF, STRLEN (BUFF)); // Send Request
MEMSET (BUFF, 0, 600);
Clientsock.Receive (BUFF, 600);
IF (strstr (BUFF, "HTTP / 1.0 200 Connection Established") == null) // Connection is unsuccessful
{
m_Serror = _t ("" Unsecured by the agent connection master! ");
Clientsock.close ();
Return False;
}
We generally communicate with the proxy server, then send a proxy server to the proxy server (if needed, such as a SOCKS5 agent), then the verification is successful, and then send the destination address and port that needs to be connected to the proxy server. The above code is only used for TCP connections. If you listen to or through the UDP protocol, you can consult document data such as RFC1829.