ローカルAIユーザーは絶対に要確認!「マルウェア『Glassworm』の確認方法」(2026/5/13最終更新)
X記事機能でも書きましたが、スクリーニングスクリプトを作ったので取り急ぎ。
レイアウトとか全く気にせずに書いてます。
🔵概要
ローカルでAIを動かしている人は、少なからずGithubなどリポジトリから導入している人がほとんどだと思います。
Glasswormマルウェアは、異体字セレクタを利用した不可視文字によって、正規のgitプロジェクトでも悪意のあるコードを紛れ込ませ、実行する手法が取られており、現在事案が多発しています。
VSCode拡張機能やあらゆるサードパーティ製のアプリケーションにおいて、ペイロード部分で実行するマルウェアで、かつアンチウイルスソフトにも検知されない可能性があります。
Glasswormに感染すると、キーログやスクリーンショットなどを奪取され、様々な情報漏洩に繋がる恐れがあります。
🔵スクリーニング概要
特定の異体字セレクタを含むスクリプトがあるかどうかを、いわゆるgrep(文字列検索)で検索する方法です。
検索文字列はマルウェアの既知情報から以下だと判明しています。
U+FE00~U+FE0F(異体字セレクタ)
U+E0100~U+E01EF(異体字セレクタ補助)
PowerShell(管理者権限)で以下コマンドを実行して、ファイルが該当するかどうかを調べます。
🔵コマンドでのスクリーニング方法
Get-ChildItem -Path "" -Recurse -Filter "" -ErrorAction SilentlyContinue | Select-String -Pattern "([\uFE00-\uFE0F]|\uDB40[\uDD00-\uDDEF]){3,}"-Path : スクリーニングしたいフォルダパスを指定してください
-Filter : 特定の拡張子やファイル名のみを検索に含むようにします。ワイルドカードを使って指定可能です。
-Pattern : 最後の「{3,}」部分は文字列連続件数で検出します。
数字を小さくすれば、厳密に検知します。逆に数字を大きくすれば、誤検知を防ぐことができます。
マルウェア特有の長いペイロードを検知するには、ある程度長くても問題ないかと思います。
🔵PSスクリプトを使用したスクリーニング方法
特定の異体字セレクタを検出するスクリーニングスクリプトを作りました。
<#
.SYNOPSIS
Glassworm簡易スクリーニングスクリプト
.EXAMPLE
.\Scan-Glassworm.ps1 -Path "C:¥Example" -Filter "*.py" -Threshold 3
.AUTHOR
@konapieces <https://x.com/konapieces>
#>
param(
[Parameter(Mandatory=$true)]
[string]$Path,
[Parameter(Mandatory=$false)]
[string]$Filter = "*.*",
[Parameter(Mandatory=$false)]
[int]$Threshold = 3
)
$ErrorActionPreference = "SilentlyContinue"
Write-Host "--- Glassworm 検索開始 ---" -ForegroundColor Cyan
Write-Host "スキャン対象: $Path"
Write-Host "フィルタ: $Filter"
Write-Host "検知しきい値: $Threshold 文字連続"
Write-Host "--------------------------"
$Pattern = "([\uFE00-\uFE0F]|\uDB40[\uDD00-\uDDEF]){$Threshold,}"
$Files = Get-ChildItem -Path $Path -Recurse -Filter $Filter
$TotalFiles = $Files.Count
$CurrentCount = 0
$FoundCount = 0
if ($TotalFiles -eq 0) {
Write-Host "指定された条件に一致するファイルが見つかりませんでした。" -ForegroundColor Yellow
return
}
foreach ($File in $Files) {
$CurrentCount++
$Percent = [Math]::Round(($CurrentCount / $TotalFiles) * 100)
Write-Progress -Activity "スキャン中..." `
-Status "ファイル: $($File.Name)" `
-PercentComplete $Percent `
-CurrentOperation "$CurrentCount / $TotalFiles"
try {
$Content = [System.IO.File]::ReadAllText($File.FullName)
if ($Content -match $Pattern) {
Write-Host "[!] 警告: 疑わしいコードを発見しました: $($File.FullName)" -ForegroundColor Red
$FoundCount++
$matches = [regex]::Matches($Content, $Pattern)
foreach ($m in $matches) {
Write-Host " -> 位置: $($m.Index) 文字目付近" -ForegroundColor Gray
}
}
} catch {
# 読み取りエラー時はスキップ
}
}
Write-Host "`n--------------------------" -ForegroundColor Cyan
Write-Host "スキャン完了。"
Write-Host "総ファイル数: $TotalFiles"
if ($FoundCount -gt 0) {
Write-Host "検知数: $FoundCount" -ForegroundColor Red
} else {
Write-Host "検知数: $FoundCount" -ForegroundColor Green
}スキャン中のプログレス(進捗状況)も視覚的に分かるようにしています。

コマンドプロンプトやPowershellターミナルからでも実行可能ですが、お勧めはPowershell ISEです。
右クリックから「編集」をクリックすれば、Powershell ISEが立ち上がると思います。
このページの最後にスクリプトを置いてますので、お使いください。
2026.5.11追記
Powershellの実行ポリシーや、その他要因でどうやら弾かれてる方が居るみたいです。
そこまで考慮が及んでおりませんでした。すいません。
うまく動作しない方は以下を確認の上、お試しください。
1.Powershellを「管理者権限」で実行しているか
Powershellを右クリックし「管理者として実行」をクリックし、管理者権限で実行してください。

2.Scan-glassworm.ps1のブロック解除がされているか
ダウンロードしたスクリプトを右クリックし、プロパティを開いてください。
「ブロックの解除」もしくは「許可する」と言う項目がプロパティ内にある場合は、ブロックを解除してください。

3.実行ポリシーの変更
以下コマンドで現在の実行ポリシーを確認してみてください。
Get-ExecutionPolicy実行結果が以下ならば、実行制限が掛かっています。
Restricted
その場合、以下のコマンドで実行ポリシー変更してください。
変更する際は必ず「管理者権限」でPowershellを実行してください。
Set-ExecutionPolicy RemoteSigned上記のコマンドで、永続的にローカルスクリプトや署名済みスクリプトは許可されます。
🔵スクリプトダウンロード(2026.05.13最終更新)
全てのスクリーニングスクリプトを同梱しました。
基本スクリプト(Scan-Glassworm.ps1)
対象範囲
U+FE00 ~ U+FE0F(異体字セレクタ)
U+E0100 ~ U+E01EF(異体字セレクタ補助)
拡張範囲検出版(Scan-Glassworm-Extended.ps1)
対象範囲
U+FE00 ~ U+FE0F(異体字セレクタ)
U+E0100 ~ U+E01EF(異体字セレクタ補助)
U+200B ~ U+200F(ゼロ幅スペース、方向制御)
U+202A ~ U+202E(双方向テキスト制御)
U+2060(Word Joiner)
U+FFF9 ~ U+FFFB(行間注釈文字)
U+E0000 ~ U+E007F(Tags)
基本+拡張範囲検出+バイナリファイル対応版(Scan-Glassworm-Universal.ps1)
対象範囲
U+FE00 ~ U+FE0F(異体字セレクタ)
U+E0100 ~ U+E01EF(異体字セレクタ補助)
U+200B ~ U+200F(ゼロ幅スペース、方向制御)
U+202A ~ U+202E(双方向テキスト制御)
U+2060(Word Joiner)
U+FFF9 ~ U+FFFB(行間注釈文字)
U+E0000 ~ U+E007F(Tags)
[ 異体字セレクタ バイナリ検出対象16進数]
0B20,0C20,0D20,0E20,0F202A20,2B20,2C20,2D20,2E20,6020,F9FF,FAFF,FBFF
[ 異体字セレクタ バイナリ検出対象16進数レンジ]
0[0-F]FE,40DB[0-7][0-9A-F]DD
⚠️免責事項
本スクリプトを利用して、生じたあらゆる問題に関して、当方は一切責任を負いません。
🔵使い方
基本的には以下のように使ってください。
Scan-Glassworm.ps1 -Path <検索したいフォルダパス> -Filter "*.*" -Threshold 3基本的に、-Filterは全選択でいいと思います。
特定の拡張子のみを検索したい場合は以下のようにしてください。
以下例では、「.py」拡張子のみを検索します。
Scan-Glassworm.ps1 -Path <検索したいフォルダパス> -Filter "*.py" -Threshold 3Thresholdは検索文字列の連続ヒット回数のしきい値です。
デフォルトは「3」ですが、8とか10でもいい気がします。
Glasswormの特性として、コードを隠匿するために異体字セレクタを数百~数万字使うので、しきい値が10くらいでも問題ないと思います。
ただ、心配な方はデフォルトのままで使ってください。
🔴Scan-Glassworm-Universal.ps1の使い方
基本は一緒ですが、一部引数を追加しています。
大容量ファイルの検索にはかなりの時間を要し、メモリ使用量が増大します。
その為、検索するファイル容量に制限を設けられるようにしています。
Scan-Glassworm-Universal.ps1 -Path <検索したいフォルダパス> -Filter "*.py" -Threshold 3 -MaxFileSizeM 50-MaxFileSizeMはMB(メガバイト形式)で指定してください。
上記の例では、50MBまでのファイルを対象とします。
⚠️注意
Scan-Glassworm.ps1及びScan-Glassworm-Extended.ps1は、主にテキストベースのファイル走査のみになります。
バイナリファイル(.exeや.dllなど)も走査しますが、含まれる文字列はコンパイル済みである為、ファイルに含まれる文字列は認識することが困難です。
その為、バイナリファイルも含む全ファイル検査する際は、Scan-Glassworm-Universal.ps1を使用してください。
検出された場合でも、テキストベース検索より陽性判断の精度が下がります。
以下サイトでハッシュ検索し、悪意のあるコードが含まれたものかどうか、適宜照合することをお勧めします。
🔵最後に
Githubでも、正規リポジトリでかなりの数が、悪意のあるコードを紛れ込まされていたようです。
ComfyUIやForgeなどを使っている人は、拡張機能を導入する際にGithubを利用していると思います。
ついこの間には、LiteLLMのPyPIパッケージにGlasswormと思われるサプライチェーン攻撃が発生しました。
全く他人事ではないので、ローカルAIユーザーは一度スクリーニングを実施することをお勧めします。
いいなと思ったら応援しよう!
よろしければサポートお願いします!✨
頂いたサポート費用は活動費(電気代や設備費用)に使わさせて頂きます!✨