PyPI パッケージ keep に含まれるタイプミス:悪意の依存関係とパスワード窃取

PyPI package ‘keep’ mistakenly included a password stealer

2022/06/12 BleepingComputer — PyPI パッケージである keep/pyanxdns/api-res-py の一部のバージョンには、悪意の request との依存関係が存在するため、バックドアが含まれることが判明した。たとえば、keep プロジェクトの大半のバージョンでは、HTTP リクエストを行うために正規の Python モジュール requests を使用しているが、keep v.1.2 にはマルウェアである request (s なし) が含まれている。BleepingComputer は、これが単なる誤植なのか自作自演なのか、それとも、メンテナ・アカウントの乗っ取りによるものなのかを確認するため、それぞれのパッケージの作者に問い合わせた。

PyPI パッケージ ‘keep’ が悪意の ‘request’ を使う

この5月に、GitHub ユーザーである duxinglin1 が、脆弱なパッケージのバージョンに、正規の requests ライブラリではなく、スペルミスの request 依存が含まれていることに気づいた。そのため、今週、脆弱性のあるバージョンに関して、以下の CVE が割り当てられた。

  • CVE-2022-30877:keep Ver 1.2 にはバックドア request が含まれる。
  • CVE-2022-30882:pyanxdns Ver 0.2 は影響を受けている。
  • CVE-2022-31313:api-res-py Ver 0.1 は影響を受けている。

    パッケージ pyanxdns と api-res-py は小規模なプロジェクトだが、特にパッケージ keep Ver 1.2 では悪意の依存関係が使用され、1週間で平均 8,000 回以上もダウンロードされている。 また、PyPI パッケージ keep の Ver 1.2 には、悪意の request への参照が含まれているのだ。
Version 1.2 of PyPI package ‘keep’ contains a reference to malicious ‘request’ dependency
pypi package keep uses request as a dependency
Usage of malicious ‘request’ dependency in ‘keep’ version 1.2 (BleepingComputer)

2020年の時点で、Tencent Onion Anti-Intrusion System は、PyPI レジストリにアップロードされた、requests HTTP ライブラリを装いながら、悪意の情報スティーラーをドロップするタイポスクワッティング request を発見した。

GitHub ユーザーである duxinglin1 は、「このプロジェクトの Ver 1.2 に悪意のバックドアを発見し、その悪意のバックドアは request パッケージであることが分かった。リクエスト・パッケージが PyPI により削除されたとしても、多くのミラーサイトでは完全に削除されていないため、これからもインストールされる可能性がある」と述べている。

偽造された request 内の悪質なコードは、以下でハイライト表示されている。

Inside counterfeit PyPI package request
Inside counterfeit PyPI package ‘request’ (BleepingComputer)

57行目には、以下に示す check.so マルウェアへの、base64 エンコードされた URL が含まれている。さらに、脅威情報アナリストの blackorbird は、偽造された request に関連する、以下のURL (x.pyx) を特定した。

http://dexy%5B.%5Dtop/request/check.so
http://dexy%5B.%5Dtop/x.pyx。

その一方で、BleepingComputer が入手した x.pyx には、Chrome/Firefox/Yandex/Brave などのWebブラウザから、Cookie や個人情報を盗むための、情報窃取マルウェアが含まれていることが確認されている。

x.pyx file contents
x.pyx file contents decoded by BleepingComputer (BleepingComputer)

この情報窃盗型トロイの木馬は、Web ブラウザに保存されているログイン名とパスワードを盗み出そうとする。ユーザーの認証情報を入手した後に脅威アクターは、開発者が使用する他のアカウントを侵害しようとし、さらなるサプライチェーン攻撃につなげようとしている。

ハイジャックか? それとも本物のタイプミスか?

複数の PyPI パッケージに存在する悪意の依存関係だが、なぜこのようなことが起こったのか、という重要な問題を提起している。BleepingComputer は、これが単なる誤植なのか自作自演なのか、それとも、メンテナ・アカウントの乗っ取りによるものなのかを確認するため、それぞれのパッケージの作者に問い合わせた。

パッケージ pyanxdns の作者/メンテナである Marky Egebäck からは、アカウントの侵害ではなく、誤植によるものであることを確認したとの返答があった。また、他の2つのパッケージの作者も、うっかりして、正当な requests ではなく request と入力ミスしたようだ。

Egebäck は BleepingComputer に対して、「setup.py ファイル内の単純なタイプミスで申し訳ないが、git 履歴によると、私が install_requires が追加したときに間違えたようだ」と語っている。その後に、この開発者は、新しいバージョンを PyPI に再アップロードし、悪意の request 依存関係を参照するバージョンを削除している。

Egebäck は、「これは setup.py の typo に基づく単純なミスで。私は通常、PyPI でソフトウェアを公開しないが、友人と自分のために素早く開発した。彼が、これを宣伝したかどうかは不明だが、主な目的は、社内の Docker プロジェクトで個人的に使用することだった」と述べている。

Egebäck は、彼のプロジェクトに存在する、悪意の依存関係を指摘してくれた、GitHub ユーザーである duxinglin1 に感謝ししている。また、Python にコントリビュートしたプロジェクトのメンテナンスに、最近は多くの時間を費やせないことも説明していた。

Egebäck は、「もちろん、もっと早く修正すれば良かったのだが、この問題の深刻さを理解していなかった。また、最近は、コーディングにほとんど時間をかけていないため、長い時間が掛かってしまった」と述べている。

アプリケーションをコーディングする際の、開発者による無意識なタイプミスが、この問題の原因だったようだ。そのミスを悪用して、ソフトウェアのサプライチェーン全体を危険にさらす、タイポス・クワッティング攻撃を成功させてしまうことがあるのだ。このケースでは、悪意のある ‘request’ 依存関係は、とっくに PyPI レジストリから削除されているが、脆弱なバージョンの PyPI パッケージを使い続け、ミラー・サイトに依存している人は、悪意のある情報スティーラーを、自分のシステムに取り込んでしまうことになりかねないのだ。

この記事は、keep/pyanxdns/api-res-py における単なるタイプミスが、タイポス・クワッティング攻撃へと変容してしまうという、とても具体的な事例でもあります。このような OSS リポジトリの安全を確保するために、GitHub ではリポジトリ・プッシュ前のパッケージ自動判定や、そして、OpenSSF では OSS リポジトリから悪意のパッケージを探し出す試みなどが進められています。今回の PyPI パッケージでのインシデントをみると、とても大切なことだと実感できます。

%d bloggers like this: