号称 98 分的宏碁售票,差的那两分就在 Cookie 认证

2020-06-24    收藏498
点击次数:405

  • 前言

    号称 98 分的宏碁售票,差的那两分就在 Cookie 认证(Photo by mcf1986)

    Cookie 是开发网页应用程式很常利用的东西,它是为了解决 HTTP stateless 特性但又需要有互动而产生的。开发者想把什幺资讯暂存在用户浏览器都可以透过 Cookie 来完成,只要资讯量不大于约 4KB 的限制就没问题。在这样的空间里,可以放购物车内的暂存商品、可以储存读者阅读记录以精準推荐产品、当然也可以写入一些认证资讯让使用者能保持登入状态。

    Cookie 有一些先天上的缺点,在于资料是储存在浏览器端,而使用者是可以任意修改这些资料的。所以如果网站的使用者身分认证资讯依赖 Cookie,偷偷窜改那些认证资讯,也许有机会能够欺骗网站,盗用他人身分,今天就来谈谈这样的一件事情吧!

  • 问题与回报

    会想要聊这个议题,主要是因为最近很红的宏碁云端售票系统就是採用 Cookie 认证。上週在注册该网站时看了一下 Cookie,发现该网站没有使用 Session 机制 的迹象,也就是单纯利用 Cookie 的值来认证。

    号称 98 分的宏碁售票,差的那两分就在 Cookie 认证

    于是开始好奇认证主要的依据是什幺?从图中可以看到 Cookie 值并不多,猜测该网站大概会是看 USER_ID、USER_ACCOUNT 来判断你是哪个使用者,稍作测试后会发现有些页面只依据 USER_ACCOUNT 的值来确认身分,而 USER_ACCOUNT 这个值其实就是使用者的身分证字号,也就是说任何人只要跟网站说我的身分证字号是什幺,网站就会认为你是那个身分证字号的使用者。 利用这点设计上的小瑕疵,就可以窃取他人个资,更进阶一点,甚至可以用来清空别人的志愿单让其他使用者买不到票 。

    发现这个问题后,决定通报 VulReport 漏洞回报平台 ,由该平台统一通知开发商。这是我第一次使用这个平台,对我而言这是一个方便且对整体资安环境有助益的平台。方便点在于,过去常常困扰于发现一些网站有设计上的疏失却不知该不该通报,如果认识该网站的开发者倒是还好可以直接讲,但对于其他不认识的,一来没有明确窗口,二来碍于工作关係怕被认为是敲竹槓,所以影响不大的漏洞可能就放水流了。

    这样放任其实不是一件健康的事情,漏洞在风险就在,有了这样的回报平台至少可以告诉企业可能存在风险,自己也可以放心通报。事实上,对岸有 类似的平台 已经行之有年,最显着的效果,就是对岸网站在 0 day 被揭露后能在一週左右全国修复,而以往可能好多年过去了漏洞还在。这真的能够加速保护企业和使用者,很高兴台湾也有了这样的平台!

    昨天早上收到了平台回报宏碁云端售票已经 修复的消息 ,既然已经修复且公开了,就顺便讲解这个问题的细节吧!希望其他开发者可以从中体会到攻击者的思维,进而做洽当的防御。

  • 验证及危害

    为了方便验证解说这个问题,这边特别用两个不存在的身分证字号在宏碁云端售票申请帐号,分别是 Z288252522 和 Z239398899。测试目的是登入帐号 Z288252522 后看看是否能利用上述 Cookie 问题读取 Z239398899 的个资。

    首先登入帐号 Z288252522,找到一个会回传个资的页面:

    号称 98 分的宏碁售票,差的那两分就在 Cookie 认证

    此时的 Cookie 值如下:

    号称 98 分的宏碁售票,差的那两分就在 Cookie 认证

    从图中发现 Cookie 的值其实是经过加密的,这点在上面说明攻击观念时刻意没有提及。把 Cookie 值加密是一种防止别人修改 Cookie 值的方式,攻击者不知道 Cookie 值的内容,自然也无法修改了。

    然而这样做还是存在些微风险,一旦这个加解密方式被找到,攻击者就得以修改 Cookie 内容,进而盗用别人身分。在本例中,若想凭着改变 Cookie 盗用别人身分其实可以不用花时间去解加密法,这里有一个小 trick,我们从观察中马上就能发现所有 Cookie 值都是用同一套加密方式,而且其中 USER_EMAIL、USER_NAME 这些还是我们可以修改的值。这也意味着如果我们把姓名改成我们想要加密的身分证字号,伺服器就会回传一个加密好的值给 USER_NAME。

    我们直接来修改姓名看看:

    号称 98 分的宏碁售票,差的那两分就在 Cookie 认证

    当姓名改成目标 Z239398899 时,Cookie 中的 USER_NAME 值就会改变成我们要的加密结果。耶!是一种作业不会写找出题老师帮忙写的概念 XD

    号称 98 分的宏碁售票,差的那两分就在 Cookie 认证

    接着直接把 USER_NAME 的值拿来用,複製贴上到目标栏位 USER_ACCOUNT 中,之后就是以 Z239398899 的身分来读取网页了。我们再读取一次 https://www.jody-ticket.com.tw/UTK0196_.aspx 看看:

    号称 98 分的宏碁售票,差的那两分就在 Cookie 认证

    成功看到 Z239398899 的资料了!如此,就可以只凭一个身分证字号读到他人的地址电话资讯,甚至可以帮别人抢票或取消票券。这个流程写成程式后只要两个 request 就可以尝试登入一个身分证字号,要大量偷取会员个资也是可行的了。

    说到这边,也许有人会质疑要猜中注册帐户的身分证字号是有难度的,但其实要列举出全台湾可能在使用的身分证字号并不困难,再加上宏碁云端的硬体其实是很不错的,事实也证明它能够在 短时间处理四千万个请求系统仍保持稳定 ,只要攻击者网路不要 卡在自家巷子口 ,多机器多线程布下去猜身分证字号效率应该很可观!

  • 建议原则

    这次的问题是两个弱点的组合攻击:

      宏碁云端售票为了效率和分流,使用 Cookie 认证是相当合理的设计,所以要解决这个问题,从第二点来解决会是最有效且符合成本的方式,怎幺改呢?推测原本的 SQL 语句应该类似这样:

      由于 USER_ACCOUNT 是身分证字号,容易穷举,更严谨的作法可以多判断一个 id,像是这样:

      从只需要告诉伺服器身分证字号就回传会员资料,到变成需要身分证字号和会员编号同时正确才会回传会员资料,至此,攻击者已经很难同时知道别人的会员编号和身分证字号了,因此大大降低了被猜中的机率,增加了安全性。

      Cookie 一直以来都是 Web Application Security 领域的兵家必争之地,攻击者无不绞尽脑汁想偷到或伪造它,前阵子举办的 HITCON GIRLS Web 课堂练习题第一题就是改 Cookie 来伪造身分,足见这个问题有多基本和重要。

      关于 Cookie,这里提供一点原则和概念供大家参考:

      首先,Cookie 是存在客户端的,所以有机会被看到、被窜改、被其他人偷走。基于这些原因,不建议在 Cookie 中储存机敏资料,或是存放会影响伺服器运作的重要参数,需评估一下这些暂存资料被人家看到或修改是不是没差,这是储存的原则。如果权衡后还是要在 Cookie 中存放重要资料,那就需要对值加密避免被读改,而且要确保加密的强度以及其他人是否能透过其他方法解析修改。最后,Cookie 最常被偷走的方式是透过 JavaScript,所以建议在重要的 Cookie 加上 HttpOnly flag 能有效的降低被偷走的机率。也来试着整理一下这一小段的重点:

      没想到信手拈来就是三不一没有,前面再加个勾勾,感觉好像很厉害呢!

    1. 结论

      由于 Cookie 存在浏览器端,有被窜改的可能,所以如果网站使用 Cookie 认证就会有一些安全上的风险。本篇就以宏碁云端售票为例,说明这种小疏忽可能会造成被盗用帐号的风险。开发者在面对使用者可以改变的变数一定要特别小心处理,做好该有的防护,还是老话一句:使用者传来的资料皆不可信!只要掌握这个原则,开发出来的产品就能够少很多很多风险!

      行文至此,预期中是要再推广一下漏洞回报平台,顺便称讚宏碁非常重视资安,修复快速,是良好的正循环。不过前两天看到一些关于宏碁云端售票的新闻时,上线发现此弱点仍未修复,这好像真的有点不应该,毕竟官方上週已经接收到通报,要修复这个弱点也只需一行判断式…。

      能理解这次的弱点在短时间开发过程中很难被注意到,对于这样一个一週不眠不休完成的售票网站,我其实也是给予满高的评价,但如果官方能再增两分对资安事件的重视,相信下次定能以满分之姿呈现在使用者面前!

    2. 相关文章  RELEVANT ARTICLES