AIの進化と普及は、優先順位の転換や新技術への適応と受け入れ、そしてそれらを効果的に活用する必要性など、多くの課題をもたらしています。また、こうした技術の導入や利用に伴い、さまざまな懸念も顕在化しています。その1つが、これらのモデルが稼働するクラウド上の処理基盤に機密情報が送信または開示されるリスクです。さらに、これらのモデルは利用されるだけで性能が向上するため、結果的にベンダーが独自のアプリケーションや競合製品を開発することにつながりかねません。
多くの企業は、生成AI、特に大規模言語モデル(LLM)を導入する際に、「ソブリンAI」という方向性に沿ったアプローチを採用しています。これは、モデルをローカル環境やプライベートクラウドにデプロイする手法です。データとモデルを分離し、自社固有のデータを用いて微調整やトレーニングを行うことで、パブリッククラウドやインターネットとのやり取りを避け、安全性を確保します。これは同時に、複数のクライアントとリソースを共有し、それに伴うさまざまな影響があるパブリックプロバイダーを利用する場合と比較して、コスト削減と高速なアクセスを実現できることも意味します。
デスクトップやノートPCに大規模モデルの軽量版をデプロイできる点も、現在のAI技術が持つ大きな利点であり特徴です。しかし、デスクトップやモバイルPCなどの環境において、新しい技術を早く習得したいという焦りから、ローカルでモデルを実行できるさまざまなフレームワークを急いでダウンロードし、導入してしまうユーザーも少なくありません。こうした行為は、これらのアプリケーションが実行される組織に対して、多くのリスクをもたらす可能性があります。

このブログでは、Splunkの脅威調査チーム(STRT)が、インターネットからダウンロード可能な複数の公開アプリケーションを取り上げます。これらはローカルのデスクトップやモバイルPCにインストールされ、ローカルLLMの実行やクラウドLLMへの接続を可能にする一方で、組織による認可、制御、可視化を回避する可能性があります。これは「シャドーAI」として知られる現象です。さらに、多くの攻撃キャンペーンや新たなペイロードがいかにこの状況を悪用しているかを解説し、この現象を検知して防御する方法についても詳しく説明します。
ローカルやクラウドベースのLLMを実行できるフレームワークの入手は、決して難しくありません。インターネットで検索するか、PerplexityやCopilotといったLLMベースの検索ツールを使用して、ダウンロードするだけで済みます。また、ローカルで実行する場合、GPUすら必要としない非常に小さなモデルもあるため、ハイスペックなハードウェアは必要ありません。16GB以上のRAM、現行のプロセッサ、十分なストレージ容量を持つSSDを搭載したノートパソコンがあれば、すぐに始めることができます。
モデルの精度や重みを削減する量子化というプロセスにより、モデルのサイズとVRAMの使用量を大幅に抑えることが可能になりました。これにより、モデルをコンシューマー向けの一般的なハードウェアで動作させることができます。LLMの量子化にはいくつかの手法がありますが、これらを知っておくことは重要です。なぜなら、ダウンロードしたモデルの拡張子にその手法が反映されるからです。以下にその例をご紹介します。
モデルフォーマットにおける「MP3」とも呼ばれており、互換性が高く柔軟に利用できます。CPUとGPUのいずれか、あるいはその両方で動作しますが、GPU専用のフォーマットに比べると低速になる傾向にあります。このフォーマットは、OllamaやLM Studioといったツールで採用されています。ローカルLLMを実行するフレームワークとして、これら2つが最も広く使われているのには、明確な理由があります。
これは、NVIDIA製GPUでの実行に最適化された、より高度な量子化手法です。実行速度、圧縮率、精度のすべてにおいて、優れたパフォーマンスを発揮する傾向にあります。ただし、GPU専用であることに加え、セットアップがやや難しいという側面もあります。
GPTQに匹敵する、より新しく高度な量子化フォーマットです。速度と精度の双方が向上しているのが特徴ですが、NVIDIA製GPU専用となります。
これらのモデル量子化フォーマットの一部は、GGUFという拡張子で識別できることがわかります。この拡張子は、以下のようなローカルLLMフレームワークの存在を検知する手がかりとしても利用できます。
このブログの執筆時点で、最も広く普及し、利用可能なフレームワークは以下のとおりです。
Ollamaは、Llama 3やMistralといった強力なオープンソースの大規模言語モデルをPCにダウンロードして実行できる、無料で使いやすいツールです。

