initial commit
This commit is contained in:
Executable
+326
@@ -0,0 +1,326 @@
|
||||
|
||||
// CLIENT_SK5_V2
|
||||
|
||||
std::string hex_string(std::string hexstr)
|
||||
{
|
||||
std::string str = "";
|
||||
str.resize((hexstr.size() + 1) / 2);
|
||||
for (size_t i = 0, j = 0; i < str.size(); i++, j++)
|
||||
{
|
||||
char at = '@';
|
||||
str[i] = (hexstr[j] & at ? hexstr[j] + 9 : hexstr[j]) << 4, j++;
|
||||
str[i] |= (hexstr[j] & at ? hexstr[j] + 9 : hexstr[j]) & 0xF;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string string_hex(std::string str, const bool capital = false)
|
||||
{
|
||||
std::string hexstr = "";
|
||||
hexstr.resize(str.size() * 2);
|
||||
static const char a = capital ? 0x40 : 0x60;
|
||||
for (size_t i = 0; i < str.size(); i++)
|
||||
{
|
||||
char c = (str[i] >> 4) & 0xF;
|
||||
hexstr[i * 2] = c > 9 ? (c - 9) | a : c | '0';
|
||||
hexstr[i * 2 + 1] = (str[i] & 0xF) > 9 ? (str[i] - 9) & 0xF | a : str[i] & 0xF | '0';
|
||||
}
|
||||
return hexstr;
|
||||
}
|
||||
|
||||
std::string char_to_string(char x[], int size_recv)
|
||||
{
|
||||
int num_car = 0;
|
||||
int stop_while = size_recv;
|
||||
std::string output = "";
|
||||
|
||||
while (stop_while > 0)
|
||||
{
|
||||
output += x[num_car];
|
||||
if (num_car < size_recv) { num_car++; }
|
||||
|
||||
stop_while--;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
long int hex_to_dec(std::string x)
|
||||
{
|
||||
return strtol(x.data(), NULL, 16);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SOCKET x;
|
||||
SOCKET y;
|
||||
BOOL VERBOSE_mode;
|
||||
int timeout_sec;
|
||||
int buf_size;
|
||||
} threaddata;
|
||||
|
||||
void set_fds(int sock1, int sock2, fd_set* fds) {
|
||||
FD_ZERO(fds);
|
||||
FD_SET(sock1, fds);
|
||||
FD_SET(sock2, fds);
|
||||
}
|
||||
|
||||
// MSG SOCKS5
|
||||
char msg_auth_ok[] = { 0X05, 0X00 }; // VERSION SOCKS, AUTH MODE, OK
|
||||
char msg_ipv6_nok[] = { 0X05, 0X08, 0X00, 0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00 }; // IPv6 not compt
|
||||
char msg_request_co_ok[] = { 0X05, 0X00, 0X00, 0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00 }; // Request connect OK
|
||||
|
||||
DWORD WINAPI sock5_gen(void* param)
|
||||
{
|
||||
threaddata* sub = (threaddata*)param;
|
||||
|
||||
SOCKET sock_SK5 = sub->x;
|
||||
BOOL VERBOSE_mode = sub->VERBOSE_mode;
|
||||
int timeout_sec = sub->timeout_sec;
|
||||
int buf_size = sub->buf_size;
|
||||
|
||||
char buf[5016]; // If changed, line 25 in main.cpp is a change too
|
||||
int version_sock = 0; // 5, 4, 0, ??
|
||||
|
||||
// Phase A = Version Socks, Send Msg Auth
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
// Get Version Socks
|
||||
int size_recv_PA = recv(sock_SK5, buf, sizeof(buf), 0);
|
||||
|
||||
if (size_recv_PA <= 0)
|
||||
{
|
||||
printf(EC("[!] size_recv_PA <= 0\n"));
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
version_sock = buf[0];
|
||||
if (version_sock != 5)
|
||||
{
|
||||
printf(EC("[!] version_sock != 5\n"));
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Send msg_auth_ok
|
||||
|
||||
int size_send_PA = send(sock_SK5, msg_auth_ok, sizeof(msg_auth_ok), 0);
|
||||
|
||||
if (size_send_PA <= 0)
|
||||
{
|
||||
printf(EC("[!] size_send_PA <= 0\n"));
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Phase B = Mode Connect & Type Addr & Addr/Port
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
int size_recv_PB = recv(sock_SK5, buf, sizeof(buf), 0);
|
||||
|
||||
if (size_recv_PB <= 0)
|
||||
{
|
||||
printf(EC("[!] size_recv_PB <= 0\n"));
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int mode_cmd = buf[1]; // Connect = 1, Bind = 2, UDP = 3
|
||||
int type_addr = buf[3]; // IPv4 = 01, Domain Name = 03, IPv6 = 04
|
||||
|
||||
if (mode_cmd != 1)
|
||||
{
|
||||
printf(EC("[!] Bind/UDP not supported\n"));
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string dest_ip = ""; // IP dest
|
||||
int dest_port = 0; // Port dest
|
||||
|
||||
if (type_addr == 1) // IPv4
|
||||
{
|
||||
std::string raw_demand = char_to_string(buf, size_recv_PB); // convert to string
|
||||
std::string str_ip_dest = raw_demand.substr(4, 11); // get IPv4
|
||||
std::string str_port_dest = raw_demand.substr(8, 10); // get Port
|
||||
|
||||
sockaddr_in svr = { 0 };
|
||||
svr.sin_family = AF_INET;
|
||||
svr.sin_addr.s_addr = MAKELONG(MAKEWORD((buf[4] & 0xff), (buf[5] & 0xff)), MAKEWORD((buf[6] & 0xff), (buf[7] & 0xff)));
|
||||
|
||||
dest_ip = inet_ntoa(svr.sin_addr); // IPv4 dest in string
|
||||
dest_port = hex_to_dec(string_hex(str_port_dest)); // port dest in long
|
||||
}
|
||||
|
||||
if (type_addr == 3) // Domain Name
|
||||
{
|
||||
std::string raw_demand = char_to_string(buf, size_recv_PB); // convert to string
|
||||
int size_domain_name = buf[4]; // Get size Domain Name
|
||||
std::string str_domain_name;
|
||||
std::string str_port_dest;
|
||||
|
||||
try
|
||||
{
|
||||
str_domain_name = raw_demand.substr(5, size_domain_name); // get domain_name
|
||||
str_port_dest = raw_demand.substr(5 + size_domain_name, 5 + size_domain_name + 2); // get Port
|
||||
dest_port = hex_to_dec(string_hex(str_port_dest)); // port dest in long
|
||||
}
|
||||
catch (const std::out_of_range& e)
|
||||
{
|
||||
printf(EC("[!] Out of Range\n"));
|
||||
}
|
||||
|
||||
struct hostent* he_a;
|
||||
he_a = gethostbyname(str_domain_name.c_str());
|
||||
if (he_a == NULL) // Error gethostbyname
|
||||
{
|
||||
printf(EC("[!] gethostbyname\n"));
|
||||
closesocket(sock_SK5);
|
||||
return 12;
|
||||
}
|
||||
else // Ok gethostbyname
|
||||
{
|
||||
dest_ip = inet_ntoa(*((struct in_addr*)he_a->h_addr_list[0]));
|
||||
}
|
||||
}
|
||||
|
||||
if (type_addr == 4) // IPv6
|
||||
{
|
||||
printf(EC("[!] IPv6 not supported\n"));
|
||||
|
||||
int size_send_IPNOK = send(sock_SK5, msg_ipv6_nok, sizeof(msg_ipv6_nok), 0);
|
||||
|
||||
if (size_send_IPNOK <= 0) // Send msg_ipv6_nok
|
||||
{
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Phase C = Send Request Addr OK & Recv Request & Connect to TARGET SERVER
|
||||
int size_send_PC = send(sock_SK5, msg_request_co_ok, sizeof(msg_request_co_ok), 0);
|
||||
|
||||
if (size_send_PC <= 0) // Send msg_request_co_ok
|
||||
{
|
||||
printf(EC("[!] size_send_PC <= 0\n"));
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
int size_recv_PC = recv(sock_SK5, buf, sizeof(buf), 0);
|
||||
|
||||
if (size_recv_PC <= 0)
|
||||
{
|
||||
printf(EC("[!] size_recv_PC <= 0\n"));
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
SOCKET client_TARGET; // Socket Connection for TARGET
|
||||
struct sockaddr_in serveraddra_a;
|
||||
|
||||
if ((client_TARGET = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) //open socket
|
||||
printf(EC("[!] socket() failed\n"));
|
||||
|
||||
//connect
|
||||
memset(&serveraddra_a, 0, sizeof(serveraddra_a));
|
||||
serveraddra_a.sin_family = AF_INET;
|
||||
serveraddra_a.sin_addr.s_addr = inet_addr(dest_ip.c_str());
|
||||
serveraddra_a.sin_port = htons((unsigned short)dest_port);
|
||||
|
||||
if (connect(client_TARGET, (struct sockaddr*)&serveraddra_a, sizeof(serveraddra_a)) == SOCKET_ERROR)
|
||||
{
|
||||
printf(EC("[!] connect() failed\n"));
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (send(client_TARGET, buf, size_recv_PC, 0) != size_recv_PC)
|
||||
printf(EC("[!] send() sent a different number of bytes than expected\n"));
|
||||
|
||||
fd_set readfds;
|
||||
int result, nfds = max(sock_SK5, client_TARGET) + 1;
|
||||
set_fds(sock_SK5, client_TARGET, &readfds);
|
||||
|
||||
// Set timeout for select
|
||||
timeval tv;
|
||||
tv.tv_sec = timeout_sec;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
while (TRUE) // SK5_BASE <-> SERVER_TARGET
|
||||
{
|
||||
if ((result = select(nfds, &readfds, 0, 0, &tv)) > 0)
|
||||
{
|
||||
if (FD_ISSET(sock_SK5, &readfds)) // SK5_BASE -> SERVER_TARGET
|
||||
{
|
||||
int recvd_A = 0;
|
||||
|
||||
recvd_A = recv(sock_SK5, buf, buf_size, 0);
|
||||
|
||||
if (recvd_A <= 0)
|
||||
{
|
||||
printf(EC("[!] recvd_A (%i) <= 0\n"), recvd_A);
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sendd_A = 0;
|
||||
send(client_TARGET, buf, recvd_A, 0); // SERVER_TARGET
|
||||
|
||||
if (VERBOSE_mode) printf(EC("[+] A DATA RECV = %i | DATA SEND = %i\n"), recvd_A, sendd_A);
|
||||
}
|
||||
|
||||
if (FD_ISSET(client_TARGET, &readfds)) // SERVER_TARGET -> SK5_BASE
|
||||
{
|
||||
int recvd_B = recv(client_TARGET, buf, buf_size, 0);
|
||||
if (recvd_B <= 0)
|
||||
{
|
||||
printf(EC("[!] recvd_B (%i) <= 0\n"), recvd_B);
|
||||
closesocket(sock_SK5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sendd_B = 0;
|
||||
|
||||
sendd_B = send(sock_SK5, buf, recvd_B, 0);
|
||||
|
||||
if (VERBOSE_mode) printf(EC("[+] B DATA RECV = %i | DATA SEND = %i\n"), recvd_B, sendd_B);
|
||||
}
|
||||
set_fds(sock_SK5, client_TARGET, &readfds);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(EC("[!] select > 0\n"));
|
||||
shutdown(client_TARGET, 2);
|
||||
closesocket(client_TARGET);
|
||||
closesocket(sock_SK5);
|
||||
|
||||
return 12;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
shutdown(client_TARGET, 2);
|
||||
closesocket(client_TARGET);
|
||||
closesocket(sock_SK5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create_sock_thread(void* s)
|
||||
{
|
||||
HANDLE handle;
|
||||
|
||||
if (!(handle = CreateThread(NULL, 0, sock5_gen, s, 0, 0)))
|
||||
return 0;
|
||||
|
||||
CloseHandle(handle);
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user