c - SOCKS5 错误 400 Tor

标签 c proxy winsock tor

我正在尝试使用 Winsock 通过 Tor 发出 GET 请求,但似乎有某种错误?当我在一个普通的网站上尝试它时,它会通过并运行。但如果我尝试使用 Tor 网站,它只会返回错误 400。那是因为我需要解析 Tor 主机名等。我该如何在 C 中执行此操作?

这是代码

     #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();
}
}

最佳答案

您必须在 socks 有效负载中指定一个域,我帮助您第二个缓冲区:

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

应该是这样的:

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;

如果您喜欢 Tor 之类的东西并且想成为黑客,请不要使用像 htons 这样的函数,尝试了解如何自己进行简单的字节和位操作

关于c - SOCKS5 错误 400 Tor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44320061/

相关文章:

C API 设计 : what to do when malloc returns NULL?

C pthread,指针丢失内容

Java API : Connect using proxies on different threads

delphi - 一次发送多于 2 行的问题

c - 多播不工作

c - 在 C/Gameboy 编程中使用两个数组

java - 在 HP-UX 环境 JVM 中,C 堆与 Java 堆中运行的是什么?

java - 通过类实现接口(interface)创建基于 CGLib 的代理

linux - 通过HTTP代理的SSH隧道

c - 处理 WSARecv 的立即返回