Ollamaは、デスクトップ環境や企業のローカル環境での導入において、最も広く利用されているフレームワークです。STRTでは、これまでにもOllamaフレームワークについて詳しく取り上げてきました。
LM Studioは、ローカルLLMをPCにダウンロードして実行するための、洗練された使いやすいGUIを備えた無料のデスクトップアプリケーションです。モデルブラウザとチャットウィンドウが内蔵されているため、コマンドラインを介することなく、誰でも簡単にさまざまなモデルを試すことができます。

Ollamaと比較すると、LM Studioは一般ユーザーや初心者向けのツールと言えます。その洗練されたGUIにより、セットアップや操作がOllamaよりも容易で、より使いやすくなっています。また、Ollamaとは異なり、LM Studioはクローズドソースである点も特徴です。上の図のように、モデルを直接検索してダウンロードし、そのままインストールできます。さらに、OpenAIなどのクラウドプロバイダーに接続することもできます。
ローカルLLMを誰もが利用できるようにした、先駆的なプロジェクトの1つです。プライバシーに配慮し、信頼性の高いCPUパフォーマンスを備えたツールで、多くのユーザーに支持されています。初心者やプライバシーを重視するユーザーを主なターゲットとしており、強力なGPUを搭載していない古いハードウェアでも動作させることができます。

GPT4Allでは、モデルのダウンロードは可能ですが、ローカルファーストのプライバシー設計のため、外部モデルに接続することはできません。
Llama.cppは、大規模言語モデルを実行するために開発された高性能なC++ライブラリです。CPUやGPUを搭載した一般的なコンシューマー向けハードウェアでも非常に効率的に動作します。当初はMeta社のLLaMAモデルを実行するために開発されました。このエンジンはコマンドラインで操作する仕様で、GUIを備えておらず、主にパワーユーザーを対象としています。
このエンジンは量子化されたモデルファイル(GGUFフォーマット)を読み込み、可能な限り高速に実行します。Llama.cppは、LM Studioに組み込まれているほか、Ollamaのフレームワーク内でも利用されています。いわば、OllamaやLM Studioは、ローカルLLMを実行するメインエンジンであるLlama.cppのラッパーのような存在です。Llama.cppは単体で動作させることもできますが、双方のツールにとって基盤となるエンジンの役割を果たしています。どちらのツールでGGUFモデルを実行する場合も、技術的にはLlama.cppを使用していることになりますが、より使いやすい形で操作できるようになっています。
ローカルLLMツールの世界には、使いやすいアプリケーションから強力なバックエンドサービスまで、多様なニーズに応える選択肢があります。洗練されたオープンソースのデスクトップクライアントを求めるユーザーにとって、クリーンなGUIを備えたJan.aiは、LM Studioに代わる魅力的な選択肢となります。対照的に、開発者はLocalAIのようなソリューションを好む傾向があります。LocalAIは汎用性の高いセルフホスト型のAPIサーバーとして動作し、OpenAI APIをそのまま置き換えて利用できます。
また、クリエイティブな用途に特化したKoboldCppは、ロールプレイや共同執筆に最適化された高性能なWeb UIとして注目されており、物語の生成を細かく制御できる機能を備えています。さらに、こうした確立されたツールに並び、Nutstudioのようなニッチなプロジェクトや新興のプロジェクトも、ローカルLLMツールのエコシステムの幅を広げており、それぞれが特定のユーザーワークフローや実験的な機能の提供を目的としています。


