前言

从这一章开始,正式进入了攻击阶段。BeEF提供了大量的攻击模块,可以直接使用。除了已有的模块,BeEF还提供了API,可以使用API来自行开发新的攻击模块。这一章,要介绍如何绕过同源策略,还会介绍BeEF的一个强大的功能Tunneling Proxy。

绕过同源策略

笔者在第一章就已经介绍了SOP(同源策略),SOP把拥有相同主机名 、协议和端口的页面视为同一来源。不同来源的资源之间交互是受到限制的。因为SOP的存在,BeEF只能对被勾子钩住的页面所在域进行操作。如果有办法绕过SOP,那么无疑会使攻击面放大。

绕过SOP可从两方面入手。第一个是从浏览器本身和插件的漏洞入手,一些旧版的浏览器曾被发现有绕过SOP的漏洞,旧版的插件也有类似的情况(JAVA,Adobe Flash等)。由于笔者自身能力限制,无法介绍这一方面的相关内容,读者可以自行查阅相关信息。第二个是Web的开发者错误的设置导致,下面介绍这一方面。

SOP与DOM

js或其它协议访问DOM时,也是需要遵守SOP。但是有时候子域之间需要相互访问,比如要login.site.com的代码访问admin.site.com中的表单。那么开发人员可以通过设置document.domain属性来达到目的。以login.site.com和admin.site.com来举个例子。为了使login.site.com访问admin.site.com的表单,那么开发人员会在admin.site.com的页面中加入:

document.domian = "site.com"

admin.site.com页面有了这一句js语句,那么site.com下所有页面的js都可以访问admin.site.com页面的DOM了。如果test.site.com中有XSS漏洞,那么攻击者可以使用BeEF钩住它,然后接着来攻击admin.site.com。这样不经意之间就会放宽了SOP,扩大了BeEF的攻击面了。

SOP与CORS

还记得上一章提过的跨域资源共享( CORS)吗?跨站请求可以正常发起,但是因为SOP的缘故,返回结果会被浏览器拦截。CORS机制允许进行跨域访问。如果开发者设置错误,这也会使BeEF的攻击面扩大。举个例子,为了使user.site.com访问login.site.com的资源,开发人员可能会在login.site.com的服务器设置返回以下响应首部:

Access-Control-Allow-Origin: *.site.com
Access-Control-Allow-Methods: OPTIONS, GET, POST

因为有上面的首部,所以会导致site.com下的所有子域都可以访问login.site.com的资源(浏览器不会拦截)。如果test.site.com中有XSS漏洞,那么攻击者可以使用BeEF钩住它,然后接着来攻击login.site.com。这样不经意之间就会放宽了SOP,扩大了BeEF的攻击面了。

Tunneling Proxy

前面讲了那么多理论,都是为后面的攻击做准备。这是第一个介绍的攻击模块,所以笔者挑了一个笔者个人认为BeEF中最为强大的武器之一:Tunneling Proxy。

简单来说Tuneling Proxy是把被钩住的浏览器作为一个代理,这项技术也被叫做浏览器代理。下面给出原理图:

3.jpeg1. 攻击者向Hook-domain.com主页向隧道代理发送一个GET请求。

2. 隧道代理接收到请求后,它解析收到的HTTP请求,将其转换成AJAX请求,然后通过上一章说介绍的通信技术(XMLHttpRequest或WebSocket)将该请求插入被勾连的浏览器要执行的后续JavaScript代码中。

3. 被勾连的浏览器接收到数据后,会向Hook-domain.com的主页发出一个AJAX请求。由于是浏览器发出的请求,所以它会带上Hook-domain.com的Cookie一起发送。

4. Hooke-domain.com接到被勾连的浏览器的请求后,返会HTTP响应。响应的内容会被勾子截取,直接发送回给代理隧道。所以响应的内容不会在被勾连的浏览器中显示。

5.响应的内容从被勾连的浏览器发送给代理隧道。

6.响应被发送回攻击者这里。

上面就是浏览器代理的基本原理,实际的过程要复杂的多(主要是转换成ajax请求的过程要复杂些),单单看原理可能很难理解它究竟有什么作用。下面给个例子,笔者强烈推荐读者也实际操作一次。

下面是测试环境:

本次测环境依旧是kali系统,而且需要使用到三个不同的浏览器。笔者使用 firefox 的 -P 选项创建了三个不同profile的浏览器,它们三个相互之间是不会共享数据的。

浏览器 作用
浏览器A 登录BeEF服务器。
浏览器B 作为受害者, 且登录了Freebuf网站。
浏览器C 作为攻击者,通过Tuneling proxy来窃取浏览器B的会话。

开启BeEF服务器, 接着使用浏览器A登录BeEF服务器。

使用浏览器B访问Freebuf网站,接着登录。然后返回首页,使用Burp Suite截取返回的数据,并在里面注入勾子。

这时的浏览器B如下图,笔者已经登录,并且这个页面已经注入了勾子:

1.png

浏览器B的任务已经结束了,从现在开始到测试结束,只要一直保持这个样子就可以了。

这时的浏览器A如下图,可以看到浏览器B已经被钩住了:

2.png

