Search code examples
cproxywinsocktor

SOCKS5 Error 400 Tor


I am trying to make a GET request through tor using winsock but it seems to have some sort of an error? When I try it with a normal website it goes through and works. But if I try it with a tor website it simply comes back with error 400. That is because i need to resolve the tor hostname or etc. How would i do this in C?

here is the code

     #ifndef MAX_PATHZZ
    #define MAX_PATHZZ 256
   #endif
    #define WINDOWS_USER

   #ifndef INVALID_SOCKET
   #define INVALID_SOCKET (-1)
    #endif



int main(int argc, char *argv[])
{
int sock;
int irecv;
char brecv[MAX_PATHZZ];
char header[MAX_PATHZZ * 2];
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) == 0)
{


    if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)
    {
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(9050);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");

        printf("\nAddress = %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));


        if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
        {
            char buff[] =
            {
                0x05,  
                0x01,  
                0x00   
            };


            send(sock, buff, sizeof(buff), 0);
            printf("Sended (%d) = ", sizeof(buff));
            print_hex(buff, sizeof(buff));


            irecv = recv(sock, brecv, MAX_PATHZZ, 0);
            if (irecv > 0)
            {
                printf("Receved data(%d): ", irecv);
                print_hex(brecv, irecv);



                if (brecv[0] != 0x05) { 
                    printf("Invalid server SOCKS version!\n");
                    goto connection_end;
                }

                if (brecv[1] == 0x02) {
                    printf("Auth is needed!!!\n");
                    goto connection_end;
                }
                if (brecv[1] == 0x00)
                {
                    printf("Connection made :P \n");

                    char buff_step_two[MAX_PATHZZ] =
                    {
                        0x05,    
                        0x01,    
                        0x00,    
                        0x01    
                    };

                    printf("\nSend data step two...\n");
                    struct hostent *st_hostent;
                    struct sockaddr_in addr;
                    struct hostent *host;
                    host = gethostbyname("www.google.com");
                    addr.sin_port = htons(80);
                    addr.sin_addr.s_addr = *((unsigned long*)host->h_addr);

                    memcpy(buff_step_two + 4, &addr.sin_addr.s_addr, 4);
                    memcpy(buff_step_two + 8, &addr.sin_port, 2);

                    send(sock, buff_step_two, 10, 0);

                    memset(brecv, '\0', MAX_PATHZZ);
                    irecv = recv(sock, brecv, 10, 0);
                    if (irecv > 0)
                    {

                        printf("Receved data(%d): ", irecv);
                        print_hex(brecv, irecv);
                        sprintf(header, "GET / HTTP/1.1\r\n"
                            "Host: google.com\r\n\r\n");

                        printf("\nHeader...\n%s\n", header);
                        send(sock, header, strlen(header), 0);
                        RtlSecureZeroMemory(brecv, sizeof(brecv));



                            while (recv(sock, brecv, MAX_PATHZZ, 0) > 0){
                                printf("out...\n%s\n", brecv);

                        }

                    }

                    goto connection_end;
                }
            }
        }

    connection_end:

        closesocket(sock);

    }
    WSACleanup();
}
}

Solution

  • You must specify a domain in a socks payload, i help you second buffer:

    char buff_step_two[MAX_PATHZZ] =
                        {
                            0x05,    
                            0x01,    
                            0x00,    
                            0x01    
                        };
    

    should be like this:

    char onion_domain[] = "lol24235235.onion";
    short port = 80; // might be 443 also
    
    int onion_len = strlen(onion_domain);
    
    char buff_step_two[MAX_PATHZZ] = { 0x05,0x01,0x00,0x03 };
    int n = 4;
    buff_step_two[n] = strlen(onion_domain);
    memcpy(buff_step_two+n,onion_len,onion_domain);
    n += onion_len;
    
    buff_step_two[n] = (port & 0xFF);
    n++;
    buff_step_two[n] = (port >> 8) & 0xFF;
    

    And don use functions like htons if you are into tor and that sort of stuff and want to become, hacker try understand how to do simple byte and bit manimulatino by yourself