您的位置:首页 > 其它

一个可大规模悄无声息窃取淘宝/支付宝账号与密码的漏洞 -(埋雷式攻击附带视频演示)

2015-09-07 22:51 1076 查看


一个可大规模悄无声息窃取淘宝/支付宝账号与密码的漏洞 -(埋雷式攻击附带视频演示)

http://drops.wooyun.org/papers/1426

gainover · 2014/04/17
10:59


0x00 说在前面的话

下面是一段如何利用flash xss rookit漏洞来窃取淘宝/支付宝帐号密码的演示视频,当前漏洞已经修复
由于视频网站上传的均不给通过,只好给出一个URL了:
http://static.wooyun.org/files/taobaoxss.swf
网速好的可以下载并观看清晰版本:
http://static.wooyun.org/files/taobaoxss.wmv
2月底我们PK***团队在乌云(http://www.wooyun.org/index.php)上向阿里(淘宝/支付宝)报告了该漏洞,漏洞的标题看起来有点恐怖,但它绝对不是“标题党”。 乌云的漏洞审核人员在看了漏洞中的视频演示后,为其附加了一个生动又有一点霸气的名字:"埋雷式攻击"。
为何叫埋雷呢?本文中也会给出具体的解释。
当时阿里推出了5W的奖励计划,有人问我这个漏洞为什么不上报asrc(阿里巴巴漏洞应急响应中心),报乌云没奖励的。
我给出的答复是:“ 思路灵感都是乌云来的,自当报还之”。
本人乃至本团队,还是更喜欢并赞同乌云上这种透明的机制,从我们自身角度来讲能学习到不少,从用户角度来讲,至少可以让用户知道发生过什么,怎么保护自己 (试想,如果本文中的漏洞曾被黑客拿来窃取过用户帐号与密码,然后某天厂商修复了,用户并不知道曾经有这个漏洞发生过,也不知道自己密码是如何被盗的)。
从厂商角度来讲:Oh shit! 不要拿漏洞恐吓用户!
下面带大家一起来感受一下,这个来自乌云,又回归乌云的漏洞历程。


0x01 第一次漏洞报告

这个有意思的漏洞最初在乌云上由白帽子neobyte报告( WooYun: 一个flash的0day导致的淘宝网存储xss(可形成永久后门) ),该漏洞描述了在一些FLASH应用中,因使用Local
Shared Object (以下简称LSO)与ExternalInterface.addCallback而导致的一类XSS漏洞。由于此前并没有见到类似的报告,从开发人员角度来说,并不会 十分去注意并防御此类漏洞。我们来看看,在开发人员的角度,通过js与as的交互来实现读取FLASH本地缓存功能的流程图:



在这个示意图中,红色的箭头表示函数的调用,蓝色的箭头表示用户数据的流向。普通的开发人员仅仅在意功能是否完整的实现;带有一些安全意识的开发人员会注意到,jsGetData所获得的数据需要经过过滤再进入DOM, 如果没有考虑这点会造成什么安全问题呢?乌云上的p.z大神也给我们举了一个好例子( WooYun:
淘宝某处存储型XSS漏洞 ); 但是现在,我们将会遇到一个最糟糕的情况:“不论你是否是一个有安全意识的程序员,你都十分可能掉入这个坑中!”。
这是一个什么样的坑呢?
我们得先更深入了解下javascript调用FLASH所提供的函数接口时,到底做了哪些事情。下图描述了当我们调用jsGetData函数来获取FLASH本地缓存数据的调用过程:



上面是一个正常获取数据的流程,假设LSO中存放的数据是AAAAAAAAAAAA,最终,我们的data变量的值也为AAAAAAAAAAAA,当然,这是理想状态下的情况。
如果你对DOM XSS有一定了解,也知道eval是多么evil!(不了解但有兴趣的参见本人马甲贴:WooYun:
[腾讯实例教程] 那些年我们一起学XSS - 10. Dom Xss进阶 [邂逅eval] ),那么你一定不难想到下面的做法:将存储在LSO中的数据做以下改变:
AAAAAAAAAAAA 返回数据过程中会执行: eval('"AAAAAAAAAAAA"');
如果我们将存储的数据更换为:

返回数据将执行:

可以看到,我们在eval的数据中插入了一个alert(1),当eval执行时,就会执行弹窗操作!(你也可以打开F12的console,然后复制上面的代码运行试一试!)
然而,上面只是我们假想的情况。实际上FLASH会对返回数据进行转义操作,将双引号 (") 转义为反斜线+双引号 (\"),即我们更改存储的数据后,实际执行的是下面的代码:

正是这个转义,使得我们上面的想法泡汤了。但是,别灰心,FLASH对返回数据的过滤是存在问题的,虽然过滤了双引号
(")
,但是FLASH并没有过滤反斜线
(\)
,我们只需将上面的代码稍加修改,如下:

返回数据将会是以下的情况:

随后返回内容进入eval被当作脚本执行。
eval('返回内容');

其中双引号 (")被转义为反斜线+双引号("),但是该反斜线却被我们添加的反斜线所转义。
//如果你想在控制台测试效果,可以执行以下代码

//-- 此处由 @piaca 指出并更正描述,由于实际内容写成字符串时,反斜线需要被写成转义形式。
小总结:到了这里,我们可以知道的是,如果我们可以在LSO中存储恶意数据,当HTML页面中通过javascript调用jsGetData函数,继而通过actionscript中的asGetData函数, 从Flash本地存储中读取该恶意数据时,就会触发我们的恶意代码。
接下来的问题,我们如何往LSO中添加我们的恶意数据呢?最暴力的方法是,抢你电脑,拔你网线,拆你硬盘,而后改之!,&@……!%&!%@ ... 温柔,一定要温柔!
在我们的第一个图中,开发人员同样为我们实现了
jsSetData -> asSetData -> LSO

的流程,也就是说,我们可以通过Javascript调用jsSetData来实现修改LSO中的数据。从功能角度上是这么设计的,然而出于安全考虑,FLASH所提供的外部函数接口,并不是什么时候都可以调用的,在默认情况下,只有http://A.com的网页文件才能调用http://A.com下的FLASH文件所提供的函数接口,如下图:



这样看来,其实在默认的安全设置下,我们并没有直接的办法来修改数据。此外,每个域名下FLASH文件所使用的缓存是独立的,因而正常情况下,我们也无法使用http://B.com的FLASH文件来修改http://A.com下的FLASH缓存(不排除有猥琐的办法哦~)。
然而,这种”js读写FLASH缓存“的功能模块,天生会要求有一种特性,就是写一次,四处皆可用,从开发的角度来讲,这是天经地义的事情,方便,很方便。于是乎,开发人员在代码中加上了下面这么一句:

这一句代码的具体作用,可参见官方手册(Flash CS4 Professional
ActionScript 2.0)),简单来说,这一句话,打破了我们上面所述的FLASH默认安全设置,使得任何域名下的网页均可以调用A.com下FLASH文件所提供的addCallback接口。
这样一来,我们整个漏洞的原理图就可以建立起来了:



这个图箭头比较多。当黑客创建了恶意页面后,我们以受害者作为起点,当受害者访问了恶意页面后,会执行一系列操作,从而将恶意数据存入LSO中,这个过程,我们称之为“埋雷”。哪里会被“埋雷”呢?答案是很多地方:
譬如:
低级一点的:黑客A向你发送一个链接,你点开了。

不知不觉一点的:当你到处点网页的时候!

高级一点的:你看了一篇黑客写的博文/日志,或是有黑客给你的QQ空间日志发表了一条留言或者评论,内容里被植入了XSS代码(需结合QQ的XSS漏洞),你点开了。

再高级再不知不觉一点的:某天你QQ收到了一条礼物消息(QQ空间礼物功能XSS可以攻击任意指定QQ号码用户),或者是某天突然来了一个陌生人的QQ对话框(微博上正在疯传的那个QQ客户端聊天就中的XSS(可登陆和控制他人账号))。

总之,如果是有心而为之,你!,被埋雷的可能性非常大。
当受害者被埋下雷之后,受害者再次访问目标站(比如本次漏洞中的淘宝,或者是支付宝),黑客所埋下的恶意代码就会被触发,Bomb! 雷就爆炸了!当然,实际上黑客不大可能去恶作剧式的“Bomb!"的吓你一跳,而是偷偷的,悄无声息的利用这颗无声的”雷“来窃取受害者的帐号与密码。
看我敲了这么多,发了这么多张图,你们觉得这个漏洞的潜在危害大么?反正我觉得挺大的,再来看看厂商对neobyte提交漏洞的响应:
危害等级:中

漏洞Rank:8

确认时间:2013-10-12 16:44

是的,厂商似乎没有感觉到这个漏洞的危害。


0x02 第二次漏洞报告

到了2013年10月24号,我已经可以查看neobyte所提交的漏洞详情,于是就对他所提交的这个漏洞进行了研究,由于自己对FLASH也推敲过一些,在明白成因之后,也下载了漏洞中所提到的那个存在缺陷的FLASH文件(http://acjstb.aliyun.com/actionlog/flash/JSocket.swf)。以下是对方的修复代码:

由于业务上,淘宝此处存储在LSO的数据,并不需要字母,但是恶意代码中却需要使用到字母,例如:alert。所以开发人员这里加上了一个正则判断:“如果所获取的数据中存在字母,则返回空字符串”。是的,看起来是被修复了,但是依然存在问题,一来,开发人员并没有过滤掉真正导致潜在危害的反斜线(),二来,Javascript中调用函数完全可以不需要存在任何字母,纳尼??一起来看看:

这样我们就实现了不需要字母即可执行alert(1)的目的。再利用在上一小节中所说的恶意代码构造技巧,我们只需将AAAAAAAAAAAAAA替换为以下代码:

漏洞就这样再次出现了,虽然当时已经想到这个漏洞用来钓鱼的危害挺大,但是并没有动力去做一个钓鱼演示,并且漏洞刚被阿里修复不久,只是出于技术上的好意,想提醒开发人员完美的修复。于是,我“不好意思”的登上了我另外一个马甲号,发了一个续集: WooYun:
一个flash的0day导致的淘宝网存储xss 【续集】 。当时我给漏洞自评了8分,因为漏洞的原作者neobyte也只要了8分,我也没敢多要。但是,对方竟然只给了我5分:
危害等级:中

漏洞Rank:5

确认时间:2013-10-24 14:19


0x03 第三次漏洞报告

恩,不得不说,为什么还会有第三次呢?主要是因为上面这个5分!个人觉得,如果一个漏洞被修复后,又被绕过,这是更加严重的情况,怎么说也不应该给5分,起码也得6分是不!。这个5分大大刺激了我的“报复欲”,让我想再次绕过他们的修复方案,然后做一个大规模的钓鱼演示,让他们知道这个绝对不能是5分!!!。但是呢,这一次他们的修复方案并没有好的绕过方法! 虽然如此,隔三差五的,我还是会去研究研究,不怕贼偷,就怕贼惦记.......,直到有一天,我发现FLASH中的修复方案竟然被换掉了,并且,第一眼,我就看出这个换掉的方案又出现问题了。新的修复代码如下:

可以看到,正则表达式 _local2 仅仅过滤了 ( 和 { ,而前面也已提到,正确的过滤方法应该是过滤 \ 。经过前面2轮的洗礼,我觉得安全人员应该是知道\的危害了,为什么还会出现过滤失误呢?我在漏洞描述中也已经给出了以下猜测,后确认,答案是B。毕竟我也是写了很多年前端的,RegExp这个坑在我曾经也数次掉入。
A. 响应漏洞的同学并没看到我的修复建议并转告开发同学。

B. 开发的同学,认为 [\\({] 是 \ , ( 和 } 的集合, 而实际上,RegExp方式创建正则表达式时,需要写成 [\\\\({] ,原因是:\在字符串里是转义符,在正则里也是转义符。

当然,还需要注意的是,这个正则,不允许(和{,那么还可以执行javascript代码吗?答案是可以的,如下:

使用location.href来执行js,并且将其中的括号与花括号进行URL编码。
嗯,这个漏洞就这样再次出现了,这一次我可不想再得到那可怜的5分!于是花了时间写了一个真实可利用的代码,并录制了本文最开始的视频,撰写了漏洞报告( WooYun:
一个可大规模悄无声息窃取淘宝/支付宝账号与密码的漏洞 -(埋雷式攻击附带视频演示) )。阿里这次给出了15分,还是没有给出我心中的20分。怎么说呢,从用户角度来讲,它的危害肯定是值20分的,但是厂商并不总是站在用户考虑问题的。
危害等级:高

漏洞Rank:15

确认时间:2014-02-26 10:25


0x04 对于开发人员

注意addCallback: 在Flash中使用addCallback向外部提供函数接口时,如果as中对应函数的返回值是String, Array, Object等类型,并且返回数据中有用户可控的数据时,建议对返回值进行过滤操作,将反斜线()过滤掉。如果没有进行过滤的话,则可能出现与( WooYun:
QQ空间某功能缺陷导致日志存储型XSS - 14 )相类似的案例。这里我就不给出具体的过滤代码了,相信一般的开发人员的as都比我写的好,以下是伪代码:

勿滥用*|*Security.allowDomain("*"): **不是非常、极其、十分需要的情况下,建议将allowDomain限定在指定的域名下面,而不要为了方便而使用*。因为使用*,可能还会导致其它安全问题。


0x05 对于普通用户

由于这类漏洞十分隐蔽,目前应该没有安全软件能防御此类攻击。鉴于绝大部分厂商并不会“举一反三”的修复同类问题,我们不能完全指望厂商,安全还得靠自己。如果我们尽可能的定期清理Flash player缓存,理论上会大大降低此类漏洞造成的危害。
Flash的本地缓存一般存放在一个叫做 #SharedObjects的目录中,如果有使用Everything这款搜索工具的网友,可以使用Everything查找所有#SharedObjects目录,然后这些目录下的目录(8位的数字/字母组成)下的内容进行删除处理。(当然,删除#SharedObjects目录下数据,可能导致一些FLASH游戏或者FLASH应用的数据需要重新下载,但是相比之下,安全更重要。)
如果你没有使用Everything,下表列出了IE和chrome中Flash的缓存目录所在,找到对应目录进行清理即可,其它浏览器用户,如360***|||||*,搜狗,可自行搜索C盘下SharedObjects目录进行相应删除操作。
IE浏览器

C:\Documents and Settings\用户名 \Application Data\Macromedia\Flash Player\#SharedObjects (Win XP 系统)

C:\Users\用户名\AppData\Roaming\Macromedia\Flash Player\#SharedObjects\ (Win 7)

Chrome

C:\Documents and Settings\用户名 \Local Settings\Application Data\Google\Chrome\User Data\【用户目录】\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects (Win XP 系统)

C:\Users\用户名 \AppData\Local\Google\Chrome\User Data\【用户目录】\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects (Win 7)

*【用户目录】可能是Profile+数字 或者 Default

常见的“卫士”软件,自带了垃圾清理功能,但是可能在默认设置中,并未开启清理FLASH缓存功能,所以需要用户手动勾选“清理Flash player缓存”。这里以金山卫士为例:清理垃圾->其它常用软件产生的垃圾文件->Flash player缓存。 但是该方法也许并不会完全清理干净,例如:并不会清理chrome浏览器的flash缓存,因此还是建议使用以上方法手工清理。


0x06 说在后面的话

这个漏洞虽然标题是在说“窃取淘宝/支付宝的帐号与密码”,有些人觉得反正不知道支付密码,不要紧!但是这个漏洞所造成的潜在危害,并不是只有淘宝/支付宝帐号与密码那么简单。试想,如果在淘宝的登录页面上再结合一个QQ的xss漏洞,我们可以得到什么信息呢?淘宝/支付宝帐号、密码,QQ帐号及QQ相关信息(关于QQ的XSS可以做什么,参见乌云一哥jannock的 WooYun:
跨站脚本-可以让战场离得更远(浅谈腾讯架构缺陷) ,这个2012年时候的情况,现在已经有所好转,但是当前状况似乎依然不是太好)。此外,由于淘宝/支付宝这类涉及现金的帐号,密码等级往往十分高,可能会出现支付宝登录密码同样是QQ密码的情况,所以这类密码一旦泄漏,可能会涉及后续更严重的信息泄漏。

收藏

分享








qhwlpg 2015-03-29 17:20:11
受益匪浅
回复



Lateisha 2015-02-23 13:38:21
That hits the target peetycflr. Thanks!
回复



迦南 2014-12-12 21:38:22
回过头来,又看了一遍,再次受益匪浅
回复



南柯太守 2014-11-28 23:03:27
真能写,G博士
回复



ice 2014-09-19 17:30:04
学习了!
回复



nliar 2014-09-16 17:12:04
第一次这么认真的看完这恶魔长篇幅的文章。收益很多。谢谢楼主的分享。点32个赞...
回复



Jam 2014-09-16 11:15:27
是Flash干的,2011年就有人报告过这个漏洞,FLASH开发人员竟然SB到觉得不是个安全问题就不去修复了。 http://lcamtuf.blogspot.com/2011/03/other-reason-to-beware-of.html 回复



无面者 2014-06-30 15:28:12
这么长的篇幅,我居然看完了,看的都累,不得不佩服作者,业界良心,/大拇指
回复



gainover 2014-04-29 12:41:18
开启安全控件后,你可以在chrome控制台下,将context切换到loginIframe, 然后执行以下代码: document.getElementById("password_rsainput").onblur=function(){window.ppp=document.getElementById("password_rsainput").value} 然后再密码框输入 密码, 然后查看window.ppp变量,密码是会被记录的,
乌云那个漏洞贴中的利用代码,考虑了使用安全控件和未使用安全控件两种情况。 所以并不存在“不厚道”,与事实不讲清的情况:)
回复



gainover 2014-04-29 12:35:06
当时测试的时候,存在安全控件的情况下,依然是可以得到用户输入的密码的。
回复



小秦 2014-04-27 20:52:53
不过在逃避正则过滤后仍然执行js, 的确很厉害.
回复



小秦 2014-04-27 20:46:01
貌似楼主不厚道, 事实不讲清. 利用Flash插xss是事实,但盗账号密码却是有条件的. 在使用安全控件登陆的时候,最多得到账号,不可能得到用户输入的密码的. 在没有使用安全控件登陆的时候,得到密码是可以的. 但视频里面根本没说明这种情况,给人感觉就是只要你中了,你密码百分百被盗的感觉. 那个被插的地方是淘宝和支付宝登陆的时候,有一个在计算ua的时候会去提取这个玩意,从而导致的.
回复



咖啡 2014-04-24 19:51:38
流弊
回复



adm1n 2014-04-22 09:33:58
膜拜二哥
回复



yangff 2014-04-21 08:50:55
为什么从LSO取到的东西还要eval一下,这是浏览器干的还是flash干的?
回复



D&G 2014-04-19 09:23:50
思路灵感都是乌云来的,自当报还之 点赞
回复



YHHK 2014-04-18 17:57:42
叼炸天
回复



裙下的秘密 2014-04-18 11:34:38
只能说是太强大了,学习了
回复



小心黑哥找你 2014-04-17 22:59:09
你这是想找黑哥黑你啊,嘿嘿
回复



felixk3y 2014-04-17 18:06:39
"思路灵感都是乌云来的,自当报还之" 为你这句话,树个大拇指!赞!
回复



fate0 2014-04-17 17:59:39
没有错别字,这肯定不是黑哥
回复



gainover 2014-04-17 17:51:41
写的通俗才易懂嘛!简称:“通俗易懂”
回复



gainover 2014-04-17 17:50:52
漏洞已修复,已经无影响。
回复



计算姬 2014-04-17 17:36:40
请问,我点开了这个页面。http://xsst.sinaapp.com/taobao_xss_2014_2_20_abc3fd.htm 意味着我已经被中了那个rootkit?那我以后不能用这个浏览器登录支付宝了?
回复



wefgod 2014-04-17 16:59:40
牛逼哦
回复



不告诉你 2014-04-17 16:30:37
学习了
回复



Draycen 2014-04-17 16:26:07
学习了!
回复



子墨 2014-04-17 14:23:57
很详尽,学习了!
回复



heige 2014-04-17 13:42:27
写的这么通俗,这是想像heartbleed一样火一下啊
回复



laterain 2014-04-17 13:41:48
excellent
回复



xsser 2014-04-17 12:50:24
flash和dom环境其实两个完全不同的系统,在两个完全不同的系统里交换数据彼此应该是完全不信任的,如果实现得不好很容易出现问题
回复



zeracker 2014-04-17 12:37:33
拜膜
回复



_Evil 2014-04-17 11:50:39

回复



莊 2014-04-17 11:36:57
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: