作者:余弦(@evilcos)

0x01. XSS获取明文密码的多种方式

我已经感受到Web潮流带来的巨大革新,尤其是最近HTML5越来越火。浏览器们在客户端瓜分着这个Web OS,只要是对用户体验好的功能,浏览器之间就会互相学习,然后去实现,但是实现总是存在一些差异,有些差异是用户体验上的,有些则可能带来安全问题。

这篇文章是想深入描述下浏览器记住用户密码这种机制带来的安全问题与实现上的一些差异性。黑客们如何通过技巧获取到浏览器保存的密码,明文。

先回到XSS本身上,XSS获取明文密码的方式有哪些?

1.通过DHTML钓鱼方式

比如document.write出一个登陆页面,或一个登录框。也就是目标网站的登录方式是怎样的,就通过DOM模拟出怎样的。用户很难区分同域内的钓鱼,如果再次输入密码登录时就悲剧了。

2.通过JavaScript hook住密码框

满足某个事件(如onsubmit/onblur/onchange等)就记录之。

3.通过JavaScript实现键盘记录器的功能

监听用户在表单里的击键事件,记录击键的值,有时候这个效果会非常不错。

上面这三个方法都是大家在用的,效果各有千秋,这次我要提一种新的方式:通过利用浏览器保存密码这个机制来达到获取明文密码的目的,效果显得更加直接。

0x02. 浏览器记住密码的机制

现在回到浏览器的这个机制上,最早是哪个浏览器实现的,我懒得去考证了,可能是IE。在用户登录的时候,浏览器会提示保存密码,可以在下面这个地址在线查看我测试的8个浏览器截图:

http://evilcos.me/lab/xss_pwd/

注:这也是本文的demo地址,测试的浏览器有:

Chrome(v 16.0.912.75 m)
IE9
IE8
Firefox(v 9)
Opera(v 11.60)
Safari(v 5.1.2)
Maxthon(v 3.2.2.1000)
Sogou(v 3.0.0.3000)

保存密码是为了提高用户体验,省去了每次登录需要输密码的麻烦,在这个机制之前经常是通过身份认证的本地Cookie来实现的,也许是因为并不是所 有网站都采用持久化Cookie,浏览器才开始选择了这样的方式。而且现代浏览器大多有一个机制:云同步,除了书签、个人偏好外,还可以同步浏览器记住的 密码,使得用户在任意地方都可以同步自己的“习惯”。有的身份认证Cookie是绑定IP的,这样的话同步Cookie就不好使了。简而言之吧,密码这东 西就是方便,可也太滥用了,滥用有风险,而且还来了个云同步,黑客兴奋了。

在浏览器记住密码机制之前大家应该都知道还有一个很火热的机制:表单自动填充!曾经出现的安全风险是:由于这个自动填充的值是跨域共享的,攻击者可以在自 己的域放一个页面,用户的浏览器访问后,会自动填充这个页面的表单(比如Email、家庭地址、手机号等等,如果用户的浏览器记住过这些值的话),然后这 个页面的JavaScript就可以获取到这些值了。这些值还好,攻击者并不一定很喜欢,可是明文密码就不一样了。

记住密码机制需要遵循同源策略,但是如果有XSS就可以忽略这个同源策略,注入JavaScript去得到这个明文密码:P

下面我以Chrome为例深入说明说明,攻击者通过这个机制是如何得到你的明文密码的。Opera与IE的机制相对来说是最安全的,而搜狗浏览器在这方面的安全性最差。

0x03. 获得Chrome记住的密码

先来看Chrome,demo地址:http://evilcos.me/lab/xss_pwd/。可以输入admin/1234567,然后LOGIN试试。浏览器弹出保存密码提示时,选择保存。重新载入这个demo地址,可以看到浏览器已经自动填充了密码。点击按钮“see ur pwd”会弹出你输入的密码明文。

实际上你查看页面源代码是看不到密码的,这个密码是浏览器判断页面加载后,发现表单中有密码项,就自动填充最近一次记录的用户名与密码,就像(或者说就 是)一次DOM操作,动态填充。既然是DOM操作,那么在这之后我们控制JavaScript也来一次DOM操作,这次是读,将密码项里的value值读 出来,是不是就得到了明文密码?对……是这样!

知道这个过程后,邪恶的想法诞生了……

这个机制遵循同源策略,那么如果在一个域内,任意页面存在XSS,就应该可以通过DOM动态创建一个包含一模一样的用户名与密码表单项的表单出来,然后等待浏览器自动填充密码后,再通过DOM操纵得到密码项里的值。
开始实验!

这个页面http://evilcos.me/lab/xss_pwd/的表单是这样:

<form method="post" action=".">
<label for="username">USER: </label><input id="username" name="username" type="text" class="text" value="" />
<label for="password">PASS: </label><input id="password" name="password" type="password" class="text" value="" />
<input type="submit" class="submit" value="LOGIN" />
<input type="hidden" name="next" value="" />
</form>

浏览器是如何记住这个表单的,以确保唯一性?有几个关键值(不同浏览器有差异,不过影响不大):

1.为了遵循同源策略,需要域名:evilcos.me

2.需要一个<form>标签

3.需要id或name为username的用户名<input>表单项

4.需要id或name为password的密码<input>表单项

如果是这样,攻击者发现同域内XSS后,就要开始构造一段payload,这个payload用于自动创建出这样的表单,这个表单浏览器要能够认识(认为 是之前记住密码的那个表单:P),并且必须在浏览器开始自动填充密码之前出来(否则得不到填充值),最后必须在浏览器填充完密码后开始获取表单项的值(否 则获取到的值是空的)。

条件好像很苛刻,哪个步骤时间把握不好,攻击就失败了。针对这个场景我构造了一个payload,如下:

function create_form(user) { /*获取明文密码*/
var f = document.createElement("form");
document.getElementsByTagName("body")[0].appendChild(f);
var e1 = document.createElement("input");
e1.type = "text";
e1.name = e1.id = "username";
e1.value = user;
f.appendChild(e1);
var e = document.createElement("input");
e.name = e.type = e.id = "password";
f.appendChild(e);
setTimeout(function () {
alert("i can see ur pwd: " + document.getElementById("password").value);
}, 3000); // 时间竞争
} create_form('');

也可以查看http://evilcos.me/lab/xss_pwd/xssme.html的 代码,create_form函数的执行优先于整个document文档的完全解析,这时会自动创建一个登录表单(和之前记住密码的表单关键部分是一样 的,这就足够了),然后等待3000毫秒,待整个document文档解析结束(此时浏览器已经完成了密码填充),最后获取密码表单项里的值,成功!

3000毫秒不靠谱就来个for循环直到获取到密码值才退出。

0x04. 插一个题外点:时间竞争

这个话题很大,就是谁先谁后的问题,不仅和浏览器解析处理整个DOM树的顺序有关系,也和我们要达到的目的有关,比如浏览器解析顺序的一个经典例子:

<script src='http://remote/x.js'></script>
<body></body>

是先解析完远程的js脚本,还是先解析<body>标签?

如果这样呢?

<script id='rfi'></script>
<script>
document.getElementById('rfi').src = 'http://remote/x.js';
</script>
<body></body>

我们最好对“时间竞争”心里有数,搞清楚浏览器解析的机制,这样我们的payload才能达到我们的目的。

0x05. 各浏览器的差异

我已经习惯差异了,而且喜欢差异,因为这样很可能会带来一些安全问题,不过前端工程师们就不喜欢了:&,下面我只讲关键的差异,那些小的,大家自己试验,自己发现。

1 Safari浏览器

只有Safari默认是关闭这个机制的。如果开启后,效果和chrome一样,非常好用!

2.Opera浏览器

