A-Young-Programmer-Receives-36000-Bug-Bounty-from-Google.jpg作为一名新手Bug Hunter来说,信息安全真的是一门高深而广泛的学问,要发现漏洞,需要具备专业的知识、无比的耐心和一点点的运气。想要从小白成为漏洞赏金猎人(Bug hunter),实属不易,今天我和大家一起分享3个Google漏洞,它们也是我入门Web挖洞领域之初发现的3个漏洞。

漏洞1 – Google电子表格的邀请欺骗(INVITE SPOOFING)

漏洞发现

Google电子表格介绍:Google在线电子表格可以让每个用户建立100个电子表格文件,每个文件支持内嵌20个工作表,50,000个单元格,256列或10,000行。支持导入、导出XLS和CSV格式文件。支持字体加粗、下划线、斜体、颜色等常规排版。支持200多种公式用函数。 文件自动保存,对文档的每一次编辑,都会被自动保存在服务器。还可以邀请( invite)其他用户编辑、查看和评论文档,并且支持文档内即时聊天。

这个漏洞是我在把谷歌电子表格(Google Spreadsheet)分享给我的一位老师时偶然发现的。一开始不巧的是,我在设置为 anyone can edit 分享时不小心把分享人的邮箱地址填成了老师的非Gmail地址了,所以,就这样大意地把我做好的,且附带谷歌电子表格在线链接(link)的编辑邀请(invitation)发到了老师的非Gmail邮箱里了。

share.png

2018-12-18_104503.png当然了,老师如果登录他的那个非Gmail邮箱之后,按照谷歌文档的设置,需要对方注册登录Gmail邮箱才可编辑查看该在线文档,老师肯定是无法访问到我的Google Spreadsheet了。

正当我在考虑该怎么办时,我好奇查看了发送给老师邮箱的那个在线文档链接,它是形如以下这样的URL(这里暂且就用billgates@microsoft.com当做老师邮箱吧):

https://docs.google.com/spreadsheets/d/cmFuZG9t_c3ByZWFkc2hlZXQ_aWQ/edit?usp=sharing_erp&userstoinvite=billgates@microsoft.com

如果你是文档所有者,且是Gmail邮箱登录状态,那么,直接在浏览器中打开上述文档链接之后,文档会实现加载并跳出一个已经填写好的分享人邮箱地址的提示框,如下:

pop up share with other.png此时,首先映入我脑子的是,用户执行的输入就这样在DOM对象中被Reflect反射出来了,那么试试XSS又如何呢? 但是,随后我的消极想法占据了上峰:“我不可能是第一个发现这个漏洞的人,谷歌可是一家牛逼公司啊,世界上好多厉害人物都想尝试去破解渗透它呢,不要在XSS漏洞的Payload构造上浪费时间了……”。

你可以叫我是悲观主义者,但据我最近读到的一些关于Google XSS漏洞文章来看,确实很难发现Google的XSS漏洞。但是,这里还有其它东西引起了我的注意,那就是参数名称,也就是上述URL链接里的 userstoinvite,注意,这里是userstoinviteuser后面多了个s),而不是 usertoinvite,那么,也就是说它可以一次邀请多个用户。

确实是,只要在userstoinvite=后面的邀请人邮箱地址中添加逗号,就能把在线文档发送给多个邀请人了,好吧,想象一下,如果这个地方填写的东西和邮箱里的发件人区域一样,那么,我把某个邮箱地址指定为某个人名会怎样呢? 就象下面这样:

https://docs.google.com/spreadsheets/d/cmFuZG9t_c3ByZWFkc2hlZXQ_aWQ/edit?usp=sharing_erp&userstoinvite=Bill Gates<billgates@microsoft.com>

结果如我所料,userstoinvite=Bill Gates<billgates@microsoft.com>这种方式的填写,以文档所有者身份打开上述链接之后,最终会在邀请人填写区域只显示邀请人的姓名Bill Gates,只有当鼠标移动到姓名上时才会显示该姓名对应的邮箱billgates@microsoft.com。

02.png该漏洞可应用的攻击场景

用这种方式,可利用邮箱地址和任意名字的虚假对应关系来欺骗文档邀请(invitation),以此获得对某些特殊文档的访问编辑权限,这种攻击场景如下:

1、假设你已从某家公司离职,且你对公司某个重要谷歌电子表格的访问权限已经被撤销,但在浏览器记录里还能查询到其具体的访问URL;

2、利用以上漏洞,你可以把你的邮箱地址和该公司老板的姓名进行对应,简单把userstoinvite=Big Boss<youremail@adress.com>构造到文档URL链接中;

3、把构造的文档URL链接发送给公司秘书或会计人员;

4、秘书或会计人员打开链接后,Big Boss的大名迷惑其点击确定,以此让你自己再次获得对该文档的访问编辑权限。

漏洞上报进程

2017.10.03 – 上报漏洞

2017.10.03 – 谷歌把漏洞级别从P4提升到P3

2017.10.10 – 谷歌奖励$500美金

2018.01.16 – 谷歌修复漏洞

漏洞2 – 获取别人Google云盘中的照片

自从上述我第一个漏洞上报后,我的内心既激动又高兴,要知道那可是谷歌的漏洞啊,还收获了赏金,不错不错。但我也并不自满,我觉得任何人稍加点运气可能就会发现上述那个漏洞,所以,我还需继续努力提升和证明自己。但从哪里开始呢?

首先,肯定有很多人在用自动化工具检测过谷歌漏洞了,如果我再这样做就是浪费时间,我应该从一些不寻常的地方下手。我自认为自己对Web基本概念底子不错(如对SOP和CORS的理解),而且我还喜欢用Chrome 的开发者工具(Chrome Dev Tool),所以,我决定在JS文件中寻找一些不安全的API端点或敏感信息。我的思路可以抽象化如下:


for webapp in literally_every_online_google_product_I_have_found:

    devtools.open()

    devtools.select_tab('network')

    for button in webapp:

        button.click()

    for request, response in devtools.requests:

        request.analyze_manually()

        response.analyze_manually()

测试谷歌的在线服务和相关产品,真是一个漫长而无聊的过程,我花费了无数个下午和晚上来仔细分析其中的大堆请求和响应信息,一无所获,就连我自己都记不清尝试过多少测试手段了:

“漏洞有可能存在 CSS 中,或是其字体中呢?”

“如果我用我自己的另一个账户来重放(replay)这个请求如何呢?”

“喔,在这里我可以上传一些SVG文件,或是执行一些XSS测试”

