SEEDLab-XSS攻击
SEEDLab-XSS攻击
跨站脚本攻击(XSS)是一种常见于Web应用程序的漏洞类型。该漏洞使攻击者能够向受害者的网络浏览器注入恶意代码(例如JavaScript程序)。利用此类恶意代码,攻击者可窃取受害者的凭据(如Cookie)。浏览器用于保护这些凭据的访问控制策略(即同源策略)可能因XSS漏洞被绕过而失效。此类漏洞可能导致大规模攻击。
为展示攻击者如何利用XSS漏洞实施攻击,我们搭建了一个基于phpBB的Web留言板系统。我们对该软件进行了修改,在留言板中植入了一个XSS漏洞;该漏洞允许用户发布任意内容到留言板,包括JavaScript程序。学习者需通过向该留言板发布恶意消息来利用此漏洞;查看这些恶意消息的用户将成为受害者。攻击者的目标是为受害者发布伪造消息。
任务1 发布恶意消息以显示警告窗口
本任务的目标是发布一条包含JavaScript代码的恶意消息,用于显示一个警告窗口。此JavaScript代码应随用户评论一同输入在消息中。以下JavaScript代码将显示一个警告窗口:
如果您在留言板上发布此JavaScript代码及您的评论,那么任何查看此评论的用户都将看到这个警告窗口。
使用账号Samy发布包含以上JS代码的帖子,当Alice访问这个帖子时就会弹出显示XSS的窗口。
任务2 发布恶意消息以显示Cookie
本任务的目标是在留言板上发布一条包含JavaScript代码的恶意消息,使得每当用户查看此消息时,该用户的Cookie会被显示出来。例如,考虑以下包含JavaScript代码的消息:
当用户查看此消息帖子时,他/她将看到一个弹窗消息框,其中显示该用户的Cookie。
与任务1类似,Samy发布一个包含上文JS代码的贴子,用户Alice访问该贴后弹出对话框显示出了用户Cookie,如图3所示。
任务3 从受害者机器窃取Cookie
在前一个任务中,恶意JavaScript代码可以打印出用户的Cookie;而在此任务中,攻击者希望JavaScript代码将Cookie发送给他/她自己。为实现此目的,恶意JavaScript代码可以向攻击者发送一个HTTP请求,并将Cookie附加到该请求中。我们可以通过让恶意JavaScript插入一个标签来实现,并将其src属性设置为攻击者目的地的URL。当JavaScript插入此img标签时,浏览器会尝试从指定的URL加载图像,并在此过程中向攻击者的网站发送一个HTTP
GET请求。下面给出的JavaScript代码将Cookie发送到攻击者机器上指定的5555端口。在该特定端口上,攻击者运行着一个TCP服务器,它仅打印出接收到的请求。该TCP服务器程序将提供给您(可从本实验网站获取)。