Opera好像很安全,记住密码后,浏览器并不会自动填充密码,而是要用户自己点击地址栏左边的钥匙图标,才会开始填充并登录。

3.IE8/9浏览器

IE8/9及部分这个内核的浏览器(比如遨游的IE模式)很聪明,将每个登录表单绑定到所在的页面上(下面简称这个页面为绑定页面),由于绑定页面地址是唯一的,同域内其他页面就无法通过生成一个一模一样的表单来获取密码了。

如果就这样还是不安全:P,因为XSS可以动态iframe进这个绑定页面,然后注入JS进行任意DOM操作,同样非常容易获取到密码表单项的值,IE估 计是考虑到了这个,通过iframe调用绑定页面也无效。而且IE的机制还远没这样简单,即使在绑定页面内我也没成功得到密码,因为IE默认并不填充密 码,只有输入正确用户名后,并触发类似onblur事件,这个密码表单项才会填充进对应用户名的密码。这个过程我本想通过DOM来模拟进行的,但是没有成 功。感兴趣的同学可以试试。

4.其他浏览器

其他浏览器(除了搜狗浏览器)都和Chrome差不多了,大多是因为webkit内核。下面单独说说搜狗浏览器吧。

0x06. 搜狗浏览器“记住密码机制”的安全缺陷

搜狗浏览器在实现这个机制估计是下了一些苦工了,双核模式下都很好兼容,不过安全方面的实现存在一些问题,并没严格遵循同源策略。在我的测试中发现,搜狗没区分好不同端口及不同子域的同源问题。
比如在www.foo.com域下记住的密码,在a.foo.com与www.foo.com:8080域中都可以读取到。
还有一个有意思的,我们的payload甚至仅创建一个password表单项(<form>都可以不需要)就可以得到明文密码。看来搜狗浏览器在实现这个机制有偷工减料的嫌疑啊,用户体验虽然不错。

0x07. 如何防御

从三个方面进行:浏览器、网站、用户。

1.浏览器防御

IE的机制相对来说很不错了,其他浏览器可以借鉴,虽然这样会影响一些用户体验,我想为了更安全也值得了吧,需要特别注意的,IE这个机制有好几个关键点,不要到时候依葫芦画瓢,学不好让人笑了:P

2.网站防御

通常给表单的<form>标签设置autocomplete="off"即可,不过不是所有浏览器都兼容,我发现搜狗与遨游浏览器不买这个帐。或者不要<form>标签了,通过JS自提交登录。新浪微博采用了这两种方式,其他网站可以学学。

3.用户防御

意识为先吧,浏览器记住你的密码需谨慎,没必要的就不用记了。

0x08.总结

到这还没结束,大家可以试试给表单多增加一个项或者少一个项,不同浏览器还是存在很多差异,这个大家自己找吧。
这个安全问题我很早就发现,也公开过,不过没引起足够重视:P,如果一个SNS类的网站中传播XSS蠕虫,带上这样的payload,不知道能获取多少明 文密码……或者在定点渗透过程中,如邮箱XSS渗透,带上这样的payload,一定概率说不定可以拿到明文密码。怎么个危害,就看怎么个场景,怎么个利 用。

XSS攻击:获取浏览器记住的明文密码的更多相关文章

  1. 如何php防止XSS攻击

    什么是XSS:这里通俗的讲,就像是SQL注入一样,XSS攻击也可以算是对HTML和JS的一种注入.你本来希望得到是从用户那得到一段有用的文本文字,但用户提交给你的却是别有用心的可执行javascrip ...

  2. xss攻击入门

    xss表示Cross Site Scripting(跨站脚本攻击),它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意 ...

  3. 前端Hack之XSS攻击个人学习笔记

    简单概述 **        此篇系本人两周来学习XSS的一份个人总结,实质上应该是一份笔记,方便自己日后重新回来复习,文中涉及到的文章我都会在末尾尽可能地添加上,此次总结是我在学习过程中所写,如有任 ...

  4. web安全:防止浏览器记住或自动填写用户名和密码(表单)的终极解决方案

    最近项目上要求做到这一点,在网上搜了一圈,发现都是不完美的,不兼容全部的浏览器,于是只能自己摸索了,最终得出了终极解决方案: 涉及: disabled 或 readonly display:none; ...

  5. 获取windows凭证管理器明文密码

    1.运行cmdkey /list查看windows保存凭证 方法1.mimikaz mimikatz vault::cred 2.利用powershell尝试获取 windows 普通凭据类型中的明文 ...

  6. Vue单页面应用阻止浏览器记住密码

    Vue单页面应用阻止浏览器记住密码 ——IT唐伯虎 摘要: Vue单页面应用阻止浏览器记住密码. 现象1:路由切换时再次提示“是否记住密码” 登录页面有个密码输入框,输入账号密码进行登录: 登录完成后 ...

  7. 【源码阅读】Mimikatz一键获取远程终端凭据与获取明文密码修改方法

    1.前言 mimikatz框架是非常精妙的,粗浅讲一下修改的思路. 它的模块主要由各个结构体数组组成,根据传入的命令搜索执行相应命令的模块 mimikatz.c 部分代码: NTSTATUS mimi ...

  8. # 防止xss攻击,过滤script标签,获取出标签外的内容

    from bs4 import BeautifulSoups = '<h1>123</h1> <span>456<span>'soup = Beauti ...

  9. 转:获取windows凭证管理器明文密码

    1.运行cmdkey /list查看windows保存凭证 方法1.mimikaz mimikatz vault::cred 2.利用powershell尝试获取 windows 普通凭据类型中的明文 ...

随机推荐

  1. Android requires compiler compliance level 5.0 or 6.0. Found '1.7' instead. Please use Android Tool

    重装操作系统后,要重新配置Android开发环境.配置成功后,添加原本项目时却出现了错误! Android requires compiler compliance level 5.0 or 6.0. ...

  2. Jenkins进阶之自动发送邮件的Default Content设置模板

    分享一个简洁实用的Jenkins项目邮件管理系统的"Default Content"设置模板 配置如下: <h1><center><font colo ...

  3. 年前辞职-WCF入门学习(4)

    前言 上一篇的学习中碰到一个问题,用地址http://localhost:8080/mex 访问元数据的时候一直提示400 bad request 错误,因为时间太晚了,查了好几遍代码,也没有发现问题 ...

  4. 每天一个linux命令(43):lsof命令

    lsof(list open files) 是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以 如传输控制 ...

  5. 复合sql

    update select update bucp..Core_Flow_Opinion set useruid =(select user_uid from bua..bua_user b wher ...

  6. css学习归纳总结

    来源于:trigkit4 css学习归纳总结(一) 选择器的分组 CSS选择器分为 1.群组选择器 如:p, body, img, div{} 2.兄弟选择器 如:p + p { color:#f00 ...

  7. VS中两个常用辅助工具

    一. 首当推荐的是DPack 下载地址:http://www.usysware.com/dpack/ 快捷键:以下都是个人常用的热键.其他还有,我都用得比较少了,3个已经完全够了 Alt+U   查找 ...

  8. Java sun的JDK

    JDK概述 JDK(Java Development Kit)是Sun Microsystems针对Java开发员的产品.自从Java推出以来,JDK已经成为使用最广泛的Java SDK(Softwa ...

  9. 常用JQuery插件

    虽然自己也写过插件,但JQuery插件种类的繁多,大多时候,我还是使用别人写好的插件,这些都是我用了同类插件里较为不错的一些,今天就整理一下公开放出来. UI: jquery.HooRay(哈哈,自己 ...

  10. HDU2096 小明A+B

    入门级都没到的水题!看到顺便就做了,AC记录喜+1 Description 小明今年3岁了, 现在他已经能够认识100以内的非负整数, 并且能够进行100以内的非负整数的加法计算. 对于大于等于100 ...