开启Tunneling Proxy,在kali中默认开启Tunneling Proxy功能。如果是自主安装BeEF,需要开启,配置文件是beef目录的extensions/proxy/config.yaml。确保有下图的设置, 修改后重启BeEF:

3.png

开启了Tunneling Proxy功能之后,接着是选择一个被勾连的浏览器做为代理。在这个例子中自然是选择被钩住的浏览器B。在浏览器A中,点击左上方的主机,然后点击右键,选择Use as Proxy。

4.png

这样BeEF所在主机(在这个例子中,主机就是127.0.0.1)的6789端口就是一个代理了,而它会把数据传给浏览器B,浏览器B也成了一个代理,只是这个代理有点特殊。

现在到浏览器C出场了,先给浏览器C设置代理。

5.png

都设置好了以后,看看有什么效果。这时使用浏览器C访问Freebuf主页看看, 会有如下图的效果:

7.png虽然图片和一些js没有加载成功,导致排版有些问题。但还是可以看到浏览器C通过Tunneling Proxy窃取了浏览器B中的会话。

现在来解决一下图片下载问题。 通过查看BeEF管理页面(浏览器A)中Tunneling Proxy的历史,可以找到问题所在:

8.png

可以看到freebuf把一些静态的文件都放在了 static.3001.net这个域下。当勾子操作着浏览器B向这个域发送AJAX请求,浏览器B接收到响应,响应中的首部没有设置。

Access-Control-Allow-Origin: *

由于同源策略的限制,所以勾子无法读取响应。 导致了出现了错误。

一般情况下图片、CSS、js等静态文件是不会受同源策略的限制。但是这里是因为由勾子的js代码发出的AJAX请求,所以才会受SOP的限制。

知道了问题所在,那么解决办法也就简单了。既然是static.3001.net这个域的静态文件无法返回,那么只要设置freebuf.com这个域走代理,其它域都不走代理就可以了。写一个proxy1.pac文件,内容如下:

function FindProxyForURL(url, host) {

if (shExpMatch(url, "*freebuf.com/*")) {

return 'PROXY 127.0.0.1:6789';

}

return 'DIRECT';

}

上面pac文件会告诉firefox,只有访问freebuf.com这个域或其子域的时候才会走127.0.0.1:6789这个代理。

接下来设置浏览器C使用pac自动代理:

10.png

好了,现在来看看效果如何,再一次使用浏览器C来访问freebuf:

11.png

这次效果就好多了, 浏览器C已经成功窃取了浏览器B的会话。这时的浏览器B还是保持着它原来的样子(在freebuf的首页,也就是上面的第一张图),它无法察觉它的会话已被窃取。下面来看看窃取到的会话还可以做些什么操作。

12.png15.png13.png14.png

可以看到只要是同源的情况下,都可以使用窃取来的会话进行操作,异源就不行了。这里可以看到Freebuf各子域之间的并没有使用CORS来允许交互。

测试一下退出的操作,发现能成功。浏览器C执行退出操作后,浏览器B的会话也会失效。

16.png

测试到这里就结束了,现在来回顾一下整一个过程。首先,我们让浏览器B作为一个代理,而能和浏览器B交互的只有BeEF的服务器,所以在BeEF服务器的主机下的6789端口也被设置成了一个代理。这样Tunneling Proxy就形成了,而攻击者可以使用浏览器来走这个代理(上面例子是使用了浏览器C)。浏览器C发出的请求会走过BeEF服务器,再到浏览器B,最后送到Freebuf网站。我们可以忽略中间的过程,只关注从浏览器B哪里发出的请求。从这里发出请求是由浏览器B中勾子发出的AJAX请求,所以浏览器B会把Freebuf站点上的Cookies也一起放到请求中,对于浏览器B来说这个AJAX请求只不过是一个对Freebuf网站正常请求。这就是能窃取会话的原因,至始至终浏览器C和BeEF服务器都没有获得过Freebuf站点上关于用户会话的Cookies。因为设置了HttpOnly,所以js代码是无法访问的。

Tunneling Proxy 的优缺点

先说优点:

第一它可以无视HttpOnly的限制,成功的窃取会话。

第二它开启了一个代理隧道,那么就可以使用Burp和Sqlmap这些工具, 下一章会介绍。

缺点:

第一是隧道的生存时间不稳定,一旦勾子失效(用户关闭被钩住的页面或者关闭被钩住的浏览器等),那么隧道就会断了。所以要使用上一章说道的技术来尽可能维持控制。

第二是SOP的限制,像上面的例子。即便窃取了会话,但由于SOP的限制,无法做出过多的操作。所以Tunneling Proxy如果能和绕过SOP的技术一起使用,无疑可以让攻击面变大。

Tunneling Proxy 的防御

防御Tuneling Proxy就需要从根本下手,Tunneling Proxy能建立成功,是因为勾子的代码能执行成功。所以只需要使用CSP来限制这种跨域的脚本就可以了。

结语

看完这一章,读者应该可以初步感受到BeEF的能力了,而这还只是开始。当看完所有的攻击技术后,读者会惊讶BeEF的能力,并且感叹即便是一个xss的漏洞也能作出那么多的攻击。如果对本章有疑问或纠错的朋友,欢迎在评论中留言。