00:00:00(键盘敲击声) 我想看看正在发生的这个Honey大丑闻。
00:00:12如果你不熟悉Honey,Honey是那种优惠券Chrome扩展程序之一,这意味着它的所有代码我都可以查看。
00:00:19所以我可以看看这些YouTube视频中指控的事情,我可以实际看到,这是真的在发生吗?
00:00:26但更重要的是,
00:00:27对于扩展程序,
00:00:29我实际上可以纵观时间线来看,
00:00:32这些糟糕的决定是否一直在被执行,
00:00:35软件工程师们是否不仅继续这样做,
00:00:39还进行了改动来让这些不良行为变得更好、
00:00:43更稳健?
00:00:44是的,他们确实这样做了。
00:00:45我会向你展示这是如何发生的。
00:00:47但我知道你们中有很多人可能完全不知道发生了什么。
00:00:50你甚至不太熟悉Honey。
00:00:52所以你从来没有真正了解过情况。
00:00:55这实际上涉及到Honey的一个非常具体的操作,我想详细说明一下。
00:00:59所以我们实际上要看这个最新Honey揭露视频中的一个三分钟片段。
00:01:05然后我要讲讲如何查看压缩代码,以及我到底发现了什么,还有背后的意图,这有点令人惊讶。
00:01:12现在,如果说有什么比欺骗更让人讨厌的,那就是盗窃。
00:01:15在我的第一个视频中,我向你展示了Honey是如何从网红那里窃取钱财的。
00:01:19但我没有告诉你的是,这种行为在大多数情况下是严格不允许的。
00:01:25你看,
00:01:25运营这个行业的公司,
00:01:27也就是联盟营销网络,
00:01:28非常清楚像Honey这样的优惠券扩展程序很有可能从网红、
00:01:33博主和其他内容驱动的联盟成员那里抢走佣金。
00:01:37更重要的是,他们也明白这是不公平的,尤其是在"最后点击获胜"政策下,这一直是行业标准。
00:01:46所以为了防止这种类型的佣金盗窃,大多数主要的联盟营销网络执行所谓的退让政策。
00:01:53让我展示一下在Honey上是什么样子的。
00:01:55让我们先访问newegg.com,不使用联盟链接。
00:01:58如你所见,Honey立即弹出提供返现。
00:02:02但如果我们再做一次,这次使用我的Newegg联盟链接,你会注意到Honey根本没有弹出。
00:02:08如果我们点击Honey图标,你可以看到Honey现在被禁用了。
00:02:12所以这就是当用户已经点击了别人的联盟链接时,Honey应该有的行为。
00:02:17那么你要问,所谓的欺诈在哪里呢?
00:02:20嗯,事实证明,Honey一直在他们的应用程序中内置了退让系统,但他们一直在有选择性地决定何时以及对谁应用这些规则。
00:02:28让我们再测试一次我的Newegg联盟链接。
00:02:31只是这次我同时打开了两个完全独立的Chrome浏览器,每个浏览器都登录了不同的Honey账户。
00:02:38左边的Honey账户有零返现积分,而右边的Honey账户已经积累了返现积分。
00:02:45现在,当我在两个浏览器上打开Newegg联盟链接时会发生什么?
00:02:49左边的Honey账户像第一次那样退让了。
00:02:52但看看这个,右边有返现积分的账户没有退让。
00:02:58那么这是为什么呢?
00:02:59所以这就是我想测试的东西。
00:03:01我想仔细研究这个,因为这是代码。
00:03:03我能理解代码。
00:03:05我可以查看下载的JSON数据,我能理解它。
00:03:09不仅如此,AI的力量将让我能够以我整个编程生涯中从未有过的速度搜索压缩代码。
00:03:18所以我们做的是,首先获取了一堆Honey的版本。
00:03:22所以我查看的版本大约从2019年2月开始,一直到现在的1901版本。
00:03:29有了这些,我想做的是,好吧,首先,这种根据用户积分来决定何时显示以及何时不显示退让菜单的机制,它存在吗?
00:03:38是的,它确实存在。
00:03:40但真正的问题是,它有没有发生变化?
00:03:43因为我在大公司工作过,对吧,你也在大公司工作过,我相信你们中有些人也是,你知道有时候代码就这么一直存在着。
00:03:50你知道的,就像是个小失误,它就一直在那儿,五年来没人改过它,事情就是这样。
00:03:55这就是我想要找的,也就是说,代码是不是一直保留着?
00:04:00还是有过重大的变更?
00:04:03不是那种小的bug修复。
00:04:05好吧,为了避免版权问题,因为显然PayPal的律师会用DMCA打击任何真正展示代码的人。
00:04:13这意味着我得在老式黑板上做这种奇怪的哑谜式演示来给你们展示发生了什么。
00:04:18所以从版本11开始,记住,大约是2019年,这个版本确实有降级逻辑。
00:04:25它甚至有被称为SSD降级逻辑的东西。
00:04:29它与下发的包含大量数据的JSON文件相匹配。
00:04:32这是我对一个完全没有登录的用户的降级处理,最基本的东西。
00:04:38在这里,你可以看到UP是用户积分。
00:04:41ADB是类似广告拦截器最后使用时间。
00:04:45还有账户是否已登录。
00:04:47还有一些其他字段时不时会出现。
00:04:50所以有趣的是,在2019年的版本11中,情况通常是这样的。
00:04:55有一个巨大的switch语句,最终有这些case分支,就像是,好吧,嘿,我们要测试邮箱吗?
00:05:02是的,它真的有一个字符串。
00:05:04这个邮箱是否包含test?
00:05:06然后总是降级,顺便说一句,很可疑。
00:05:10它在避免这些链接测试账户进来,像link share test那样去看这个是否真的有效?
00:05:16因为说实话,在座的谁没有一个不包含test的测试账户呢?
00:05:20我肯定有。
00:05:22但无论如何,这里就是一个明确的检查。
00:05:24如果你的邮箱中任何地方有test这个词,它就会禁用你。
00:05:29但更重要的是,
00:05:30我的意思是,
00:05:31这个已经讨论过了,
00:05:32但更让人困惑的是它会经过一系列检查,
00:05:35然后会说,
00:05:36嘿,
00:05:36当前激活的提供商是否等于LS,
00:05:39也就是link share?
00:05:41如果是的话,我要你应用这些确切的规则。
00:05:44然后在后面,
00:05:45它有这样一个检查,
00:05:47它会遍历所有已经确定的规则,
00:05:49然后在一个小的for循环中逐一检查这些规则,
00:05:52看它们中是否有任何一个失败?
00:05:55如果其中任何一个失败,它就会降级。
00:05:57所以这是一个相当硬编码的过程,正如你所看到的,因为有像这样的字面行说,如果是link share,就做这个动作。
00:06:06如果我们在另一个提供商那里,就做别的事情。
00:06:08现在我当然参与过很多很多项目,这种事情经常发生。
00:06:12这完全正常。
00:06:14你刚开始的时候会想,好吧,嘿,我们可能有一两个提供商,就是这样。
00:06:18所以我就在这里放几个硬编码的边界情况,我们只要确保事情以某种方式得到处理就行。
00:06:24我们降级一段时间,顺便说一句,这不是很长的部分。
00:06:27你应该看MegaLeg的视频来了解这些规则究竟有多糟糕。
00:06:34但同样,我的目标是去看,好吧,他们对代码做了修改,它们是bug修复吗?
00:06:39发生了什么?
00:06:40嗯,这就是事情变得有点混乱的地方,因为在版本11到14之间,我相信一直到2022年,是的,2022年,情况基本保持不变。
00:06:52真的没什么变化,有一点编辑,没有什么真正值得展示的。
00:06:56但大约从版本16开始,也就是2024年,进行了一次强大的重构,这样他们就可以从Honey的一个端点驱动很多这些决策。
00:07:07现在这个端点下发一个看起来像这样的对象,它有这个基础值,然后它有这些值,然后在X下有这些值。
00:07:16所以这意味着之前的版本,它使用了一堆if语句系列来确定它想要执行的行为类型。
00:07:23然后它会进行规则评估,看看这条规则是否真的通过了?
00:07:28我们实际得到的是 true 还是 false?
00:07:30但在版本 16 中,他们决定在软件工程方面做得更深入一些。
00:07:36我们都知道,当你有一堆 if 语句在对数据进行包装并对对象进行基本修改时,你会怎么做?
00:07:45你会想通过某种配置来驱动它。
00:07:48你会想通过更动态的方式来驱动它,让它更容易维护。
00:07:52而这正是他们所做的。
00:07:53如果我们回到这里看看从我这个未登录的 Honey 用户那里传下来的数据,你会看到这里有一个基础类。
00:08:00这个基础类将成为 Honey 如何做出判断的基础对象。
00:08:05现在对于这个未登录用户的基础类,我需要 65,000 个用户积分才能让 Honey 不退出。
00:08:13如果我的积分少于 65,000,记住我没有登录所以我有零积分,它会说,抱歉,我要退出了。
00:08:18我要避开这个。
00:08:20现在,当它获得这个基础类后,它接下来会检查它是如何到达这里的?
00:08:25我们是从哪里到达这里的?
00:08:27我们为什么会到达这里?
00:08:28然后它会进行下一个检查,这是否来自这些联盟网络之一?
00:08:32然后它会开始包装这些东西。
00:08:33所以,好吧,如果我来自一个 link share 的地方,它现在只会让我需要的积分变成 5,001。
00:08:40它会编辑这个基础对象。
00:08:41它实际上在做更好、更复杂的工程实践。
00:08:44它不再是一系列硬编码的 if 语句了。
00:08:48相反,它实际上在说,嘿,取 base 对象。
00:08:51然后我想说,你有我的提供商吗?
00:08:55如果你有我的提供商,我想展开我提供商的值,或者只是一个空对象。
00:09:01然后它做了一些更疯狂的事情,就是这里 X 下面的所有这些。
00:09:07这些都是特定商店的值。
00:09:09然后它会检查,嘿,无论我现在在哪个商店,我也想把那些值放上去。
00:09:17然后它会执行基本的规则逻辑,表明它不再处于某种维护模式下。
00:09:23它表明这不再是那种存在了十年的硬编码、粗制滥造的东西。
00:09:29相反,他们从那种方式转变了。
00:09:31在 2024 年,他们说,你知道吗?
00:09:33我们需要更稳健,我们需要能够以更容易维护的方式对更多商店和更多提供商做出更多决策。
00:09:43这是软件工程人员的工作,他们做到了。
00:09:46所以当我看到这个时,我看到的是随着时间的推移,他们做出了改变来让他们的系统变得更好,这意味着背后是有意图的。
00:09:54他们想保持这个系统正在做的事情,无论它是否存在欺诈。
00:09:59我不能说那是由别人来决定的,但我至少可以说他们的决定是让它更稳健和更好。
00:10:07考虑到人们普遍认为这个系统相当可疑,他们已经让他们这个相当可疑的系统变得好多了。
00:10:16但我发现的不止这些。
00:10:17我发现了其他一些引起我兴趣的东西。
00:10:19我不断看到 VIM 这个词一直出现。
00:10:23我想,VIM,文本编辑器在做什么?
00:10:26当我问 Claude 关于这个时,它实际上说,嘿,你说的是在 Honey 里找到的 VIM 实例管理器吧?
00:10:34我就想,VIM 实例管理器。
00:10:35好吧,不可能是这个。
00:10:37不是这个。
00:10:38然后当我开始查看这个时,
00:10:40我最终看到的是在 Honey 插件内部运行着一个完整的 JavaScript in JavaScript 引擎。
00:10:49现在,这绝对是我见过的最奇怪的事情。
00:10:54我试着去查阅一些资料。
00:10:56我不是 Chrome 插件开发的专家。
00:10:59所以我不知道为什么有人会在 JavaScript 中运行 JavaScript。
00:11:05但 Honey 做的是它实际上有 Acorn,
00:11:08这是一个 JavaScript 解析器,
00:11:11可以从有效的 JavaScript 中生成 AST。
00:11:14它接收这个,评估 JavaScript,然后将其输入到这个 VIM 引擎中。
00:11:19现在代码中有几处引用实际上指向另一个叫做 cart ops retrieval JS 和 product ops retrieval JS 的对象,
00:11:29这些对象有时不为空,
00:11:30实际上包含代码。
00:11:31它还引用了这个 JS 代码,有时也不为空,就像这里,它是真实的 JavaScript 代码。
00:11:38但据我所知,它实际上并没有执行这些代码。
00:11:41我尝试设置了一些断点。
00:11:42我从未真正触发过它,但不管怎样,这确实存在。
00:11:47他们已经设置好了机制,能够以一种非常非常混淆的方式,基于 Honey 返回的任何内容在你的机器上执行远程代码。
00:11:57这是 JavaScript 中的 JavaScript,他们有一个 JavaScript 解析器。
00:12:00他们有一个 JavaScript 虚拟机。
00:12:03这是 JavaScript 里的真实 JavaScript。
00:12:06但他们还有这么一个部分,里面全是这些字符串化的函数。
00:12:11还有大量内联的 JavaScript,充满了他们搜索页面等各种方式。
00:12:18但这些是随产品一起下发的。
00:12:22所以从技术上讲,它们并不违反旧的 Google 服务条款。
00:12:26因为如果你看看针对 manifest V3 的附加要求,
00:12:29对于任何做这件事的人来说,
00:12:31你不应该被允许使用 JavaScript eval。
00:12:33好的,所以我们不会那样做。
00:12:34我们不会用 eval。
00:12:35我们要做的是硬编码一些我们不想让其他插件知道的操作。
00:12:40然后我们会整合一个完整的 JavaScript 引擎来运行它们,以进一步混淆我们正在做的事情。
00:12:47有趣的是,
00:12:48这个 V3 看起来就像是专门为 Honey 设计的,
00:12:52因为它说构建一个解释器来运行从远程源获取的复杂命令,
00:12:56即使这些命令是作为数据获取的。
00:12:59所以他们绕过了这一点。
00:13:00这些不是远程的东西。
00:13:01这些是在 Honey 扩展中实际可用的字符串。
00:13:05但天哪,这混淆得够厉害的。
00:13:07这真是奇怪的东西。
00:13:09我个人完全无法理解为什么会出现这种情况的任何理由。
00:13:14就像我说的,显然这是由于与其他扩展的交互,其他扩展指的是广告拦截器。
00:13:19显然,
00:13:19如果 Honey 扩展直接运行某些函数,
00:13:23广告拦截器可能会拦截它,
00:13:25但不知怎么的,
00:13:26通过这个奇怪的解释器,
00:13:28它能够实际运行避免被捕获的内容。
00:13:31我不知道,但在我看来这简直是一团乱麻。
00:13:34我发现这非常非常有趣,因为我从未做过任何逆向工程。
00:13:37我从未真正看过别人的源代码,尤其是压缩过的源代码。
00:13:41我只是想给你们展示一下这个。
00:13:42这也许是我一生中见过的最不寻常的工程设计。
00:13:46我曾参与过有一万多行奇怪状态机的代码库,难以使用,难以理解,但这个必须拿第一。
00:13:57这必定是我见过的最复杂、最奇怪的装置,鲁布·戈德堡级别的。
00:14:03此外,用于执行 stand down 操作的动态规则非常强大。
00:14:08无论目的是否具有欺诈性,它都被设计成动态的,并通过 JSON 按每个商店、每个提供商和每个用户进行控制。
00:14:19但无论如何,我想特别向 Magalega 致敬。
00:14:21真的太棒了。
00:14:22我有机会和他聊天。
00:14:23他帮助我看了一些东西。
00:14:25所以向他致以崇高的敬意。
00:14:26你绝对应该看看这个视频。
00:14:27链接在描述中。
00:14:28做得非常好。
00:14:29有好几个视频,我建议你全部看完。
00:14:32它们真的非常非常好。
00:14:33另外,你喜欢我做的这个吗?
00:14:35你喜欢这种形式吗?
00:14:36我不知道。
00:14:37这对我来说有点新。
00:14:38这只是我在直播中花时间玩得开心,然后向你们汇报。
00:14:42如果你在直播中,你会看到这个现场发生。
00:14:44对你来说可能会有趣得多。
00:14:45名字叫我不是逆向工程师,但这真的很有趣。
00:14:50我能理解为什么人们会做这个。
00:14:51再见。
00:14:52嘿,那是 HTTP?
00:14:55别用那个。
00:14:56我们不是这样点咖啡的。
00:14:57我们通过 SSH 点咖啡,terminal.shop。
00:15:00想要真正的体验?
00:15:02想要真正的咖啡?
00:15:03想要超棒的订阅服务,让你再也不用费心记着?
00:15:06想要独家拼配、独家咖啡和独家内容?
00:15:12那就来看看 CRON。
00:15:13你不知道 SSH 是什么?
00:15:14那这咖啡可能不适合你。
00:15:18♪ 手握终端咖啡 ♪ ♪ 活在梦中 ♪