图4中的代码的作用是获取用户的Cookie并发送到指定地址(localhost)的5555端口。如图5所示,Samy运行了一个监听5555端口的程序,当Alice访问这个贴子后,她的Cookie被成功发送给Samy。
任务4 使用窃取的Cookie冒充受害者
窃取受害者的Cookie后,攻击者可以对该phpBB网页服务器执行受害者所能执行的任何操作,包括以受害者名义发布新消息、删除受害者的帖子等。在此任务中,我们将编写一个程序来代表受害者伪造消息帖子。
要伪造消息帖子,我们首先应分析phpBB发布消息的工作机制。更具体地说,我们的目标是弄清楚当用户发布消息时,向服务器发送了什么内容。Firefox的LiveHTTPHeaders扩展可以协助我们;它能显示从浏览器发送的任何HTTP请求消息的内容。从这些内容中,我们可以识别出消息的所有参数。图1给出了LiveHTTPHeaders的屏幕截图。LiveHTTPHeaders扩展可从以下网址下载,并且它已预装在Ubuntu虚拟机镜像中。
一旦我们理解了消息发布的HTTP请求格式,就可以编写一个Java程序来发送相同的HTTP请求。phpBB服务器无法区分该请求是由用户的浏览器发出还是由攻击者的Java程序发出。只要我们正确设置了所有参数,服务器就会接受并处理该消息发布HTTP请求。 程序需要遵循这几个步骤:
- 打开到网页服务器的连接。
- 设置必要的HTTP头信息。
- 将请求发送到网页服务器。
- 从网页服务器获取响应。 另外需要注意的是,伪造的消息帖子必须从同一台虚拟机生成,即受害者(连接到网络论坛的用户)和攻击者(生成伪造消息帖子的一方)应在同一台机器上,因为phpBB使用IP地址和Cookie进行会话管理。如果攻击者从不同的机器生成伪造的消息帖子,伪造数据包的IP地址将与受害者的IP地址不同,因此尽管伪造的消息携带了正确的Cookie信息,phpBB服务器也会拒绝该伪造的消息帖子。
如果要编写攻击程序,首先要了解发帖过程中的HTTP请求头是怎样的。如图6所示,使用LiveHTTPHeaders查看HTTP请求头的格式。然后使用Java编写攻击程序,如图7所示,将上一个任务中获得的Cookie内容作为请求头,并编写fake
news作为发帖内容,进行POST请求。编译并运行该Java程序。
如图8所示,成功伪装用户发送出虚假的帖子。
任务5 编写XSS蠕虫
在前一个任务中,我们学习了如何从受害者那里窃取Cookie,然后使用窃取的Cookie伪造HTTP请求。在此任务中,我们需要编写一个恶意的JavaScript代码,以直接从受害者的浏览器伪造HTTP请求。这种攻击不需要攻击者的干预。能够实现此功能的JavaScript代码被称为跨站脚本蠕虫。 对于此Web应用程序,蠕虫程序应执行以下操作:
- 使用JavaScript检索用户的会话ID。
- 伪造一个使用该会话ID来发布消息的HTTP POST请求。 HTTP请求有两种常见类型,一种是HTTP GET请求,另一种是HTTP POST请求。这两种类型的HTTP请求在向服务器发送请求内容的方式上有所不同。在phpBB中,发布消息的请求使用HTTP POST请求。我们可以使用XMLHttpRequest对象来为Web应用程序发送HTTP GET和POST请求。XMLHttpRequest只能将HTTP请求发送回服务器,而不能发送到其他计算机,因为同源策略对XMLHttpRequest有严格限制。这对我们来说不是问题,因为我们正是希望使用XMLHttpRequest向phpBB服务器发送伪造的HTTP POST请求。
从LiveHTTPHeaders扩展的输出中,可以注意到sid在消息发布请求中出现了两次。一次是在Cookie部分(phpbb2mysql_sid)。因此,由XMLHttpRequest发出的HTTP POST请求也必须包含Cookie。仔细查看LiveHTTPHeaders的输出,可以看到相同的会话ID也出现在以“subject=“开头的行中。phpBB服务器在此处使用会话ID来防止另一种类型的攻击。在我们伪造的消息发布请求中,我们还需要添加此会话ID信息;此会话ID的值与phpbb2mysql_sid中的值完全相同。如果请求中没有此会话ID,该请求将被服务器丢弃。
构造的恶意JS代码如上所示,这段代码是一个存储型XSS攻击脚本,它利用Ajax技术在后台执行身份窃取与操作伪造:脚本首先通过document.cookie自动提取用户的会话ID(sid),随后在用户毫无察觉的情况下,冒充其身份向服务器发送一个伪造的POST请求,从而在论坛上自动发布一条特定内容的帖子。
如图9,10所示,Samy将攻击代码嵌入到自己的帖子中。Alice不小心访问Samy的帖子,这使得她在不知情的情况下发送了一个帖子,攻击成功
任务6 编写自我传播的XSS蠕虫
在前一任务中构建的蠕虫仅代表受害者伪造消息;它不会自我传播。因此,从技术上讲,它并不是一个蠕虫。为了能够自我传播,伪造的消息中还应包含蠕虫代码,这样每当有人点击伪造的消息时,就会创建一个携带相同蠕虫代码的新伪造消息。通过这种方式,蠕虫得以传播。点击伪造消息的人越多,蠕虫传播得越快。 这需要扩展在任务5中所做的工作,并将一份蠕虫代码的副本添加到伪造消息的正文中。
编写的恶意JS代码如上所示,这段XSS蠕虫的工作原理是利用目标网站的存储型XSS漏洞的缺陷,通过一段具有自我复制能力的JavaScript代码,在受害者查看帖子时,脚本会自动从当前页面DOM中提取自身的源码,并配合从Cookie中获取的身份凭证,伪造一个发帖请求将这段源码再次发布到服务器,从而实现从Samy到Alice再到Bob的无限链式传播。
如图11所示,Samy发送了初始的恶意帖子,Alice“不小心”点击了这个诱人的帖子,结果成功中招,她也“被迫”发送了类似的帖子,Bob点击了Alice的帖子,结果同样;而后是Carol……,攻击成功。