ここまで、最も一般的で使いやすいローカルLLMフレームワークをいくつか紹介してきました。詳細は、こちらからご確認いただけます。
前述のとおり、IT部門やセキュリティ部門の許可なくAIツール、モデル、APIを利用することはシャドーAIと呼ばれます。ここまで各フレームワークについて解説してきたように、これらは個々のユーザーやチームによって容易にインストールされ、企業の監視や調達、ガバナンスのプロセスを回避する形で利用される可能性があります。従業員は生産性の向上や試験的な利用、業務の自動化のためにこれらのツールを導入することがありますが、多くの場合、そのリスクやコンプライアンス上の影響を十分に認識していません。
シャドーAIに伴うリスクには、以下のようなものがあります。
現在、多くの攻撃キャンペーンやマルウェアが、シャドーAIやローカルLLMの導入環境を標的にし、管理の行き届かない未承認のモデルを悪意ある目的のために利用しています。以下にその例をご紹介します。
分散処理によく用いられるオープンソースのAIフレームワーク「Ray」の脆弱性を悪用した、進行中のクリプトマイナー攻撃が確認されています。攻撃者はRay AIフレームワークの設定不備、特にインターネットに公開された環境を悪用していました。
この攻撃は、AIインフラそのものが標的となっている実態を浮き彫りにしています。AIモデルが企業のデータベースやその他の内部システムと連携しているケースでは、そのリスクを正しく理解しておくことが不可欠です。
PromptLockは概念実証のランサムウェアであり、Ollamaなどのフレームワーク経由でローカルLLMを連携させることで、オンデマンドでポリモーフィックなマルウェアコードを生成し、ペイロード生成を自動化できることを示しています。
PromptLockは、実行のたびに自然言語のプロンプトを使って、攻撃の計画やコード作成を組み込みのLLMモデルに委ねます。これにより、感染ごとに固有の亜種が生成され、検知や攻撃者の特定を困難にしています。
このペイロードはローカルのAPIエンドポイントを利用してオープンウェイトLLMを呼び出し、ステルス性と柔軟性を求める攻撃者にとって、シャドーAIインスタンスがいかに価値の高い資産となり得るかを実証しています。
有名企業の従業員が、ローカル環境でのAI画像生成を試そうと、ComfyUIのプラグインまたは拡張機能(ComfyUI_LLMVISION)とされる未検証のAIアート生成ツールをGitHubからダウンロードしました。
ダウンロードされたソフトウェアは一見正当なものに見えましたが、マルウェアと情報窃取型マルウェアが埋め込まれていました。このマルウェアは従業員のコンピューターを侵害し、認証情報を窃取することで、攻撃者が社内の通信やシステム、機密ファイルにアクセスできるようにしました。
大手企業2社において、独自のコードや機密性の高い内部情報がChatGPTに入力され、その結果、自社固有のデータがモデルの応答に表示される事案が発生しました。
複数の攻撃キャンペーンにおいて、DeepSeekのインストーラーを装い、開発ツールになりすます悪質なコードが確認されています。
DeepSeekは非常に人気のあるAIモデルであり、OpenRouterやAlibaba Cloudなど、米国以外のさまざまなモデルリポジトリで入手できます。ユーザーは通常、こうしたプラットフォームからモデルをダウンロードしており、米国国外のユーザーを対象としたローカルLLMフレームワークも同様の場所で提供されています。この傾向は、IoTデバイスやロボットなどのAIが組み込まれた機器においても同様です。DeepSeekにこれほど多くのバージョンが存在する理由は、このモデルが「蒸留(ディスティレーション)」によって開発されているためです。この手法は、大規模なモデルを使ってより小さなモデルにその振る舞いや推論を模倣させる技術です。そのため、モデルリポジトリでは、下の図のように名前に「DeepSeek」が付いたモデルが多数見られます。

ローカルLLMを実行するフレームワークの監視は、組織のセキュリティとコンプライアンスに重大なリスクをもたらすデータ漏えいを防ぐために不可欠です。監視の行き届かないLLMでは、プロンプト入力、ファインチューニングのプロセス、あるいは生成された出力などを通じて、機密情報や規制対象データが意図せず流出してしまう恐れがあります。こうした情報漏えいは、深刻なプライバシー侵害や、GDPR、HIPAA、PCI DSSといった重要なコンプライアンスフレームワークへの違反につながり、組織に重大な法的および財務的影響をもたらす可能性があります。
適切な監視が欠如していると、組織の意思決定や責任の所在において、危険な盲点が生じます。シャドーデプロイメント(未承認または未追跡のLLM実装)を通じたAI主導のビジネスの意思決定には、監査証跡が一切残らないため、その意思決定に伴うリスクを追跡、説明、管理することが不可能になります。さらに、監視なしで運用されるローカルフレームワークは、集中型のアクセス制御や包括的なログ記録システム、定期的な脆弱性のパッチ適用といった重要なセキュリティ対策が不十分な場合が多く、こうした弱点を悪用しようとする攻撃者にとって、格好の標的となります。
ローカルLLMフレームワークを介したシャドーAIの可能性を検知し、防御するために活用できる検出ルールをいくつか挙げます。
シャドーAIの発見、監視、防御に取り組むべき理由は数多くあります。具体的な取り組みとして、Sysmonポリシーセットに追加できるSysmonポリシーガイダンスファイルを利用できます。また、イベントID 4688の監査を有効にしている場合、これらのフレームワークの発見と検知を目的とした以下の検出ルールも導入できます。さらに、前述のローカルLLMフレームワークの包括的なリストも忘れずにご確認ください。これは、環境に応じてSysmonポリシーや提供された検出ルールを調整するのに役立ちます。
以下に、シャドーAIを対象とした、STRTによるローカルLLMフレームワーク検知のサンプルをいくつかご紹介します。
プロセス作成イベント(イベントID 4688)を監視し、WindowsエンドポイントにおけるローカルLLMフレームワークとAIツールの実行を検知します。また、普及しているオープンソースやローカルホスト型のAIプラットフォームを追跡し、企業環境におけるシャドーITの利用やデータ流出のリスク、あるいは未承認のAIツール導入を特定します。
index="llm4688" sourcetype=XmlWinEventLog EventID=4688
| spath
| rename "Event.System.Computer" as Computer, "Event.System.EventID" as EventID
| eval NewProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "NewProcessName"))
| eval ParentProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "ParentProcessName"))
| eval CommandLine=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "CommandLine"))
| eval SubjectUserName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectUserName"))
| search (
NewProcessName="*ollama*" OR
NewProcessName="*llama*" OR
NewProcessName="*llama-run*" OR
NewProcessName="*gpt4all*" OR
NewProcessName="*lmstudio*" OR
NewProcessName="*nutstudio*" OR
NewProcessName="*koboldcpp*" OR
NewProcessName="*jan*" OR
NewProcessName="*jan.exe*" OR
CommandLine="*transformers*" OR
CommandLine="*langchain*" OR
CommandLine="*huggingface*" OR
CommandLine="*llama-run*" OR
CommandLine="*nutstudio*" OR
ParentProcessName="*ollama*" OR
ParentProcessName="*lmstudio*" OR
ParentProcessName="*nutstudio*" OR
ParentProcessName="*gpt4all*" OR
ParentProcessName="*jan*" OR
ParentProcessName="*llama-run*"
)
| eval Framework=case(
like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama",
like(NewProcessName, "%lmstudio%") OR like(NewProcessName, "%LM Studio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio",
like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%") OR like(CommandLine, "%nutstudio%"), "NutStudio",
like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All",
like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%") OR like(NewProcessName, "%jan.exe%"), "Jan",
like(NewProcessName, "%koboldcpp%") OR like(CommandLine, "%koboldcpp%"), "KoboldCPP",
like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%") OR like(CommandLine, "%llama-run%"), "Llama-Run",
like(CommandLine, "%transformers%") OR like(CommandLine, "%huggingface%"), "HuggingFace/Transformers",
like(CommandLine, "%langchain%"), "LangChain",
like(NewProcessName, "%llama%") OR like(NewProcessName, "%llama.cpp%") OR like(ParentProcessName, "%llama%"), "Llama.cpp",
1=1, "Related Activity"
)
| stats count by Computer, Framework, EventID, ParentProcessName
| sort Computer, Framework, -count

このSplunkサーチでは、Windowsのプロセス作成イベント(イベントID 4688)を追跡し、ログオンIDを使って特定のユーザーセッションと紐付けることで、ローカルLLMフレームワーク(Ollama、LM Studio、GPT4All、Janなど)の利用を特定します。親プロセス名、ユーザーアカウント、コンピューター名などの主要なプロセス情報を抽出し、企業全体でどのユーザーがAIツールを実行しているかを可視化します。また、検索結果をユーザーセッションごとに集計してLLMフレームワークの実行頻度を示し、シャドーAIの導入状況の把握やAIツールの利用パターンの監視を支援します。
index="llm4688" sourcetype=XmlWinEventLog EventID=4688
| spath
| rename "Event.System.Computer" as Computer
| eval SubjectUserName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectUserName"))
| eval SubjectLogonId=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectLogonId"))
| eval NewProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "NewProcessName"))
| eval ParentProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "ParentProcessName"))
| eval TokenElevationType=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "TokenElevationType"))
| search (
ParentProcessName="*ollama*" OR ParentProcessName="*lmstudio*" OR
ParentProcessName="*nutstudio*" OR ParentProcessName="*gpt4all*" OR
ParentProcessName="*jan*" OR ParentProcessName="*llama-run*"
)
| stats count by SubjectUserName, ParentProcessName, SubjectLogonId, Computer
| sort -count

