Флуд phpbb3 от имени нескольких пользователей

Discussion in 'Песочница' started by Devilwhore, 16 Jun 2011.

  1. Devilwhore

    Devilwhore New Member

    Joined:
    15 Jun 2011
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Доброго всем взаимного расположения небесных тел... Задавала этот вопрос на phpbbguru (в более пристойной формулировке, естественно), однако, ничего внятного не услышала... Суть задачи: есть форум на MyBB, я исполняю обязанности модератора. Что за форум - не скажу, ибо реклама. Планируется его перенести на собственный хостинг, однако изъять копию уже имеющегося нереально. Владельцы MyBB отказываются делать дамп базы или бэкап; поэтому, очевидно, придётся делать экспорт прямо из HTML-варианта, а потом заново постить на новый форум. Теперь собственно вопрос.

    Пожалуйста, подскажите, как реализовать авторизацию с последующей отправкой нужного сообщения в нужную тему (создавать новую тему не нужно). Пробовала для этого Denyo Launch, но это немного не то, на каждый пост надо по новой задавать cookie, неудобно... Я пробовала отправлять POST-запросы - почти довольна результатами, ибо, судя по содержимому строки "Сейчас на форуме" в обозревателе, авторизация проходит. Из ответа сервера мне удаётся извлечь номер пользователя и идентификатор сессии. Вставляю их в виде cookie во второй запрос, уже к posting.php и... ничего не происходит! Почему?

    Пробовала двумя способами:
    1. отправить запрос, составленный вручную, через сокет; и
    2. путём запуска cURL с нужными аргументами (пользоваться ей надоумили на phpbbguru).
    Результат - ничего: что через сокет, что через cURL - индифферентно...

    Хотя нет, пробовала и третий способ - флудер Cl!kodol для phpbb на perl. Увы, он не запускается, сервер говорит 503... Путь к интерпретатору проверяла, так что по-идее, должен бы работать. Также пробовала какой-то флудер на PHP, он запускается и нормально шлёт запросы; однако, безрезультатно.

    Важный момент: отправка единственного поста из Denyo Launch происходит удачно. Но в том-то и соль, что участники форума не пишут по два поста подряд, так что данные авторизации для следующего сообщения нужно менять... В общем, если у кого-то есть исходники DL, есть шанс, что я смогу вытащить из них нужный мне кусок. Или, может быть, кто-то выложит свой исходник для обращения к posting.php. Я смогу понять Pascal (лучше всего секу в FPC/Lazarus, но можно Delphi); очень может быть, C или PHP; и может быть, MASM или FASM.

    Пожалуйста, помогите... Количество постов скоро перевалит за три тысячи, и нащёлкивать их мышкой на новом форуме мне очень не хочется. Хватит того, что мне ещё парсер HTML для MyBB писать... Если интересуют запросы, командные строки запуска curl или код моего клиента, скажите - напишу.
     
    #1 Devilwhore, 16 Jun 2011
    Last edited: 16 Jun 2011
  2. Flisk

    Flisk Member

    Joined:
    4 Aug 2010
    Messages:
    147
    Likes Received:
    8
    Reputations:
    -2
    Имхо, вы не с той стороны подходите к решению данной задачи. Лично я бы заполнял форум сразу через запросы к базе данных, минуя прямой постинг на форуме (вы же свой форум заполняете, а не чужой флудите).
     
  3. Devilwhore

    Devilwhore New Member

    Joined:
    15 Jun 2011
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Уже разобралась с ним - вставила в index, viewtopic, ucp и posting сценарии на JavaScript, которые запускают обработку форм. Через }|{, короче... Но главное - 40000 файлов, сотворённых парсером из трех тысяч, выдранных curl со старого форума, превратились в девятимегабайтную базу :)

    Но вообще такая наработка была бы полезной. До сих пор не поняла, почему, например, запросы PHP-флудера проходят, но безрезультатно...

    Flisk
    К сожалению, не так хорошо знаю структуру базы форумов phpBB, чтобы вручную таблицы составлять...
     
  4. Flisk

    Flisk Member

    Joined:
    4 Aug 2010
    Messages:
    147
    Likes Received:
    8
    Reputations:
    -2
    Devilwhore, а как вы все таки распределили эти посты между пользователями? Интересно бы глянуть на вашу реализацию, если это,конечно, не секрет. Хотя бы в общем.

    По структуре базы данных - я не разбирался с phpBB, но кодил скрипты (парсер+автопостер) для других цмс, и имхо, там ничего сложного нет. Смотрим структуру записи любого поста, также смотрим, какие еще записи и в каких таблицах меняются при "обычном" постинге, и повторяем все это скриптом.
     
  5. Devilwhore

    Devilwhore New Member

    Joined:
    15 Jun 2011
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Долго не заглядывала, была работа... Выкладываю на случай, если кому-то ещё понадобится.

    Регер пользователей:

    В ucp.php после
    Code:
    case 'register':
    
    вставить это:
    Code:
    $pendnum=file_get_contents("./data/pending.tmp");
    $postqty=file_get_contents("./data/total.tmp");
    if($pendnum>$postqty){
     print "<h1>REGISTRATION FINISHED.<br>REPLACE FILES UCP.PHP, INDEX.PHP BY ORIGINAL</h1>";
    }else{
     $namedata=iconv("windows-1251","utf-8",file_get_contents("./data/reg/login".$pendnum.".txt"));
     $passdata=iconv("windows-1251","utf-8",file_get_contents("./data/reg/passw".$pendnum.".txt"));
     $maildata=iconv("windows-1251","utf-8",file_get_contents("./data/reg/email".$pendnum.".txt"));
     print "<h1>REGISTERING (".$pendnum."/".$postqty.")...</h1><script language=javascript>
     function force_login_execute(){
      var x=document.getElementById('agreement');
      if(x!=undefined){
       x.agreed.click();
      }else{
       x=document.getElementById('register');
       if(x!=undefined){
        x.username.value='".$namedata."';
        x.email.value='".$maildata."';
        x.email_confirm.value='".$maildata."';
        x.new_password.value='".$passdata."';
        x.password_confirm.value='".$passdata."';
        x.submit.click();
       }else{
        document.location='./index.php';
       }
      }
     }
     setTimeout('force_login_execute()',1000);
     </script>";
    }		
    
    в index.php перед
    Code:
    page_footer();
    
    вставить:
    Code:
    $pendnum=file_get_contents("./data/pending.tmp");
    $postqty=file_get_contents("./data/total.tmp");
    if($pendnum>$postqty){
     print "<h1>REGISTRATION FINISHED.<br>REPLACE FILES UCP.PHP, INDEX.PHP BY ORIGINAL</h1>";
    }else{
     print "<h1>REGISTERED <br>".$pendnum."/".$postqty.".</h1>";
     $pendnum++;
     $pendf=fopen("./data/pending.tmp","wb");
     fputs($pendf,$pendnum);
     fclose($pendf);
     print "<script language=javascript>
     function force_reg_execute(){
      document.location='./ucp.php?mode=register';
     }
     setTimeout('force_reg_execute()',1000);
     </script>";
    }
    
    где в файлах login1.txt, passw1.txt, email1.txt, login2.txt, passw2.txt, email2.txt имена, пароли и адреса почты
    регистрируемых. Файлы сложены в каталоге ./data/reg/
    В файле ./data/total.tmp находится цифра, сколько всего регистрировать (если 100, то в ./data/reg/ должны быть
    файлы ?????1.txt - ?????100.txt). В ./data/pending.tmp перед запуском должна быть цифра 0.

    Флудер

    в ucp.php после
    Code:
    case 'reply':
    
    вставить:
    Code:
    $pendnum=file_get_contents("./data/pending.tmp");
    $postqty=file_get_contents("./data/total.tmp");
    if($pendnum>$postqty){
     print "<h1>POSTING FINISHED.<br>REPLACE FILES INDEX.PHP, UCP.PHP, POSTING.PHP AND VIEWTOPIC.PHP BY ORIGINAL</h1>";
    }else{
     $posttextdata=iconv("windows-1251","utf-8",file_get_contents("./data/post".$pendnum.".txt"));
     $authnamedata=iconv("windows-1251","utf-8",file_get_contents("./data/login".$pendnum.".txt"));
     $authpassdata=iconv("windows-1251","utf-8",file_get_contents("./data/passw".$pendnum.".txt"));
     print "<h1>POSTING FILE ".$pendnum." OF ".$postqty."...</h1><script language=javascript>
     function force_post_execute(){
      x=document.getElementById('postform');
      if(x!=undefined){
       x.message.value='".$posttextdata."';
       x.post.click();
      }else{
       var x=document.getElementById('login');
       if(x!=undefined){
        x.username.value='".$authnamedata."';
        x.password.value='".$authpassdata."';
        x.login.click();
       }
      }
     }
     setTimeout('force_post_execute()',1000);
     </script>";
    }
    
    в ucp.php после
    Code:
    case 'login':
    
    вставить:
    Code:
    $pendnum=file_get_contents("./data/pending.tmp");
    $postqty=file_get_contents("./data/total.tmp");
    if($pendnum>$postqty){
     print "<h1>POSTING FINISHED.<br>REPLACE FILES INDEX.PHP, UCP.PHP, POSTING.PHP AND VIEWTOPIC.PHP BY ORIGINAL</h1>";
    }else{
     $authnamedata=iconv("windows-1251","utf-8",file_get_contents("./data/login".$pendnum.".txt"));
     $authpassdata=iconv("windows-1251","utf-8",file_get_contents("./data/passw".$pendnum.".txt"));
     $postyeardata=file_get_contents("./data/year".$pendnum.".txt");
     $postmonthdata=file_get_contents("./data/month".$pendnum.".txt");
     $postdaydata=file_get_contents("./data/day".$pendnum.".txt");
     $posthourdata=file_get_contents("./data/hour".$pendnum.".txt");
     $postmindata=file_get_contents("./data/min".$pendnum.".txt");
     $postsecdata=file_get_contents("./data/sec".$pendnum.".txt");
     exec("echo ".$postdaydata."-".$postmonthdata."-".$postyeardata."|date");
     exec("echo ".$posthourdata.":".$postmindata.":".$postsecdata."|time");
     print "<h1>LOGGING IN (FILE ".$pendnum."/".$postqty.")...</h1><script language=javascript>
     function force_login_execute(){
      var x=document.getElementById('login');
      if(x!=undefined){
       x.username.value='".$authnamedata."';
       x.password.value='".$authpassdata."';
       x.login.click();
      }
     }
     setTimeout('force_login_execute()',1000);
     </script>";
    }
    
    в viewtopic.phpперед
    Code:
    page_footer();
    
    вставить:
    Code:
    $siddata=file_get_contents("./data/sid.tmp");
    $pendnum=file_get_contents("./data/pending.tmp");
    $postqty=file_get_contents("./data/total.tmp");
    if($pendnum>$postqty){
     print "<h1>POSTING FINISHED.<br>REPLACE FILES INDEX.PHP, UCP.PHP, POSTING.PHP AND VIEWTOPIC.PHP BY ORIGINAL</h1>";
    }else{
     print "<a name=home><h1>POSTED ".$pendnum." OF ".$postqty.". PREPARING TO LOG OUT...</h1>";
     $pendnum++;
     $pendf=fopen("./data/pending.tmp","wb");
     fputs($pendf,$pendnum);
     fclose($pendf);
     print "<script language=javascript>
     function force_logout_execute(){
      document.location='./ucp.php?mode=logout&sid=".$siddata."';
     }
    // если не нужно чтобы страница темы прокручивалась вверх до строки отчета, от отсюда
     function force_roll_up(){
      document.location='#home';
     }
     setTimeout('force_roll_up()',1000);
    // до этой строки убрать
     setTimeout('force_logout_execute()',1000);
     </script>";
    }
    
    в index.php перед
    Code:
    page_footer();
    
    вставить:
    Code:
    $pendnum=file_get_contents("./data/pending.tmp");
    $postqty=file_get_contents("./data/total.tmp");
    if($pendnum>$postqty){
     print "<h1>POSTING FINISHED.<br>REPLACE FILES INDEX.PHP, UCP.PHP, POSTING.PHP AND VIEWTOPIC.PHP BY ORIGINAL</h1>";
    }else{
     $tiddata=file_get_contents("./data/tid".$pendnum.".txt");
     if(isset($_GET['sid'])){
      print "<h1>STORING SESSION IDENTIFIER (FILE ".$pendnum."/".$postqty.")...</h1>";
      $sidf=fopen("./data/sid.tmp","wb");
      fputs($sidf,$_GET['sid']);
      fclose($sidf);
     }
     print "<script language=javascript>
     function force_redir_execute(){
      document.location='./posting.php?mode=reply".$tiddata."';
     }
     setTimeout('force_redir_execute()',1000);
     </script>";
    }
    
    файлы, сложенные в ./data/

    post*.txt - тексты постов, знак \ нужно заменить на \\, знак ' (одиночная кавычка) на \', перевод строки - на \n
    login*.txt - имена
    passw*.txt - пароли
    tid*.txt - идентификаторы веток (в виде строки &f=номер_форума&t=номер_темы)
    year*.txt, month*.txt, day*.txt, hour*.txt, min*.txt, sec*.txt - даты/время постов
    total.tmp, pending.tmp - то же, что для регистратора, sid.tmp - идентификатор сессии текущего залогиненного пользователя (пишется само)

    Настройки форума:
    - все пользователи на время работы флудера должны быть в группе Administrators
    - минимум сообщений от пользователя до ухода из группы "Newly registered" - 0 (по дефолту 3, надо поменять, иначе посты будут попадать на премодерацию)
    - antiflood delay - 5 секунд
    - тест CAPTCHA отключен