通信を巧妙に隠す手口が進化。Linuxを狙う高度なマルウェアの仕組み

文●フォーティネットジャパン 編集●ASCII

提供: フォーティネットジャパン

  • この記事をはてなブックマークに追加
  • 本文印刷

本記事はフォーティネットジャパンが提供する「FORTINETブログ」に掲載された「SymbioteおよびBPFdoorマルウェア向けの新たなeBPFフィルター」を再編集したものです。

影響を受けるプラットフォーム:Linux
影響を受けるユーザー:Linuxベースのネットワークアプリケーションまたはサーバー
影響:悪意のあるC2通信の隠蔽
深刻度:中

 eBPF(extended Berkeley Packet Filter)は非常に興味深いカーネルテクノロジーです。eBPFを使用することで、小さなサンドボックス化されたプログラムをLinuxカーネルに読み込んで、ネットワークパケット、システムコールなどの調査や変更を行うことができます。2015年に登場したこのテクノロジーは、当時の新しいコンピュータアーキテクチャ(64ビットなど)ではもはや使われなくなっていたレガシー(1992年誕生)BPFテクノロジーを刷新しました。

 いつものように、このテクノロジーはすぐにマルウェア作成者たちの目に留まり、2015年にBvp47マルウェアが登場し、EbpfkitやTripleCrossなどの一群のルートキットも生み出されました。しかし、eBPFの使用や悪用には高いスキルが必要であったため、このようなマルウェアは珍しい存在でした(数の面において)。現在、この種のマルウェアは主に2つのファミリー、SymbioteとBPFDoorで構成されています。どちらも2021年に発見されました。

2025年のeBPF

 2025年の今、BPFマルウェアはもう排除されたでしょうか。その答えはイエスでもありノーでもあります。

 「イエス」である理由は、このようなファミリーの新たな亜種がこれまではすべて検知されていて、フォーティネットのお客様の安全が保たれているからです。「ノー」である理由は、eBPFマルウェアがまだ過去のものにはなっていないからです。FortiGuard Labsは2025年に、BPFDoorの新たなサンプルを151件、Symbioteの新たなサンプルを3件検知しました。

 eBPFマルウェアの使用件数は多くありません。eBPFマルウェアの開発にはランダムな詐欺やランサムウェアの場合よりはるかに高いスキルが必要なためです。eBPFマルウェアは全く別種のマルウェアであり、検知が難しく、効率的かつ強力であるため、非常に危険です。したがって、eBPFマルウェアは国家の支援を受けて開発されるのが一般的です(BPFDoorもそのケースだとされています)。

BPFバイトコードのリバース

 BPFは独自の命令セットを使用します。これはよく知られたx86 / ARMとは全く異なります。eBPF ISAは、固定長の64ビット命令を使って意図的にサイズを最小限に抑えています(x86命令とARM命令はどちらも可変長命令を使用します)。

 BPFバイトコードを含むマルウェアをリバースする場合、eBPF ISAは「複雑」ではありませんが、リバースエンジニアリングが困難な別のレイヤーを付け加えます。リバースエンジニアリング用のツールはいくつか存在し、bpftoolIDA Pro向けeBPFプロセッサCapstoneエンジンなどが利用できます。

 Radare2ネイティブでBPFバイトコードをサポートしていることは、おそらくあまり知られていません。一例として、2025年7月30日に見つかったSymbioteの最近のサンプルを分析してみましょう。このサンプルは初期のバージョンによく似ていますが(詳細はこちら)、ある時点でBPFフィルターをソケットに接続します。この最近のバージョン以外では、BPFフィルターが変更されています。

 Radare2を使用すると、悪意のあるバイナリに含まれるeBPFバイトコードオブジェクトを見つけることができます。その長さは352バイトであることがわかっています(バイトコードを使用する関数をリバースすることで)。Radare2に対して、BPFアーキテクチャ(e asm.arch)に切り替えてバイトコードを逆アセンブルするように(pd)命じることができます。Radare2はサンプルを簡単に逆アセンブルします。ldh(半ワードを読み込む)とjeq(等しければジャンプ)は典型的なBPF命令です。

非標準ポートを介したC2通信

 BPF命令を見ると、この新しい亜種がポート54778、58870、59666、54879、57987、64322、45677、および63227で、TCP、UDP、およびSCTPプロトコルのIPv4またはIPv6パケットのみを受け入れることがわかります。

 これはボットネットにとっては一般的な、非標準ポートを介したC2通信です。一部のセキュリティツール(例:基本的なファイアウォール、IDSまたはIPS検知エンジン)は既知のポート(HTTPなど)の検査に重点を置いていることが多く、番号の大きい未知のポートは重視しません。Symbioteなどのトラフィックに関して、この種のツールはトラフィックをいっさい記録しない場合が多く、よくて「未知のポート」への少数のパケットにフラグを付ける程度です。それらは正規のトラフィックであることが多いため、気付かれない可能性があります。

 Symbioteのオリジナルバージョンは、TCPパケットとSCTPパケットのみを受け入れ、UDPは受け入れない、使用するポートのリストも短いものでした。ポートのリストが長い場合、そのマルウェアはポートホッピングを実行するものと考えられます。つまり、所定のポートがブロックされるかフラグ付けされた場合、マルウェアはリスト内の別のポートを使用します。リストが長くなればなるほど、誤検知を起こさずにポートをブロックできる効率的なルールをネットワーク管理者が作成することは難しくなります。

 UDPパケットの受け入れも、賢明な戦略であるように見えます。UDPはコネクションレス型であり、接続を確立したり閉じたりする必要がないため、マルウェアがUDPポート間で簡単にポートホッピングを行うことができます。さらに、従来のIDSはその性質上、UDPよりTCPに対して効率的に機能します。IDSのルールの多くがTCPハンドシェイクを対象にしている一方で、悪意のあるUDPセッションの特定はより困難であるためです。

BPFアセンブリを理解する:AIの活用

 Radare2は確かにBPFバイトコードを逆アセンブルできますが、そのBPF命令が何をするかについては理解が必要です。これまでは、その解決策として、マニュアルを読む必要がありました。今日では、私たちはAIの膨大な知識を活かしたサポートを利用することができます。

 私は、BPFバイトコードをClaude.AIに読み込ませました。その時点では「デコード」が間違っているのだろうと想定していましたが、それは誤りでした。実際は、私がRadare2でBPFアーキテクチャに切り替えていなかったのです。Claude Sonnet 4.5は、それぞれの命令について説明しました(IPv6パケットに関するジャンプ命令、SCTP、TCP、およびUDPプロトコルに関する分岐命令など)。

 結果として、AIはこのBPFバイトコードが何を行うのかを要約して説明しました。この要約が、マルウェアに関連しているという妥当な推測がなされている点にも注目してください。

 BPFバイトコードについてAIに質問する方が、eBPF ISAのマニュアルを読むよりもはるかに時短になります。とは言っても、AIが主張する内容については、常に懐疑的に見る必要があります。私も間違いをいくつか見つけたことがあります。

1.AIエラー#1:別のモデルは、このBPFバイトコードがパケットを受け入れずにドロップしていると主張しました。実際はその逆でした。

2.AIエラー#2:別の試行では、このBPFバイトコードがポート2048をフィルタリングしていると告げられました。バイトコードを理解していれば、これが間違いであることがわかります。16進数値0x0800(2048)は、実際はIPv4のEtherType識別子です(つまりIPv4パケットを受け入れます)。ポート2048に対するフィルタリングは存在しません。

BPFDoorの亜種の比較

 Symbioteのほかに、Linux/BPFDoorもBPFを悪用している重要なマルウェアファミリーです。BPFDoorが登場したのは2021年ですが、その新たな亜種が大量に見つかったのは2025年です(2021年以来のサンプル数が240件、2025年だけで150件)。亜種間にどのような違いがあるのでしょうか。些細な違いなのか、それとも新機能が追加されたのでしょうか。

 AIを使って調べてみましょう。私はRadare2向けMCPサーバーをセットアップしました。これにより、LLMでRadare2逆アセンブラを利用できるようになりました。その後、LLMに対して、2021年のBPFdoorに関する最初の分析を、2025年7月19日に見つかった最近のサンプルと比較するように命じました。

(82ed617816453eba2d755642e3efebfcbd19705ac626f6bc8ed238f4fc111bb0)

 以下のスクリーンショットでは、(1)一番上に私の最初のプロンプトが表示されており、(2) MCPサーバーが最近のサンプルをRadare2逆アセンブラで開く準備を進めています。

 LLMとMCPサーバーがBpfDoorのサンプル(特に、ソケット上のBPFフィルターを構成するapply_bpf_filterという名前の関数)をリバースします。その後、やや多めのマークダウン分析を生成します(以下のスクリーンキャプチャを参照)。この分析にかかった費用は0.5ドルでした。

 このレポートの最も重要な部分は以下の表にまとめられています。

 この表はAIが生成したものです。私が手動でチェックした結果、ポイント1(BPFフィルター)、ポイント2(マジック値)、ポイント5(リバースシェル)は真実であることが確認できました。ポイント4(RC4暗号化)は間違い / ハルシネーションです。サンプル内でRC4コードは見つかりませんでした。他のポイントについては、このブログにおける重要度が低いため、チェックしていません

