C++ HTTP over SOCKS5 (TOR) 400 Bad Request -


i have working c++ code getting html source of specific website. 1 function creates http request , other functions send it.

but when try access website same way, except tor (socks5), i'm getting http 400 bad request response. request identical both times, , can see correct via wiresahrk/debugging.

it seems tor may messing up, other tools need send http/https requests on tor seem work correctly.

here snippets of code:

main

int main(int argc, const char * argv[]) {  bool use_tor = false;  if(argc < 3){      std::cout << "[!] please supply url , 0 no tor or 1 tor." << std::endl;      return -1;  }  if(strcmp(argv[2],"1")==0){      use_tor = true;  }          int sock = createsocket();          if(use_tor){              socks5_greeting_response socks_gresp;             socks5_command_response socks_cresp;              socketconnect(sock, "127.0.0.1", 9050);              socks_gresp = socketwritesocks5greeting_tor(sock);              if(socks_gresp.version != 5){                  std::cout << std::endl << "[!] socks5 version mismatch!" << std::endl;                  closesocket(sock);                  return -1;              }              socks_cresp = socks5_connect(sock, get_ipv4(argv[1]), 80);              if(socks_cresp.reply != 0){                  std::cout << std::endl << "[!] socks5 connection failed!" << std::endl;                  closesocket(sock);                  return -1;              }          }         else{              socketconnect(sock, argv[1], 80);          }          socketwrite(sock, generate_basic_get_request("url","ua",""));          socketread(sock)          closesocket(sock); } 

http stuff

std::string generate_basic_get_request(std::string url, std::string ua, std::string cookie){  splitted_host info = parse_host(url);  std::string request;  request = "get " + info.get + " http/1.1\r\n"; request = request + "host: " + info.host + "\r\n"; request = request + "user-agent: " + ua + "\r\n"; request = request + "accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"; request = request + "accept-language: en-us;q=0.7,en;q=0.3\r\n";  if(cookie != ""){     request = request + "cookie: " + cookie + "\r\n"; }  request = request + "connection: close\r\n\r\n";  std::cout << std::endl << request << "----end-----" << std::endl << std::endl;  return request;  } 

this output of code:

get / http/1.1 host: www.host.de user-agent: ua accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 accept-language: en-us;q=0.7,en;q=0.3 connection: close  ----end-----  <!doctype html public "-//ietf//dtd html 2.0//en"> <html><head> <title>400 bad request</title> </head><body> <h1>bad request</h1> <p>your browser sent request server not understand.<br /> </p> </body></html> 

here picture of request in wireshark:

wireshark snapshot of http request

as sayed, same functions, without socks5 proxy, can html source should work.

some news on this:

i'll post socks5 code below, first things first.

i setup portforwarding , connected myself, listening on 'ncat -vvl 80' , able receive send header either or without socks5 proxy. header looked correct, should fine.

now know can connect socks5 proxy; proxy connects desired website , sends data. thats not problem. header arrives should be, have no idea why 400 bad request error happens. since same header working direct connection, , proxy not problem, error shouldn't happening.

the same error happens when using of free socks5 proxies public lists can find on google. must socks5 code.

but happening, must wrong. hope can find it!

here code (and yes it's not perfect , not best way of implementation):

struct socks5_greeting{  unsigned char version; unsigned char numberofmethods; unsigned char methods[256];  };  struct socks5_greeting_response{  unsigned char version; unsigned char method;  };  struct socks5_command{  unsigned char version; unsigned char cmd; unsigned char reserved = 0x00; unsigned char addrtype; union{     in_addr_t ipv4; } destaddr; unsigned short destport;  };  struct socks5_command_response{  unsigned char version; unsigned char reply; unsigned char reserved = 0x00; unsigned char addrtype; union{     in_addr_t ipv4; } bindaddr; unsigned short bindport;  };  socks5_greeting_response socketwritesocks5greeting_tor(int sock){  socks5_greeting req; socks5_greeting_response resp;  req.version = 5; req.numberofmethods = 1; req.methods[0] = 0x00; //no auth  send(sock, &req, 2+req.numberofmethods, 0);  recv(sock, &resp, sizeof(resp), 0);  return resp;  }  socks5_command_response socks5_connect(int sock, std::string dest_str, unsigned short port){  socks5_command req; socks5_command_response resp;  in_addr_t dest = inet_addr(dest_str.c_str());  req.version = 5; req.cmd = 1; req.addrtype = 1; req.destaddr.ipv4 = dest; req.destport = htons(port);  send(sock, &req, sizeof(req), 0);  recv(sock, &resp, sizeof(resp), 0);  return resp;  }  int createsocket(){  int sockfd = socket(af_inet, sock_stream, 0);  return sockfd;  }  void closesocket(int sock){  close(sock);  }  int socketconnect(int sock, const char *address, int port){  struct hostent *server; struct sockaddr_in serv_addr;  server = gethostbyname(address);  if(server == null){     return -1; }  bzero((char *) &serv_addr, sizeof(serv_addr));  serv_addr.sin_family = af_inet;  bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);  serv_addr.sin_port = htons(port);  if(connect(sock,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){     return -1; } else{     return 0; }  }  int socketwrite(int sock, std::string data){  char buffer[512];  int error;  std::string chunk;  if(data.length() > 511){      while(data.length() > 0){          if(data.length() >= 511){              chunk = data.substr(0, 511);              data = data.substr(511, data.length());          }         else{              chunk = data;              data = "";          }          bzero(buffer, 512);          chunk.copy(buffer, chunk.length());          error = write(sock, buffer, strlen(buffer));          if(error < 0){             return error;         }      }  } else{      bzero(buffer, 512);      data.copy(buffer, 512);      error = write(sock, buffer, strlen(buffer));  }  return error;  }  std::string socketread(int sock){  std::string response = "";  char buffer[512];  int bytes;  while((bytes = read(sock, buffer, 511)) > 0){      std::string temp(buffer, bytes);      response = response + temp;      bzero(buffer, 512);  }  return response;  } 

update 2:

just update. without changing in code, reran program, , seems work sites, although following response:

http/1.1 501 not implemented date: sat, 06 feb 2016 21:43:08 gmt server: apache allow: options,get,head,post vary: accept-encoding content-length: 240 content-type: text/html; charset=iso-8859-1 connection: close 

this makes more strange...

another update: it's no longer working, 400 bad request, 1 minute after seemed work. don't it...

just update: set port forwarding, opened port via ncat (nmap tools), monitored outgoing request on lo0 (to tor's socks5 proxy port) wireshark, , incoming on en1 tcpdump, , both same, byte-for-byte. problem not rely on tor or socks5 proxy. request arrives should , send, produces 400 bad request.

just whole world of server knew im behind proxy , blocking me...

another update, maybe important one: apache in debug erro_log reports: ah00566: request failed: invalid characters in uri

but again, looking @ request/response, there no invalid characters...


Comments

Popular posts from this blog

routing - AngularJS State management ->load multiple states in one page -

python - GRASS parser() error -

Swift game error message -