你可以到SEED官网获取实验资料:Buffer-Overflow Attack Lab (Server Version)

XSS概述

……

实验概述

  1. 实验环境设置
  1. DNS设置:
    使用命令sudo vim /etc/hosts编辑本地DNS配置,需要注意的是多个域名是可以定向到同一个IP地址的,因为Web服务器可以通过HTTP协议的hosts字段来区分访问的服务。

  2. 启动docker服务:
    使用命令dcbuild和dcup启动docker配置的服务,一般来说docker启动服务没有什么问题,以下是服务成功启动的截图:

  3. 准备工具“HTTP Header Live”:

任务

  1. 在浏览器提示框发布恶意消息
    使用Java Script代码写一段这样的功能很简单:

alert(‘XSS’);是JS代码部分,script标签在html中声明这是一段JS代码。
另外,这当代码过长时可以使用链接的方法方法,将指定路径的JS代码记载执行:

下面需要将这段恶意js代码注入到该网站中,登录samy的账号,在个人资料中的“brief description”中进行注入:

点击保存,Web服务器会将你的个人资料或者说恶意JS代码存入数据库。当请求该页面的资源时,浏览器获取到数据库中的恶意JS代码并执行。因此所有人访问这个页面都会受到影响,弹出提示框:

登录其他人的账号访问也是一样的。

  1. 显示cookie的提示框
    相比上一个任务并没有多大改变:

alert(document.cookie);这一段JS代码调用document.cookie函数获取用户cookie信息并弹出提示框进行显示,同样script标签用于在html页面中声明这是一段JS代码。
登录samy账号,将这段JS代码注入到个人资料中的“location”中:

点击保存后,JS代码注入成功,先弹出一个提示框“XSS”,然后弹出一个用户cookie信息:

其他人访问也是一样的:

可以通过检查网页html查看注入的JS代码,可以发现JS代码已经注入了:

  1. 窃取访问者浏览器上的Cookie
    相比于上面的任务,这个任务具有了攻击性,窃取别人的cookie在一些场景可以绕过登录验证操作别人的账号。
    实现原理也很简单,通过浏览器获取用户cookie然后将cookie信息发送给自己。

通过document.write函数向网页中写入一个img标签,浏览器解析这个标签时会向src字段的网址发送GET请求用于获取图片资源,通过img标签我们可以向自己的IP发送一个GET请求并带上cookie参数(?后面是参数内容,这里使用“c”进行简写了)。
讲这段JS代码注入到个人资料中的“brief description”中:

保存之后,页面刷新可以看到后台监听到了JS代码发送的请求:

其他用户访问也是一样,这里省略。
可以通过检查,查看网页元素,看看我们是否注入成功:

  1. 成为受害者的好友
    相比于上面窃取cookie,使用JS调用Web服务的接口要复杂一些。因为编写JS代码之前,需要先知道接口的详细信息,以便可以构造正确的请求。
  1. 抓包找到添加好友的接口和参数信息。
    这里通过“HTTP Header Live”捕获到一些信息。
    接口:GET http://www.seed-server.com/action/friends/add
    参数:friend=59;__elgg_ts和_elgg_token。其实我们猜测以下就可以知道samy的id为59,另外ts应该是时间戳,token一般是用户令牌,令牌提供访问控制相关的实现,时间戳应该用于防止用户重放。

  2. 编写JS代码并注入
    window.onload = function () { … }:这是一个事件处理器,表示在页面加载完成后执行指定的函数。函数定义了请求接口:URL(…/action/friend/add)和HTTP方法(GET),此外一个请求参数friend也被定义到了url里,这是samy的标识,另外ts和token参数也被赋值。最后通过Ajax发送这个请求。
    (这里代码接口错了)

寻找合适的注入点,将JS代码注入samy个人资料的“关于我”中。这样其他人访问这个页面,他的浏览器就会执行网页中的JS代码,导致用户添加samy为好友了。
需要注意的是这里需要启用HTML编辑模式,否则服务器将会使用一些html标签打乱你的JS代码,导致JS代码变成文本而非代码。

登录alice账号进行测试,可以看到添加好友成功:

问题一:为什么需要代码中被标注行
其实就是用户令牌,后端用来识别是那一个用户发起请求的,一般用来做访问控制,ts是时间戳,用于抗用户重放。
问题二:不更改“关于我”编辑模型,还能注入吗?
不能,因为文本编辑后,JS代码将会被注入html标签,导致JS代码无法执行,因为它们会被当成文本而非代码。
6. 修改受害者的个人资料
思路和上一题一样,也是先找接口,然后编写JS代码注入网页中。
1) 抓包找到修改个人资料的接口
接口:POST http://www.seed-server.com/action/profile/edit
接口参数:除了基本每个请求都有的ts和token以外,还有一些用户相关的参数。

这里可以通过浏览器检查中的网络查看更详细的信息:

  1. 编写代码并注入:
    通过上面收集到的接口信息构造JS代码,发送一个POST请求进行更改用户发个人资料信息:

  2. 测试是否注入成功:
    可以通过浏览器检查功能,查看网页元素信息看是否正常注入:

登录Alice的账号进行测试,发现当alice访问samy的个人资料界面以后,alice个人资料界面改变:

  1. 问题3:为什么需要标注的那一行:
    这行代码用于判断用户是不是samy本身,如果不是,才选择发送POST请求修改个人资料中的关于我信息。
  1. 编写能自我传播的XSS蠕虫
    上面的任务将恶意信息注入别人的个人资料中,这里只需要将恶意JS代码也一起注入即可。
    编写JS代码,下面这段代码会自动将JS代码嵌入html中,因此用户访问页面后,会被感染从而感染更多的人,造成传播。

将JS代码注入到samy的个人资料“关于我”中:

登录其他账号检测是否注入成功:

防御策略:使用一些转编码的方式让嵌入的script标签和其他html标签失效。
8. 使用CSP策略对抗攻击
网页文件使用JS代码有两种方式,内联方式和链接方式。内联方式是造成XSS注入的罪魁祸首,因为它可能允许用户输入JS代码进行执行;链接的方式则允许浏览器使用可信来源的JS文件。总的来说,链接的方式使得html元素和JS代码相分离。
通过CSP策略,只有可信来源(同域)的JS文件,包括其他资源比如图片等。
问题一:
下面三个网站采用了不同的CSP策略,这里有选项链接,内联,还有不同的域,三个网站CSP策略不同。

问题二:
点击按钮,只有“32a”网站作出响应。
问题三:
在配置中按照70添加一行60的就行:

这里重新启动docker生效:

问题四:
这里方法差不多,不过是使用php对index页面进行配置:

配置成功:

问题五:
禁止内联JS代码。
对于链接JS文件限制可信源。
另外还可以通过connect-src和frame-src限制资源来源和目标,防止数据泄漏。