BPFフィルターがIPv6サポートを付加

 このBPFDoorのサンプルでは、関数apply_bpf_filterの中で、rawソケット(タイプ3)に対してBPFフィルターが設定されています。

 apply_bpf_filter内には、Symbioteの場合のような直接的なBPFバイトコードはありませんが、ソケットオプションの構造体がBPFフィルターとして解釈されます。レベルがSOL_SOCKETでoptnameがSO_ATTACH_FILTERだからです。特に、これらは実際にはクラシックBPFバイトです。

 このBPFフィルターの構造体は、C言語で以下のように表現されます。

struct sock_filter bpf_filter[] = {

{ 0x28, 0, 0, 0x0000000c }, // Ethernetタイプフィールドを読み込む

{ 0x15, 0, 4, 0x000086dd }, // IPv6か? 違う場合は前方に4ジャンプ

{ 0x30, 0, 0, 0x00000014 },
{ 0x15, 0, 11, 0x00000011 }, // UDPか? 違う場合は前方に11ジャンプ

{ 0x28, 0, 0, 0x00000038 }, // UDP IPv6の宛先ポートを取得

{ 0x15, 8, 9, 0x00000035 }, // DNSポートを受け入れる

{ 0x15, 0, 8, 0x00000800 }, // IPv4か? 違う場合は8ジャンプ

{ 0x30, 0, 0, 0x00000017 }, // IPv4プロトコルを取得

{ 0x15, 0, 6, 0x00000011 }, // UDP(IPv4上の)か? 違う場合は6ジャンプ

{ 0x28, 0, 0, 0x00000014 }, // IPv4フラグメントオフセットおよびフラグを取得

{ 0x45, 4, 0, 0x00001fff }, // フラグメント化されている場合は4ジャンプ

{ 0xb1, 0, 0, 0x0000000e }, // IPv4ヘッダー長を算出

{ 0x48, 0, 0, 0x00000010 }, // 宛先ポートを取得

{ 0x15, 0, 1, 0x00000035 }, // DNSなら受け入れ、それ以外は拒否

{ 0x6, 0, 0, 0x00040000 }, // 受け入れる場合はここにジャンプ

{ 0x6, 0, 0, 0x00000000 } // 拒否する場合はここにジャンプ

};

 私はこのサンプルが今ではIPv6パケットをサポートしていることを確認しました。このサンプルは、IPv4またはIPv6でUDPポート53(DNS)のトラフィックのみを保持します。これは、マルウェアが自身の存在を隠蔽するための気付かれにくい方法です。DNSトラフィックは頻繁に送受信され、通常は疑われません。このようなDNSトラフィックを、マルウェアは自身の通信に使用しています。

結論

 2025年に、BPFを悪用するマルウェアファミリーであるSymbioteとBPFDoorの新たな亜種が発見されました。これらのサンプルをリバースエンジニアリングして古い亜種と比較した結果、マルウェアの作成者がBPFフィルターを改善して検知を回避する確率を上げていることが明らかになりました。Symbioteは番号の大きいUDPポートを対象にしたポートホッピングを使用しており、BPFDoorはIPv6のサポートを実装していました。

 eBPFマルウェアについて教えてくれた同僚のGeri Revayに感謝します。

フォーティネットのソリューション

 このレポートで解説したマルウェアは、FortiGuardアンチウイルスによって以下の名称で検知されブロックされます。

Linux/Symbiote.B!tr (SIGID: 171365647)

Linux/BpfDoor.F!tr (SIGID: 171124526)

 FortiGate、FortiMail、FortiClient、およびFortiEDRは、FortiGuardアンチウイルスサービスをサポートしています。FortiGuardアンチウイルスエンジンは、これらの各ソリューションに含まれています。したがって、これらの製品をご利用のお客様は最新の保護が備えられています。

 また、リバースシェル通信からお客様を守るために、フォーティネットは以下のIPSシグネチャもリリースしています。

Backdoor.BPFDoor.TCP

Backdoor.BPFDoor.TCP2,

Backdoor.BPFDoor.ICMP,

Backdoor.BPFDoor.UDP

 FortiGuard IPレピュテーションおよびアンチボットネットセキュリティサービスは、フォーティネット分散ネットワークからの不正送信元IPデータを集約することで、これらの攻撃をプロアクティブにブロックします。この分散ネットワークは、脅威センサー、CERT、MITRE、協力関係にある他社、その他のグローバルソースで構成され、悪意ある送信元に関する最新の脅威インテリジェンスを連携して提供しています。

 お客様の組織が本件の脅威、またはその他のサイバーセキュリティ攻撃の影響を受けていると思われる場合は、フォーティネットのグローバルFortiGuardインシデントレスポンスチームまでお問い合わせください。

IOC(Indicators of Compromise:侵害指標)

dcfbd5054bb6ea61b8f5a352a482e0cf7e8c5545bd88915d3e67f7ba01c2b3d4 Linux/Symbiote.B!tr
82ed617816453eba2d755642e3efebfcbd19705ac626f6bc8ed238f4fc111bb0 Linux/BpfDoor.F!tr

■関連サイト