麦当劳外卖系统中的漏洞:从一分钱的订单到订单劫持

科技   2024-12-20 14:12   广东  

要点/摘要

印度麦当劳 McDelivery 系统(全球最受欢迎的外卖应用之一)存在 API 漏洞,导致出现多种有趣的漏洞:

🍟可以以 1 卢比(0.01 美元)的价格订购任意数量的菜单项。

🍟通过特定序列的精心定时的 API 调用来窃取/劫持/重定向其他人的交货订单的能力。

🍟检索任何订单的详细信息的能力。

🍟能够跟踪任何处于“在途”状态的订单。您可以实时跟踪任何订单的司机位置。

🍟能够下载任何订单的发票。

🍟可以针对非您自己的订单提交反馈。

🍟查看管理员 KPI 报告的能力。

🍟可能被访问的敏感司机/乘客信息:

🍔姓名
🍔电子邮件
🍔电话号码
🍔车辆牌照号码
🍔个人资料图片

读到这篇文章的每个人都知道麦当劳,甚至可能在今天上班的路上在那里吃过早餐!小时候,我喜欢吃开心乐园餐,有时还会去 Play Place 玩耍。虽然我现在很少去那里吃饭,但麦当劳通常是我旅行时安全可靠的首选。最近几个月,我决定尝试寻找食品行业的漏洞。美国麦当劳没有官方的漏洞赏金计划,所以我没有去。不过印度麦当劳有,所以我从那里开始搜索。接下来是一段令人兴奋的经历,帮助世界上最具标志性的品牌之一在恶意黑客入侵之前修复安全问题。

印度麦当劳,特别是印度麦当劳(西部和南部)/ Hardcastle Restaurants Pvt. Ltd.,在印度西部和南部拥有/经营麦当劳餐厅。他们还运营着一个名为McDelivery的系统,正如您所猜测的,该系统允许人们订购麦当劳外卖。您也可以订购堂食和外带食物。McDelivery 在许多其他国家/地区也有提供,但印度已经开发了他们自己独有的定制网络应用程序。

McDelivery 可通过https://mcdelivery.co.in/在线和移动应用程序使用。目前,它在Google Play上的下载量已超过 1000 万次,在Apple App Store的食品和饮料类别中排名第 16 位(截至 2024 年 12 月 11 日)。它绝对非常受欢迎。

McDelivery 主页,2024 年 11 月 12 日

McDelivery 也不仅限于送餐。您可以选择多种方式来获取食物:

McDelivery 对安全问题并不陌生。早在 2017 年,就发生了一起泄露用户数据的事件。自那以后似乎没有发生什么值得注意的事情,所以安全性似乎一直很好……直到我开始拆开它。

穿过拱门

McDelivery 网站和移动应用程序使用Angular构建,Angular 是一种流行的单页应用程序框架。它非常适合这种面向消费者的高交互性应用程序。第一件事是寻找一些路线,看看这个 Web 应用程序提供了什么样的功能。没过多久就找到了与订单相关的有趣路线:

此时,我完全不知道订单、购物车或用户 ID 是什么样子的。在这些情况下,我倾向于尝试“0”或“1”来测试它们是否是简单的整数值。在浏览器地址栏中,我输入了“订单跟踪”路由,其中包含orderId、cartId和userId的值。瞧,我得到了结果!

这不是最酷的动画吗?

我很震惊,这是多么容易。这种漏洞被称为“对象级授权失效”或“BOLA”。这是我经常看到的非常常见的漏洞。麦当劳外送中发现了许多 BOLA。

深入研究网站的代码和网络活动后,我发现最终只有订单 ID 才重要,我将其设置为 1。它在 2 个请求中使用:

🍟首先是订单状态。这包含订单的基本信息。这里没有什么特别敏感的信息。

🍟第二,订单地点。


订单 ID 是连续的,这意味着您可以不断将数字加 1 以获取下一个订单的详细信息,从而获取更多用户信息。不好!

这些 API 调用中,最突出的一点就是 JWT 令牌。此时,我尚未创建帐户,也未登录。该令牌来自加载网站时在后台运行的访客登录 API 调用:

看到某种身份验证令牌与 API 一起使用总是件好事。你会惊讶地发现有多少大公司忘记使用这种令牌。然而,尽管在这种情况下有有效的身份验证,但似乎有些不对劲,因为我作为访客用户能够访问另一个用户的订单详细信息。

黄金点评

我开始增加该订单 ID,并注意到订单 ID 6 有一个新部分,您可以在其中留下对订单的反馈。之前的订单已经过审核,而订单 6 尚未审核。这些早期的测试订单是由开发人员制作的,所以我决定尝试留下评论,看看是否会被接受:

API 很高兴接受我的评论:

然后,我稍微调整了一下 API 调用,尝试检索我之前的最后一条评论。上述 API 调用的响应包含一个 ID,该 ID 用作我刚刚留下的评论的 ID。我从该数字中减去 1,然后发出新的 API 请求。它成功了:

绘制配送地图

回到 Angular 路线,我想尝试的下一个是乘客跟踪。这个也需要订单 ID。此页面充当实时跟踪系统,显示送货司机的位置。该页面不适用于测试订单 ID 1 或 6,因为它们很久以前就“交付”了。我需要一个真正的订单,一个现在正在路上的订单。

我刚刚玩过的订单反馈 API 包含了解决方案。当我检索到我之前的最后一条评论时,它包含一个重要线索:订单 ID。现在我有了一个起点来尝试查找最新订单。经过大量的 ID 操作后,我最终找到了一个正在路上的订单:

开发人员的另一个很酷的设计:送货司机自行车——位于 M 图标旁边。

就像订单跟踪页面一样,有一个底层 API 提供司机的经纬度。它还提供一些额外信息,例如他们的电话号码、电子邮件、姓名和车牌号。

您可以轻松地使用不同的订单 ID 重复此请求,以收集有关不同司机的个人信息。

任何人都可以成为麦当劳外卖司机或“骑手”。有一个应用程序可以做到这一点,而且它似乎像你期望的那样工作——注册、设置你的空闲时间,然后就可以开始了。

请检查

我注意到在订单跟踪页面上,“发票”链接会触发 API 调用来下载订单的原始发票。此外,在 JavaScript 代码中挖掘后,我发现了第二个 API,用于以略有不同的格式生成发票。这两个 API 都容易受到订单 ID 操纵,因此可以下载任何订单的发票。

创建账户

创建 McDelivery 账户需要印度电话号码来获取验证码。尽管我尽了最大努力,但我还是无法通过这种方式成功创建账户。没有账户,你就无法下订单,所以研究就此结束了……直到我发现了一个秘密的用户创建 API。

一时兴起,我向根身份验证 API 路径发送了一个 GET 请求,它返回了一个 API 端点的小列表:

你会把这称为麦当劳的“秘密菜单”吗?🤔

用户/创建 API 最受关注,因为它与正常的注册流程不同,并且未在应用程序中的任何地方使用。由于没有参考资料来制定有效的请求,我不得不自己弄清楚。幸运的是,一个空的 POST 请求促使 API 告诉我它期望什么:

然后我就能成功创建一个帐户,无需任何验证:

这是关键的第一步,但只是成功的一半。虽然这样可以创建账户,但登录需要通过验证码,因此目前如果无法检索验证码,仍然无法登录。

再次查看路由时,最后的线索出现了。存在一个隐藏的“auth-with-password”页面,可以使用密码登录。尽管有占位符文本,但该页面功能齐全,我能够登录:

登录后并提示我完成我的个人资料。

大买卖:只要一分钱就可以点任何东西

有了账户,现在就可以开始做正事了:订单/结账流程。此时我已经有了一些重要的发现,但我仍然渴望再多了解一些。

开始时,系统会要求您确认您的位置。系统会显示一张地图,您必须在其中放置图钉。我将选择我想象中的游艇:

然后,您只需浏览菜单并将您想要的任何东西添加到购物车中。我是我想象中的游艇上的一位慷慨的主人,所以我决定为每个人准备薯饼,并为我自己准备一杯特别的饮料。我喜欢麦当劳的薯饼,其他人也喜欢(对吧?)

你能发现问题吗?底部写着“所选地址无法使用”。我伤心欲绝,想看看肯德基是否会接受我的钱。但 Angular 应用程序注定要出问题,所以我做了一个简单的技巧,从按钮中删除了禁用属性。这样做成功了:

我现在可以点击按钮并重定向到支付处理器Juspay。

现在我又遇到了一个新问题:太贵了!大约 68 美元。我想要折扣。

让我们逐步了解订购流程。

购物车和商品

这确实没有什么奇怪的。当您将商品添加到购物车时,如果您没有活跃的购物车,则会首先创建一个购物车。购物车由 GUID 表示。创建购物车后,您可以将商品(使用商品的 ID)添加到购物车对象。这很简单,是一种非常常见的设计。

订购与结账

当您将商品添加到购物车并想要付款时,请转到结帐页面。您查看商品和总价。使用购物车 ID,向订单 API 发出 POST 请求,该 API 返回用于重定向到 Juspay 进行付款的信息:

我研究了是否可以在那里编辑金额字段。另外,如果你有其他用户的帐户 ID,我想也许你可以把它放在那里,并使用其他人存储的付款方式来支付订单。不幸的是,修改这些字段的所有尝试都失败了,原因如下。

有一个签名涵盖了orderDetails。它包含所有需要修改的键值,以便获得任何乐趣。除了 orderDetails 之外,还有一些字段,但更改它们不会产生预期的结果。签名在服务器端生成如下:

🍟订单 API 接受您的购物车 ID 并从购物车对象中提取所有需要的信息。

🍟创建 orderDetails 对象,并基于该对象创建 RSA 签名。

🍟两者都返回给客户。

这是一个好的设计示例,因为它确保客户端无法篡改重要值,例如要支付的金额。有关签名过程的更多信息,请参见此处。

我开始相信这是一条死路。开发人员在这方面做得对,泄露他们的 RSA 私钥的可能性很小。任何成功的希望都涉及在RSA 签名之前篡改数据。

我退后一步,看着购物车对象,一个想法浮现在我的脑海里。购物车对象能够接受商品更新,但它也能接受价格更新吗?我整理了一个 PUT 请求来更新价格。令人惊讶的是,它成功了:

这种漏洞被称为“对象属性级别授权失效”或“批量分配”。与 BOLA 不同,这是一种不常见的漏洞,我通常从未成功发现/利用过。似乎可以通过这种方式更新大多数 McDelivery 对象和字段,为许多可能性打开了大门。

我暂时抑制住了自己的兴奋,因为服务器在创建 orderDetails 对象并签名之前仍有可能重新计算价格。唯一的测试方法是再次结账。我再次结账,订单创建现在看起来非常有希望!

orderDetails 包含我们的自定义价格,并且我们有一个有效的签名。Juspay 结账将很乐意接受这一点。便宜的价格还启用了新的“货到付款”付款方式,这使得完成结账变得更加容易。

我决定尝试完成结账。我找到了一个取消 API,可以在订单处理得太慢之前快速取消。结账如预期成功。

数量一下子消失了,就像魔术一样!

你能数出麦旋风被搅拌了多少次吗?

您可能有一个疑问,如果订单没有取消,订单真的会送达吗?我相信,如果您提供了正确的地址并且没有提供太多物品,订单就会送达。虽然我知道印度人很乐意测试,但我决定不这样做,因为这会对公司造成财务欺诈。这将是一个过分的举动。

还值得注意的是,价格为 0 不起作用,因为 Juspay 要求金额大于 0,所以不可能免费订购任何东西。

窃取他人的订单

肚子还有些饿,我想试试看是否有可能窃取/重定向其他人的订单到我的地址,或者让其他人为我付款。我为这次测试创建了另一个帐户。我没有针对任何真实用户进行测试——重要的是不要对合法订单造成任何干扰,也不要欺骗或诱骗任何人。

我尝试做的第一件事是编辑购物车对象上的用户 ID。API 接受了更改,但结账时导致内部服务器错误。我没有其他办法尝试访问其他用户的付款选项来支付我的订单,因此我继续尝试重定向现有订单。

这次测试的目的是尝试更新另一个帐户下的订单,以便将其发送到我的地址而不是他们的地址。而且他们也无力阻止。我为此准备了 2 个帐户 - 将帐户 1 视为我的帐户,将帐户 2 视为受害者。

步骤 1:设置地址

两个帐户的地址簿中都需要一个地址,因此我随机选择了一些地址:


API为第一个账户分配的地址ID是29459202。

第 2 步:付款

然后受害者创建订单并被重定向到 Juspay 进行付款。在他们输入付款信息并确认付款之前,我的账户将对受害者账户的订单执行 PUT 请求,以将他们的地址 ID 替换为我的地址 ID。API 响应包含新的地址 ID,表示成功:

之后,受害者支付了订单,却不知道地址在幕后被更改了。但如果他们进入订单历史记录并查看更多详细信息,他们可能会注意到地址是错误的!😱

需要明确的是:此漏洞利用非常依赖时间,您必须在特定状态下找到顺序才能使漏洞利用起作用。

从受害者/账户 2 的角度看到的订单截图。地址已更改为我的/账户 1 的地址。

步骤 3:外卖

为了防止受害者注意到更改并可能取消订单,有一个可选步骤:将订单重新分配给我的帐户。这是通过对订单的另一个 PUT 请求来完成的,以将用户 ID 更改为我的帐户:

此后,该订单将完全与受害者的账户解除关联,现在在我的账户订单历史记录中。当然,已全额付款。

从矿场/账户 1 的视角看到的订单的截图。

据推测,受害者现在完全无法控制他们的订单。如果他们打电话给客服,他们可能也看不到,而且会有很多指责。

真实攻击场景

这种攻击需要仔细把握时机才能成功。更改订单地址时,只有订单处于“已启动”或“待处理”状态时才会成功。订单会迅速脱离这些状态,因此需要快速采取行动。

管理面板

McDelivery 的管理面板位于https://oms.mcdelivery.co.in/,似乎比消费者网站更安全!我找不到任何进入的方法,但我确实找到了一个管理端点来查看接受消费者 JWT 令牌的KPI报告。所有其他 API 都拒绝了该令牌。出于保密性考虑,KPI 数字不能共享,所以请不要询问。

有罗纳德麦当劳站岗,难怪这里基本上是安全的!

时间线

我整理了一份 24 页的报告,详细介绍了所有漏洞,并将其发送给McDelivery 漏洞赏金计划。总体互动是积极的。由于我的报告中详尽的细节,他们第一次就正确修复了所有问题,不需要我提供任何额外信息。我印象深刻。与我合作过的其他公司相比,他们的回复速度有点慢,但所有问题都在标准的 90 天期限内得到解决,并获得了赏金。

我还想特别指出,该系统有漏洞赏金计划,这真是太棒了。麦当劳美国分公司并不关心官方漏洞赏金计划。甚至 HackerOne 也指出了这一点!有趣的是,麦当劳印度分公司对安全更加重视。虽然在一个已经存在多年的成熟系统中出现如此严重的安全漏洞令人惊讶,但我很高兴他们有远见,创建了一个漏洞赏金计划。许多其他公司可以向他们学习。

🍟2024 年 7 月 20 日:报告已发送。

🍟2024 年 7 月 24 日:收到回复,确认已收到我的报告,并将在 7-10 天内进行调查。

🍟2024 年 8 月 7 日:我发送后续邮件询问任何更新或反馈。

🍟2024 年 8 月 23 日:收到回复,确认所报告的问题已在内部得到验证。我们还开始讨论奖励方案。

🍟2024 年 9 月 5 日:收到回复,告知我开发仍在进行中。

🍟2024 年 9 月 29 日:我检查了今天报告的问题并确认所有问题都已修复。

🍟2024 年 10 月 10 日:确认所有报告的问题都已解决,他们将奖励我一张价值 240 美元的亚马逊礼品卡。

🍟2024 年 10 月 13 日:我接受礼品卡并要求他们以电子方式发送。

🍟2024 年 10 月 23 日:我再次向他们确认可以通过电子方式发送礼品卡。

🍟2024 年 10 月 28 日:他们告诉我礼品卡正在内部审批中。

🍟2024 年 11 月 12 日:收到礼品卡。

🍟2024 年 11 月 18 日:向麦当劳印度公司发送披露博客,征求他们的反馈。

🍟2024 年 12 月 17 日:博客获得印度麦当劳批准。

🍟2024 年 12 月 19 日:发布

今年给家人送的圣诞礼物花费会少一些!

鉴于调查结果的严重性,我厚着脸皮建议他们让美国麦当劳给我发一张金卡。不幸的是,他们没能做到这一点。

2024 年 11 月 17 日博客评论的幕后花絮。

McDelivery 用户非官方常见问题解答

如果您以前使用过 McDelivery 并且感到担心,希望这个常见问题解答能够帮助您解答所有疑问。


问:印度以外国家的 McDelivery 系统是否受到影响?

答:其他国家使用不同的 McDelivery 系统,不会受到相同攻击。


问:印度北部和东部受影响吗?

答:不受影响——印度北部和东部的餐厅属于不同的公司,没有相同的 McDelivery 系统。只有印度西部和南部的麦当劳受到影响。


问:我应该重设密码吗?

答:不需要——这些漏洞都不会危及账户安全,因此如果您的账户已设置密码,则无需更改。


问:我应该更改我的电话号码吗?

答:不需要,但如果您收到有关登录代码的短信,请务必不要将其透露给任何人!


问:我的个人信息被泄露了吗?

答:印度麦当劳告诉我,他们已经检查了相关 API 调用日志,没有发现可疑的 API 调用模式。他们确信没有客户数据被泄露。


问:我的付款方式是否被泄露/我需要取消我的信用卡吗?

答:不需要——印度麦当劳不会存储您的付款方式,而且他们使用的支付提供商(Juspay)似乎按照行业标准存储了付款方式。印度麦当劳针对 2017 年的事件发表了一份声明,至今仍然如此。


问:我需要更新我的应用才能获得安全修复吗?

答:所有修复都是在服务器端完成的,不需要更新应用。不过,保持应用更新仍然是一个好主意。


问:现在使用 McDelivery 安全吗?

答:安全——印度麦当劳已有效修复所有已报告的安全问题,重新测试后未发现其他风险。请放心订购您的下一份薯饼!



感谢您抽出

.

.

来阅读本文

点它,分享点赞在看都在这里

Ots安全
持续发展共享方向:威胁情报、漏洞情报、恶意分析、渗透技术(工具)等,不会回复任何私信,感谢关注。
 最新文章