index="llsysmon" | spath
| eval EventID='Event.System.EventID'
| eval Image=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^Image$"))
| eval TargetFilename=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^TargetFilename$"))
| eval QueryName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^QueryName$"))
| search ( Image="*ollama*" OR Image="*gpt4all*" OR Image="*lmstudio*" OR Image="*kobold*" OR Image="*jan*" OR Image="*llama-run*" OR Image="*llama.cpp*" OR Image="*oobabooga*" OR Image="*text-generation-webui*" OR TargetFilename="*.gguf*" OR TargetFilename="*ollama*" OR TargetFilename="*jan*" OR QueryName="*huggingface.co*" OR QueryName="*ollama.com*" )
| eval Framework=case(
match(Image, "(?i)ollama") OR match(TargetFilename, "(?i)ollama") OR match(QueryName, "(?i)ollama"), "Ollama",
match(Image, "(?i)lmstudio") OR match(Image, "(?i)lm-studio") OR match(TargetFilename, "(?i)lmstudio"), "LMStudio",
match(Image, "(?i)gpt4all") OR match(TargetFilename, "(?i)gpt4all"), "GPT4All",
match(Image, "(?i)kobold"), "KoboldCPP",
match(Image, "(?i)jan") OR match(TargetFilename, "(?i)jan"), "Jan AI",
match(Image, "(?i)llama-run") OR match(Image, "(?i)llama-b") OR match(Image, "(?i)llama.cpp"), "llama.cpp",
match(Image, "(?i)oobabooga") OR match(Image, "(?i)text-generation-webui"), "Oobabooga",
1=1, "Other"
)
| search Framework!="Other"
| stats count by Framework, Event.System.Computer, host
| sort -count

シャドーAIは、企業にとって明確かつ差し迫った脅威となっています。これは、最新技術を学び活用しようとするユーザーの動きに加え、機密情報のパブリッククラウドへの流出を防ぎつつ、LLMフレームワークの運用コストを抑えようとする企業の取り組みが背景にあります。このブログで説明してきたように、これらの技術に伴うリスクを未然に防ぎ、対処するためには、企業内におけるこれらのフレームワークの利用を発見、監視、分析することが不可欠です。
STRTは、これらのアプリケーションや主要なフレームワークを検知するためのガイダンスとコンテンツを提供し、お客様がシャドーAIの脅威に対処できるよう支援します。