后期,我把关注点放在了谷歌云盘(Google Drive)和谷歌文档(Google Docs)之上,因为它们功能和设置多样,受众面广泛,且与用户的在线存储内容相连,一旦存在漏洞就会比较严重。起初,我着重测试了Google 幻灯片(Google Slides),因为我发现它与 Google Docs 和 Google Sheets架构非常相似,但是,却在某些情况下应用了不同的API服务端接口,例如,当我从自己的谷歌云盘中向Google幻灯片中插入图片时,会触发以下两个请求:(Google幻灯片的服务入口为https://docs.google.com/presentation/,大括号{}内消息为响应内容)


curl 'https://docs.google.com/presentation/d/pReS3nTaT10N_1D/copyimages?id=bG9s_Y2hlY2tvdXR0aGlz_dDY4UkV1MEh3Qnc' --data 'photo=bG9s_Y2hlY2tvdXR0aGlz_dDY4UkV1MEh3Qnc'

{"bG9s_Y2hlY2tvdXR0aGlz_dDY4UkV1MEh3Qnc":"MDRjYWVhO-QtYjc0Ny00NDdkLWJlODctZ-VmNzVkOTI1YTkw"}

---

curl 'https://docs.google.com/presentation/d/pReS3nTaT10N_1D/renderdata?id=bG9s_Y2hlY2tvdXR0aGlz_dDY4UkV1MEh3Qnc' --data 'cosmoId=MDRjYWVhO-QtYjc0Ny00NDdkLWJlODctZ-VmNzVkOTI1YTkw'

{"r0":"https://lh6.googleusercontent.com/dmVyeXZlcnl2ZXJ5dmVyeXZlcnl2ZXJ5dmVyeXZlcnl2ZXJ5dmVyeXZlcnl2ZXJ5dmVyeXZlcnl2ZXJ5dmVyeXZlcnl2ZXJ5dmVyeXZlcnl2ZXJ5bG9uZ3N0cmluZw"}

从上述请求响应可以看出,第一个请求的响应内容中包含了形如:

“ID_OF_THE_IMAGE”:”SOME_RANDOM_ID” 这样的消息,有图片ID号(暂且称其为ID_OF_THE_IMAGE)和后续的一串随机字母数字组合串(暂且称其为SOME_RANDOM_ID),而在第二个请求的响应内容中,这个SOME_RANDOM_ID却是cosmoId参数的值,而且,第二个请求的响应内容中还包含了插入图片的具体访问链接。

为什么要用两个API服务端来处理一个图片上传请求呢,这机制有点稍显复杂了,为了深入探明究竟,我把上述请求的cookie值进行了替换。

我比较喜欢用内置的Chrome 开发者工具(Chrome Dev Tool)来进行请求调试,从中可以复制网络请求作为curl命令,用此方法,我把上述请求中涉及的cookie信息替换成了我另外一个有效session会话的cookie。这样一替换,让我感叹的是,其中竟然完全不需要任何身份验证机制,也就是说, 只要我在上述请求中,利用一个有效的Google session cookie信息,在知道目标图片ID号的前提下,构造请求链接,就能响应得到一个具体的图片访问URL链接。这种访问方式,只需知道目标图片ID号,就可以读取任意用户谷歌云盘(Google Drive)中的图片。

这算是一种直接对象引用漏洞,实际利用场景中,不足的条件是图片ID不容易获取,而且其ID串非常长,还要区分大小写,所以其攻击场景不算广泛,当然最终赏金也只有$500。

漏洞上报进程

2017.11.27 -  上报漏洞

2017.12.09 -  谷歌把漏洞级别从P3 提升至 P1

2018.01.09 -  收获$500 赏金

2018.01.16 -   漏洞修复

漏洞3 – 获取别人Google相册照片分享权限

有了以上两个漏洞发现之后,我有点累了,我觉得我的好运都用尽了,我需要重生。在休整一段时间之后的5月,我决定再搞一波测试。意外的是,只用了3个小时我就发现了一个厉害的漏洞,我自己都有点不敢相信,在上报之前还反复进行了多次验证。

前两次的漏洞测试中,我忽视掉了谷歌相册(Google Photos),所以这一次我打算故技重用,把目标放到它身上。在网络调试阶段,没什么特别的发现,但是其Shared Libraries功能却有点意思。

Shared Libraries :谷歌相册新推出的分享功能,例如你跟儿子合照的照片,会分享给家人,在家里就可以利用 Shared Libraries 设定,选择将整个照片库或某些照片,自动分享给给指定的家庭成员。也就是特定照片和特定分享人的设置功能。

如果你要在谷歌相册中设置特定分享人(Partner),那么你首先需要输入分享人的邮箱地址,提交之后,会跳出一个Google账户的登录提示框,接着,你输入你自己的登录密码完成登录,你的照片就会被分享成功,然后页面会跳转到一个只包含有分享成功(Success message)和关闭窗口(Close window)按钮的界面,弹出窗口的大小遮住了整个URL链接,所以我只有将它复制到记事本中进行进一步研究:

// URL before login

https://accounts.google.com/signin/v2/sl/pwd?passive=801337085&osid=1&continue=https%3A%2F%2Fphotos.google.com%2Finitps%3Frequest%3DW1tudWxsLCIxMjU4NzQyNzU5MTIzOSJdLG51bGwsImUtbWFpbEBleGFtcGxlLmNvbSIsbnVsbCxbMixudWxsLCJXVzkxSUhKbFlXeHNlU0JzYVd0bElfR1JsWTI5a2FXNW5JSEpoYm1SdmJTQmlZWE5sTmpRZ2MzX1J5YVc1bmN5QXRJR1J2YmlkMElIbHZkVDgiXV0.

// URL after login

https://photos.google.com/initps?request=W1tudWxsLCIxMjU4NzQyNzU5MTIzOSJdLG51bGwsImUtbWFpbEBleGFtcGxlLmNvbSIsbnVsbCxbMixudWxsLCJXVzkxSUhKbFlXeHNlU0JzYVd0bElfR1JsWTI5a2FXNW5JSEpoYm1SdmJTQmlZWE5sTmpRZ2MzX1J5YVc1bmN5QXRJR1J2YmlkMElIbHZkVDgiXV0.

从上述URL链接可看出,登录前的第一个URL链接中包含的continue参数值,为登录后第二个URL的转码链接,但是这两个URL中涉及的request请求值初看上去,是一串随机字母数据组合串,最后还有一个点。

request=W1tudWxsLCIxMjU4NzQyNzU5MTIzOSJdLG51bGwsImUtbWFpbEBleGFtcGxlLmNvbSIsbnVsbCxbMixudWxsLCJXVzkxSUhKbFlXeHNlU0JzYVd0bElfR1JsWTI5a2FXNW5JSEpoYm1SdmJTQmlZWE5sTmpRZ2MzX1J5YVc1bmN5QXRJR1J2YmlkMElIbHZkVDgiXV0.

这个点我有点不懂,为什么它会出现在末尾,貌似是填充物一样。但如果它相当于base64填充用的等号(=),这就说得通了,因为上述两个URL中的request都是相同的,所以把它替换为等号=之后,我尝试对request字符串进行了base64解码,确实是!

解码前:

W1tudWxsLCIxMjU4NzQyNzU5MTIzOSJdLG51bGwsImUtbWFpbEBleGFtcGxlLmNvbSIsbnVsbCxbMixudWxsLCJXVzkxSUhKbFlXeHNlU0JzYVd0bElfR1JsWTI5a2FXNW5JSEpoYm1SdmJTQmlZWE5sTmpRZ2MzX1J5YVc1bmN5QXRJR1J2YmlkMElIbHZkVDgiXV0=

解码后:

[[null,"12587427591239"],null,"e-mail@example.com",null,[2,null,"WW91IHJlYWxseSBsaWtlI_GRlY29kaW5nIHJhbmRvbSBiYXNlNjQgc3_RyaW5ncyAtIGRvbid0IHlvdT8"]]

有了这个解码结果,我非常兴奋,马上对其中的e-mail@example.com进行了替换,换成了我自己的邮箱地址,其它的不动,结尾加上点号(.),然后进行base64加密,构造出一个Payload URL。

基于第一个URL链接,当我用我的另外一个Google账户,打开上述构造的Payload URL之后,当前账户下的照片竟然能悄无声息地分享给了之前邮箱地址对应的Google账户,最要紧的是,这个过程没有任何警告、提示或邮件告知动作。我迫不及待地想对其进行深入分析,但最终,我没有完整做完针对第二个URL链接的测试,逻辑上说,攻击者只要发送一个GET请求到第二个URL链接上,可能不需要你的登录动作,就能分享你谷歌相册中的照片了。

漏洞上报进程

2018.05.12 – 漏洞初报

2018.05.14 – 谷歌把漏洞级别从 P4 -> P2,然后再从 P2 -> P1

2018.05.22 – 收获谷歌奖励的 $3133.70

2018.08.22 – 漏洞被修复

总结

Web漏洞挖掘最难的在于,自己要去关注什么东西,这种情况是大多数安全研究人员在漏洞测试项目中经常会遇到的问题,这样的好处在于,你可以不必把自己只限定在如XSS或SQLi等某些漏洞的条条框框内,所以,睁大眼睛,放开思路,总会有所发现。

*参考来源:avatao,clouds编译,转自FreeBuf