郑昀 创建于2015/5/19 最后更新于2015/8/7
关键词:
Web安全、系统安全、Web开发、找回密码、重置密码
本文档适用人员:广义的技术人员
提纲:
- 堡垒是从内部攻破的
- 员工无知者无畏
- 运维配置暴露细节
- 后台不设防
- 找回密码
- 图形和短信验证码
- 平行权限
- MD5等于明文
- 表单被篡改
- App被篡改
- 跨站请求伪造
0x00. 前言:
第一季培训主要宣导两点,第一,白帽子或黑客都很有耐心,他手里可能捏着你多个漏洞,他一直在等机会,他也有很多工具在扫在寻找机会,第二,一次成功的入侵渗透,并不需要是多么高危的漏洞,几个普普通通的中等漏洞,加上一次社会工程学行动,就可以杀进来。
第二季主要讲一下几乎所有的 Web 工程师都容易犯的安全错误。有些事情你必须知道,并且身体力行,成为你根深蒂固的开发习惯和思路,否则会重现这个
地毯上刹车的悲剧。
0x01. 找回密码:
Web 站点的安全重灾区就是找回密码功能。很多工作了多年的 Web 开发工程师仍然意识不到这些基本安全原则:
- 客户端提交的 HTTP Request 是不可信的,表单数据可能被篡改,验证信息可能被仿冒;
- 客户端展现的一切,服务器端发给客户端的一切,一切信息,GET/POST参数,HTML/JS/Cookies,都可以被白帽子看到,毫无秘密可言;
- 靠 JavaScript 在客户端校验,第一白帽子可以在浏览器跟踪调试 JS,看懂你的算法,第二设置断点修改堆栈参数,所以靠服务器端校验才是硬道理。
1.1.你看不见,你看不见:掩耳盗铃式的开发人员
你敢保证你不会做出下面这种事情吗?
案例一:PPS
+网页版忘记密码功能:
++贴心地实现了“重新发送找回密码邮件”功能。不幸的是,在 URL 里,
用来接收邮件的 email 参数是明文的,WTF?!
++从而可以将任意用户的密码重置邮件发给指定邮箱。
图1 找回密码篇-案例1
图2 找回密码篇-案例1-把email参数改一下,改成我的邮箱,uid不变
案例二:拉手网
+App 里的忘记密码功能:
++首先,通过抓包分析,发现密码重置接口也可以 Web 访问;其次,填入手机号码提交,服务器端的响应中,
居然包含明文短信验证码,虽然是在 JavaScript 中的注释里,当我看不见啊?
图3 找回密码篇-案例2
++此事绝非个案。如
第三方支付平台支付通也干过。
案例三:走秀网
+走秀网团购的忘记密码功能
++点击忘记密码,选择输入手机号码重设,点击获取验证码,用 firebug 注意观察
浏览器发出的 AJAX 请求,验证码即将出现,神啊:
图4 找回密码篇-案例3
++直接输入此验证码即可重置密码了。
案例四:惊天大案,新网互联
+网页版忘记密码功能
++页面上虽然展示的是星号遮挡的邮箱地址,很贴心,但
HTML 文档构造的表单参数里却使用邮箱明文字符串,最终导致2013年5月12日土豆网域名被劫持,酿成国际知名大案:
图5 找回密码篇-案例4
图6 找回密码篇-案例4-白帽子有专用工具,找到关键词很容易
图7 找回密码篇-案例4-改表单参数从新提交
图7-1 找回密码篇-案例4-成功获得土豆网域名管理权限
++类似案例还有:
WooYun:和讯网修改任意用户密码漏洞。
案例五:搜狐网
+网页版找回密码功能
++找回密码时要回答“密码提示问题”;但是工程师
把答案明文写在 textarea 控件的 JS 校验函数里了,晕倒,工程师真是单纯;
++从而可以重置任意搜狐用户密码;
图8 找回密码篇-案例5
案例六:中兴某站
+网页版找回密码功能
++发送到邮箱里的重置密码链接上,Token 一看就是时间戳,精确到秒,因此可以轻易构造;
图9 找回密码篇-案例6
1.2.你能看见,那我 MD5 一下你就看不见了:Too young too naive 的开发人员
有些工程师看的入门教材可能版本太老,内容过时,所以总以为 MD5() 是神器,殊不知在 MD5 爆破库面前等同于明文。
案例七:奇虎360
+网页版找回密码功能:
++360的找回密码邮件里,重设密码地址格式为:http://i.360.cn/findpwd/setpwdfromemail?vc=%
一个MD5加密串%&u=blabla%40gmail.com;
++利用 MD5 爆破库逆向解密后发现,这个 MD5 加密串是一个类似于 1339744000 的数字,很像是UNIX时间戳;
++白帽子进一步验证后猜测,用户找回密码时,系统将此时的UNIX时间戳,与帐号绑定,记录在密码重置队列里,修改该用户的密码时会验证输入的 vc 参数;
++看似合理,但360工程师忽略了一个细节:假如这个时间戳是新生成的,攻击者就能在一定时间段内进行暴力破解,给定任意邮箱,很快就能算出一个有效的重置密码链接;
图10 找回密码篇-案例7-MD5(timestamp)
案例八:途牛网
+注册激活邮件功能:
++注册某牛网后,系统发的注册邮件里,激活URL里,id参数实际上是用户的userid,可以遍历,str参数则是MD5(id)加密串,如下图所示;
图11 找回密码篇-案例8-整数userid,MD5(userid)
图12 找回密码篇-案例8-密文输入MD5爆破库立刻得到明文真值
++从而能注册任意邮箱并激活,或遍历所有整数id激活。
案例九:新浪二手房
+网页版找回密码功能:
++点击忘记密码,随意输入一个用户名后,通过 firebug 观察 AJAX 数据包,注意到服务器端返回了一个 JSON 串,很明显是一个手机号码,被 MD5 了一把:
图13 找回密码篇-案例9-ajax返回了用户名对应的手机号,MD5等同于明文
++在手机号码输入框里输入解密后的号码,焦点移开后,浏览器发起了一个 AJAX 请求去获取数字验证码(这是神马逻辑?WTF!)
图14 找回密码篇-案例9-好吧,数字验证码也是MD5了一把
++MD5 爆破库面前,统统都是明文,于是得到数字验证码为 234589,输入后成功重置密码。
1.3.眼里只有 Token:Too young too naive 的开发人员
有些工程师确实单纯,他们做各种业务场景都可能引入平行权限漏洞。在他们的眼里,在服务器端校验一下输入参数 checkcode 或 token 或 vi 参数,就已经很了不起了,校验过了,干啥都行,所以 Token 虽然是颁发给用户 A 的,但可以改用户 B 的数据。
什么是平行权限漏洞?
我举一个栗子。
2012年的时候,你注册一个网易邮箱,注册成功后会跳转到一个绑定手机的安全提示页面:
目标网易邮箱成功被越权绑定了密保手机。 |
这就是平行权限漏洞,或者叫“越权”。
案例十:身份通
+邮箱找回密码功能
++重置密码的链接发送到了对应邮箱,链接如下:
http://www.idtag.cn/regionTempAction.do?method=resetPassword&idtagCard=用户ID值&authcode=Go8K7yp4TWy&rtEmail=邮箱地址
++抓包后,看到类似于的真值:
org.apache.struts.taglib.html.TOKEN=83accc27d5178f832d9f22a1d02bdacf&org.apache.struts.taglib.html.TOKEN=83accc27d5178f832d9f22a1d02bdacf&rtPassword=123456&passwordw=123456&rtEmail=邮箱&idtagCard=用户ID
++Token 不变,试着改一下用户ID,再次提交请求,哇,成功重置密码:
图15 找回密码篇-案例10
案例十一:OPPO
+使用绑定手机号码下发短验找回密码功能
++走正常流程,输入收到的短验和新密码提交,抓包,checkcode不变,将用户名改为任意账户,再次提交,成功重置密码;
图16 找回密码篇-案例11
案例十二:携程旅行网
+使用邮箱重置密码功能
++点击系统发送到邮箱的重置密码链接,重置密码并抓包:
图17 找回密码篇-案例12
图18 找回密码篇-案例12-发现Uid一枚
++是的,在 POST 数据中发现标识用户身份的 Uid 参数,而这个 Uid 在密码重置的第二步时,系统会“主动”提供给我们(注意看图17);
++我们用 firefox 的插件
LiveHTTPHeaders,利用它的修改 POST 表单参数并重放功能,修改 Uid,提交表单;
++成功重置另一个用户的密码。
1.4.信任客户端校验的小朋友,你危险了
白帽子有很方便的工具可以调试,可以拦截 Response,可以重放,这个客户端不仅仅指浏览器,还包括手机 App。
案例十三:乐蜂网
+使用手机号找回密码功能;
++进入乐峰网供应商管理系统,点击忘记密码,输入用户名 admin,选择手机找回密码,随意填写一个短验,然后点击下一步,此时抓包:
图19 找回密码篇-案例13-随便写一个验证码填进去
图20 找回密码篇-案例13-截断返回的数据包
++经过反复测试,将下图中的返回码,改成 102 即可绕过,服务器端响应后,直接跳转到重置密码页面:
图21 找回密码篇-案例13-修改 Body 值
++成功重置。
类似案例还有:
WooYun:oppo重置任意用户密码漏洞(4)。
1.5.玩 Cookie 玩砸了的小朋友
白帽子都身经百战,跟各种互联网公司的各种层次攻城狮斗智斗勇,所以他们都总结了很多种突破模式。其中一种就是会话覆盖,专门盯着那些喜欢把乱七八糟东西存储在 Cookie 里的小朋友。
案例十四:聚美优品
+使用邮箱找回密码功能;
++1,用浏览器找回你自己的聚美优品帐号的密码,选择验证身份方式为邮箱;
++2,你的邮箱会收到一封邮件,但不要点击那个重置密码链接,但你可以注意到这个链接上没有帐号信息参数;
++3,同一个浏览器继续使用找回密码功能,这次找回目标用户的密码,但到了下面这个步骤后就停住:
图21 找回密码篇-案例14
++4,仍在同一个浏览器里,(否则就不灵了),打开第二步里我们收到的那个重置密码链接:
图22 找回密码篇-案例14
++5,填写新密码,提交,okay,成功重置了目标用户的聚美优品密码:
图23 找回密码篇-案例14
图24 找回密码篇-案例14-搞定
1.6.不做 Rate Limiting 就是愚蠢
关键业务不做提交频次阈值防范,就是愚蠢,就等着被别人爆破吧。
参考案例,WooYun: 当当网任意用户密码修改漏洞,还有的做了频次限制但是被绕过的经典案例,WooYun: 微信任意用户密码修改漏洞,它限制了提交次数,但是存在逻辑问题,在手机号字符串后放一些字符就可以绕过。
好了,大致就是这么多案例,我们复习一下:
- 客户端提交的信息,客户端存储的信息,都可能是经过篡改的;
- 白帽子是程序员,他们有很多工具,可以很方便地找到漏洞、篡改数据并重放;
- 整数ID是可以遍历的;
- MD5加密串是可以反向爆破的;
- JS 校验是不大靠得住的,可以绕过;
- 每一个互联网站点都有的找回密码功能,看似简单,但对于 Web 开发工程师来说,没那么容易,它能考察出你是一个什么样的工程师,你未来能走多远。
最后借用乌云知识库的
BMa 整理的找回密码常见弱点:
|
他的建议是:找回密码凭证要足够复杂并且不可猜测,任何校验动作都放在服务器端进行,
传输的验证参数要做好加密,同时对参数做好过滤。
|
就到这里。
参考文献:
1,2015,乌云知识库,
密码找回逻辑漏洞总结;
2,2014,郑昀,
被小伙伴们蠢哭了的那些事儿:找回密码篇;
3,2013,郑昀,
Web开发基本准则-55实录-Web访问安全;
4,2012,郑昀,
5·12和6·17两知名网站域名被劫持事件实施过程回放;
5,2011,陈皓,
你会做Web上的用户登录功能吗?;
6,2015,郑昀,
安全基础教育第一季:堡垒是从内部攻破的;
-EOF-
来源:oschina
链接:https://my.oschina.net/u/815999/blog/492878