オンプレミス版SharePoint Serverの脆弱性CVE-2026-65660が、2026年9月25日に米CISAの悪用済み脆弱性カタログ(KEV)へ載りました。修正は8月11日の月例更新で出ていましたが、公開時は「なりすまし」と書かれ、深刻度も中程度でした。後からリモートコード実行(RCE)へ改められたため、更新を後回しにした組織が残っています。この記事では、攻撃の仕組み、ビルドで対象かを判定するスクリプト、IISログの調べ方、侵害を疑うときの対処、8月で更新が止まった2016・2019の扱いを整理しました。内容は2026年11月4日時点の公開情報にもとづきます。
まとめ:8月の累積更新の適用をビルドで確かめ、2016・2019は移行の期限を決める
まず確かめるのは、ファームのビルドが8月の修正版以上かどうかです。Subscription Editionは16.0.19725.20522、2019は16.0.10417.20198、2016は16.0.5565.1001が境目です。ここに届いていなければ、すぐに更新します。
匿名アクセスを許可したサイトを公開しているなら、更新だけで終えないでください。9月24日には、認証なしでこの欠陥を突く要求が観測されています。IISログと_layouts配下のファイルを調べ、怪しければマシンキーを入れ替えます。
2016と2019は7月14日に延長サポートが終わり、11月4日時点の更新履歴では8月11日の更新が最後です。9月以降のSharePointの修正は、Subscription Editionにしか出ていません。移行先をSubscription Editionにするか、SharePoint Onlineにするかは今期のうちに決めます。オンプレからの移行を外部と進める場合は、Microsoft 365・Copilot導入支援で移行範囲を先に固めると、権限やワークフローの漏れが出にくくなります。
CVE-2026-65660の中身:なりすまし表記からRCEへ改められた経緯と悪用の時系列
発見者はViettel Cyber Securityの研究者で、2025年5月のPwn2Own BerlinでToolShellの連鎖を示した人物です。9月22日にViettelのブログで技術的な詳細を公開し、そこから2日で実際の攻撃が観測されました。
SafeControlsの型検査をRegisterディレクティブの引用符で抜ける仕組み
SharePointには、ページに読み込める.NETのコントロールを許可リストで絞るSafeControlsという仕組みがあります。Web パーツの編集画面を処理するToolPane.GetPartPreviewAndPropertiesFromMarkup()は、受け取ったマークアップをRegisterディレクティブとタグに分けて検査し、検査の後で両者をつなぎ直して解析します。
欠陥はつなぎ直す処理にありました。RegisterDirective.GetHtml()は属性値を二重引用符で囲んで書き出すだけで、値の中の引用符をエスケープしません。SQLインジェクションと同じ要領で値に引用符を混ぜると、検査を通った後に別のRegisterディレクティブを差し込めます。許可リストに無いクラスを読み込ませ、XamlServices.Parse()経由のデシリアライズでコードを動かす流れです。デシリアライズがRCEに至る理屈は安全でないデシリアライゼーションの仕組みと防御実装で解説しています。
弱点の分類はCWE-94(コードインジェクション)です。発見者によれば、8月の更新は問題の関数を既定で無効にしました。ただし同じ型の解析処理がほかにも残る可能性を指摘しており、9月以降の更新も続けて当てる前提で考えます。RCE全般の成立経路はRCEが成立する5経路と侵入後の検知手順にまとめています。
6.5のなりすましから8.8のRCEへ:MSRCの改訂3回と9月25日のKEV登録
MicrosoftのセキュリティアップデートガイドのCVE-2026-65660は、改訂の履歴を3回残しています。8月11日の初版は「なりすまし」でCVSSは6.5でした。8月27日に影響・題名・FAQを書き換えてRCEとし、スコアを8.8に上げましたが、Microsoftはこれを「情報の変更のみ」と扱っています。9月25日には、攻撃を観測した確かな証拠があると追記しました。
| 日付 | 出来事 | 出典 |
|---|---|---|
| 8月11日 | 修正公開(なりすまし・6.5) | MSRC |
| 8月27日 | RCE・CVSS 8.8へ改訂(情報の変更扱い) | MSRC |
| 9月22日 | 発見者が技術詳細と攻撃用マークアップを公開 | Viettel |
| 9月24日 | おとりサーバーで攻撃の要求12件を観測 | Previdian |
| 9月25日 | 攻撃の観測を追記・KEV追加 | MSRC・CISA |
| 9月28日 | KEVの対応期限 | CISA |
CISAのKEVは期限を追加から3日後に置き、調査の義務を示す「Forensics Triage」を付けています。期限の決まり方はBOD 26-04の是正期限の決まり方で解説しました。注意したいのは、MSRCのAPIが返すexploitedの値が11月4日時点でも「No」のままである点です。改訂の文面では攻撃を認めているため、自動の優先度付けがこの値だけを見ていると取りこぼします。NVDの登録もスコアは8.8に直っていますが、スペイン語の説明文は「なりすまし」のままです。スコアの各指標はCVSSv3の計算式とスコアの目安で読み方を確かめられます。
6月の匿名経路と組み合わせた認証前の攻撃とPrevidianの観測内容
CVE-2026-65660そのものは、低い権限でもログインしていることが条件です。発見者は、匿名での閲覧を許可したサイトでは、AddGallery.aspxのようにWeb パーツの領域を持つページが認証の確認をせずにToolPaneを作ってしまう別の欠陥を見つけました。この経路は6月9日の更新で直っており、CVE番号は示されていません。
Previdianの観測報告によれば、9月24日12時(UTC)ごろ、1つの送信元から12件のPOSTが届きました。要点は次のとおりです。
- 宛先は
/_layouts/15/AddGallery.aspxとdesigngallery.aspxで、/_layouts/を重ねた変形も送られた - クエリで編集モードを開き、フォームの項目は
MSOTlPn_UriとMSOTlPn_DWP - CookieもAuthorizationヘッダも無く、本文は7,834バイトと535,404バイトの2段
- 送信元は169.150.248[.]21(AS212238)、User-AgentはFirefox 120
1段目は.NETのデシリアライズの型検査を外し、2段目はAESで暗号化したアセンブリを読み込むSdLoaderを運びます。9月25日の追記では、/_layouts/15/sphealth.aspxというWebシェルが作られることが分かりました。ToolShellのときに見張られたToolPane.aspxとは宛先が違うため、当時の検知ルールのままでは見落とします。
SharePointの更新は累積型で、最新の1本を当てれば過去の修正もすべて入ります。判定はファームのビルド番号1つで足ります。
対象3製品の修正KBとビルド番号:8月の累積更新で塞がる範囲
MSRCが示す修正版は次のとおりです。2016と2019は本体の更新と言語パックの更新の2本があり、FAQは「示された更新はすべて入れる」よう求めています。
| 製品 | 8月の修正KB | 修正ビルド | 11月4日時点の最新 |
|---|---|---|---|
| Subscription Edition | KB5002893 | 16.0.19725.20522 | KB5002927(10月13日) |
| 2019 | KB5002894・KB5002896 | 16.0.10417.20198 | 8月の更新が最後 |
| 2016 | KB5002905・KB5002906 | 16.0.5565.1001 | 8月の更新が最後 |
表の最新版はMicrosoftのSharePoint更新履歴で確かめました。KB5002893の説明には、SharePoint Workflow Managerを使っている場合は先にKB5002799を入れるよう書かれています。2019のKB5002894と2016のKB5002905にも同じ注記があります。
ファームのビルドをPowerShellで読み、MSRCのAPIと照合するスクリプト
ファームのビルドは、SharePoint管理シェルでGet-SPFarmのBuildVersionを読めば分かります。サーバーごとに更新が済んでいるかはGet-SPProduct -Localで見ます。
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
(Get-SPFarm).BuildVersion.ToString()
Get-SPServer | Where-Object Role -ne "Invalid" | Select-Object Name, Role, Status
台数が多いときは、MSRCのAPIから修正ビルドを取り、資産台帳の値と突き合わせます。SharePointには接続しません。
import json
import sys
import time
import urllib.parse
import urllib.request
API = "https://api.msrc.microsoft.com/sug/v2.0/en-US/affectedProduct?$filter="
CVES = ["CVE-2026-55040", "CVE-2026-65660"]
def nums(v):
# "16.0.10417.20198" を数値の組にして比べる(文字列比較は桁で狂う)
return tuple(int(x) for x in v.split("."))
def fixed_builds(cve):
q = urllib.parse.quote(f"cveNumber eq '{cve}'")
req = urllib.request.Request(API + q, headers={"User-Agent": "Mozilla/5.0"})
data = json.load(urllib.request.urlopen(req, timeout=30))
out = {}
for row in data.get("value", []):
builds = [k["fixedBuildNumber"] for k in row.get("kbArticles", []) if k.get("fixedBuildNumber")]
kbs = sorted({k["articleName"] for k in row.get("kbArticles", [])})
if builds:
out[row["product"]] = (max(builds, key=nums), kbs)
return out
# 引数: 製品名の一部=ファームのビルド(例: "2019=16.0.10417.20175")
farms = dict(a.split("=", 1) for a in sys.argv[1:]) or {"2019": "16.0.10417.20175"}
for cve in CVES:
table = fixed_builds(cve)
print(cve)
for key, build in farms.items():
hit = [(p, b, k) for p, (b, k) in table.items() if key in p]
if not hit:
print(f" {key:<14} {build:<18} 対象製品に無い(判定外)")
continue
p, need, kbs = hit[0]
flag = "修正済み" if nums(build) >= nums(need) else "未修正"
print(f" {key:<14} {build:<18} 必要 {need:<18} {flag} KB{'/'.join(kbs)}")
time.sleep(1)
python sp_msrc_check.py "Subscription=16.0.19725.20434" "2019=16.0.10417.20198" "2016=16.0.5561.1001" のように渡します。11月4日に7月の版を入れて実行したところ、Subscription Editionと2016はCVE-2026-55040で「修正済み」、CVE-2026-65660で「未修正」と出ました。7月の更新だけでは足りないことが、この出力で確かめられます。CVE-2026-55040は7月14日に直った認証回避で、8月18日にKEVへ載っています。
侵害の有無を確かめる:IISログと_layoutsのファイルで見る痕跡
8月の更新を入れる前に影響版を外部へ公開していた期間がある場合、特に9月22日以降は、次の観点で調べます。
AddGallery.aspx等への未認証POSTをIISログから抜き出す手順
SharePointの各サーバーには、IISのW3C形式のログが残ります。次のPythonは、観測された宛先への未認証POSTと、Webシェルの名前への要求を拾います。
import collections
import glob
import sys
# 匿名経路で狙われたページと、ToolShell以来のToolPane、置かれたWebシェル名
TARGETS = ("/addgallery.aspx", "/designgallery.aspx", "/toolpane.aspx")
SHELLS = ("/sphealth.aspx", "/spinstall0.aspx")
hits = collections.Counter()
for path in glob.glob(sys.argv[1]):
fields = []
for line in open(path, encoding="utf-8", errors="ignore"):
if line.startswith("#Fields:"):
fields = line.split()[1:]
continue
if line.startswith("#") or not fields:
continue
rec = dict(zip(fields, line.split()))
stem = rec.get("cs-uri-stem", "").lower()
query = rec.get("cs-uri-query", "").lower()
method = rec.get("cs-method", "")
user = rec.get("cs-username", "-")
when = rec.get("date", "") + " " + rec.get("time", "")
ip = rec.get("c-ip", "-")
if stem.endswith(SHELLS):
print("至急", when, ip, method, stem, rec.get("sc-status"))
elif method == "POST" and stem.endswith(TARGETS):
# 未認証(cs-username が "-")で編集モードを開く POST を優先して見る
level = "要調査" if user == "-" and "displaymode=edit" in query else "参考"
print(level, when, ip, method, stem, query, rec.get("sc-status"))
hits[ip] += 1
if stem.count("/_layouts/") >= 2:
print("参考(重複パス)", when, ip, method, stem)
for ip, n in hits.most_common(5):
print("POST件数", ip, n)
python sp_iislog_hunt.py "D:\IISLogs\W3SVC*\u_ex2609*.log" のようにログの場所を渡します。11月4日に、攻撃を模した要求2件、ログイン済みの利用者の要求2件、Webシェルへの要求1件を入れたサンプルで実行し、攻撃の2件が「要調査」、Webシェルが「至急」と出ることを確かめました。IISの既定のログには要求の大きさが残らないため、本文の大きさは前段のWAFやリバースプロキシで確かめます。IISのログの場所と項目はIISの仕組みと設定で確認できます。
sphealth.aspxと埋め込みアセンブリを手がかりにしたファイルとメモリの確認
次は、Webシェルが置かれていないかをファイルで確かめます。LAYOUTSフォルダーに8月以降に書かれた.aspxがあれば、更新で入ったものかどうかを1つずつ見ます。
$layouts = "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\TEMPLATE\LAYOUTS"
Get-ChildItem $layouts -Filter *.aspx -Recurse |
Where-Object { $_.LastWriteTime -gt (Get-Date "2026-08-01") -or $_.Name -in "sphealth.aspx", "spinstall0.aspx" } |
Select-Object FullName, LastWriteTime, Length |
Sort-Object LastWriteTime -Descending
Previdianは、2段目に埋め込まれたアセンブリとしてwt3k3sij.dll(391,680バイト)と24e5mo4s.dll(4,096バイト)を挙げ、SHA-256も公開しています。ただしwt3k3sij.dllがディスクへ書かれた様子は確認されていません。メモリで読み込む手口のため、ファイルが無いことは安全の証明になりません。EDRのメモリ検索やプロセスの調査が手元に無ければ、外部の調査を検討します。Webシェルの見つけ方と消し方の一般論はWebシェルの検知・除去の手順にあります。
匿名アクセスを許可したWebアプリケーションとサイトの棚卸し
認証前の経路が成り立つのは、匿名での閲覧を許可した場所だけです。どこで許可しているかを、Webアプリケーションのゾーンとサイトの2段で洗い出します。
Get-SPWebApplication | ForEach-Object {
$wa = $_
foreach ($zone in $wa.IisSettings.Keys) {
[pscustomobject]@{ WebApp = $wa.Url; Zone = $zone; AllowAnonymous = $wa.IisSettings[$zone].AllowAnonymous }
}
}
Get-SPSite -Limit All | Get-SPWeb -Limit All |
Where-Object { $_.AnonymousState -ne "Disabled" } |
Select-Object Url, AnonymousState
ゾーンで匿名を許可していても、サイト側で無効なら閲覧はできません。両方が有効な組み合わせが、今回の調査とログ確認の優先対象です。社外向けの広報サイトを除けば、匿名アクセスを残す理由は少ないはずです。権限の継承や共有リンクの棚卸しはSharePointのアクセス権設定と棚卸しで手順を解説しています。
侵害を疑うときの事後対応:マシンキーの入れ替えとAMSIの有効化
ログやファイルに痕跡が出た場合、更新を当てても攻撃者が持ち出した鍵は使い続けられます。2025年のToolShellのときにMicrosoftが示した手順が、今回もそのまま土台になります。
ASP.NETマシンキーの入れ替えとIIS再起動を更新の後に行う理由
2025年のToolShellで置かれたspinstall0.aspxは、ASP.NETのマシンキーを読み出して攻撃者へ返すWebシェルでした。キーがあれば、署名付きのデータを偽造して、更新後のサーバーでもコードを動かせます。今回のsphealth.aspxの中身は公表されていませんが、同じ目的を疑って対処する方針です。Microsoftの2025年7月のブログは、更新を当てた後にマシンキーを入れ替え、すべてのSharePointサーバーでIISを再起動するよう求めています。
Set-SPMachineKey -WebApplication "https://portal.example.co.jp"
iisreset.exe
Webアプリケーションが複数あれば、それぞれに実行します。全体管理の「監視」から「ジョブ定義の確認」を開き、Machine Key Rotation Jobを「今すぐ実行」しても同じことができます。順番は必ず更新が先です。更新前に入れ替えると、塞がっていない穴から新しいキーをまた盗まれます。
AMSIのFull ModeとDefenderで未知のペイロードを止める設定
同じブログは、オンプレミスのSharePointでAMSI(マルウェア対策スキャンインターフェイス)を有効にし、Full Modeにすることも勧めています。AMSIは要求の本文をウイルス対策製品に渡して調べる仕組みで、今回のように攻撃のマークアップが公開された後の変形に効きます。Microsoft Defender ウイルス対策を使わない場合は、AMSIに対応した製品かを確かめてください。
侵害が濃い場合、マシンキーの入れ替えだけで終えるのは勧めません。2段目のアセンブリが何をしたかは、復号前の中身が見つかっておらず不明です。ファームのサービスアカウントの資格情報も入れ替えの候補に入れ、調査を外部へ頼むかどうかはフォレンジック調査の流れと調査会社の選び方を参考に決めます。
2016・2019を使い続けるか移るか:8月が最後の更新になった版の判断
今回の件で一番重い事実は、2016と2019にこの先の修正が来ないことです。8月の更新を当てても、それで終わりではありません。
9月と10月の修正はSubscription Edition限定という事実
2016のライフサイクルと2019のライフサイクルは、どちらも延長サポートの終了を2026年7月14日としています。8月11日の更新は終了後に出たものですが、9月8日と10月13日の更新はSubscription Editionにしかありません。
NVDには、9月8日公開のSharePointのCVEが16件、10月13日公開が35件あります。このうち私たちがMSRCで確かめたCVE-2026-69268・CVE-2026-85900・CVE-2026-102866の3件は、対象製品がSubscription Editionだけでした。2016と2019が対象に無いのは、影響しないと判定されたからではなく、評価の対象から外れたためと考えるのが自然です。2016と2019には、少なくとも10月分の修正が届いていない状態だと見てください。
私たちの判断はこうです。ファイル共有とお知らせ、簡単なリストが中心なら、SharePoint Onlineへ移ります。サーバーの更新作業そのものが無くなり、今回のような改訂の追跡も要りません。移行の手順と事前チェックはSharePoint Migration Tool(SPMT)の手順と事前チェック、移行後の外部共有の初期設定はSharePoint管理センターの初期設定で確認できます。
サーバー側のコードで作り込んだソリューション(ファームソリューション)、オンプレの業務システムと直結したワークフロー、データを国内の自社設備から出せない規程がある場合は、Subscription Editionへ上げます。2016や2019からは、コンテンツデータベースを移す方式で上げることが可能です。どちらが自社の使い方に合うかは、SharePointでできることと導入判断の基準で整理し直すと決めやすくなります。
移行を待たずに今週やること:インターネット公開の遮断と認証の前段配置
移行には数か月かかります。その間に2016や2019をインターネットへ直接公開し続けるのはやめてください。社内からしか使わないなら外部公開を止め、社外から使うならVPNか、認証を済ませた要求だけを通すリバースプロキシを前に置きます。匿名アクセスも、広報サイトのように本当に要る場所を除いて切ります。
ただし、外部公開を止めて移行を先送りにするのは勧めません。乗っ取られた社員のアカウントからは、CVE-2026-65660がそのまま突けます。公開範囲を絞るのは時間稼ぎです。社外に開いたサーバー全体の点検範囲を決めたいときは、脆弱性診断の種類と進め方・外注時の判断基準が参考になります。
更新と調査を進める中で出てきやすい疑問に、公開されている一次情報の範囲で答えます。
9月や10月の更新を入れていれば、8月の更新は入れなくてよいですか?
入れなくて構いません。SharePointの更新は累積型で、Microsoftの更新履歴も最新の更新だけを入れれば過去のセキュリティ修正がすべて入ると説明しています。Subscription Editionなら10月13日のKB5002927(16.0.20326.20190)を入れれば、8月の修正も含まれます。2016と2019は8月の更新が最新なので、本体と言語パックの2本を入れてください。
CVE-2026-65660について、利用者側の作業はありません。MSRCの対象製品はSharePoint Server 2016、2019、Subscription Editionの3つで、SharePoint Onlineは含まれていません。ハイブリッド構成でオンプレのサーバーを残している組織は、そのサーバーを確かめてください。なお2013は対象製品に無いだけで、発見者は影響すると書いています。2023年4月にサポートが終わっているため、公開の停止を先に決めます。
匿名アクセスを許可していなければ、攻撃されないと考えてよいですか?
考えられません。匿名アクセスが条件になるのは、認証前に突く経路だけです。CVE-2026-65660そのものは低い権限のログインで突けるため、社員のアカウントが1つ乗っ取られれば成り立ちます。7月に直った認証回避のCVE-2026-55040と組み合わせる経路も報道で指摘されています。更新が本筋で、匿名アクセスの停止は被害の入口を減らす補助です。
MSRCの「悪用される可能性は低い」という評価を見て後回しにしていました。問題ですか?
問題があります。その評価は11月4日時点でも残っていますが、MicrosoftはMSRCの改訂履歴で9月25日に攻撃を観測したと書き、CISAもKEVに登録しています。脆弱性管理の仕組みがMSRCのAPIの項目だけで優先度を付けているなら、KEVの登録有無を判定に加えてください。
JPCERT/CCやIPAの注意喚起が出ていなくても、急ぐ必要はありますか?
急ぐ必要があります。攻撃用のマークアップが公開され、実際の攻撃も観測されています。KEVの期限は追加から3日後でした。国内の発表を待つ理由にはなりません。
関連記事
- SharePointとは?できること・OneDriveやTeamsとの違いと導入判断の基準:移行先を決める前に、SharePointでできることを整理し直すときに読む記事です。
- CVE-2026-42897とは?Exchange OWAの悪用済みXSSと修正SU・緩和策の外し方【2026年10月】:同じくオンプレのMicrosoft製品で悪用が確認された脆弱性の対応手順です。
- VPN 脆弱性:機器の版確認コマンドとKEV照合スクリプト・パッチと移行の判断【2026年10月】:版をKEVと突き合わせる仕組みを、ほかの公開機器にも広げるときに使えます。
- SharePoint Migration Tool(SPMT)とは:ファイルサーバー移行の手順・事前チェックとPowerShell実行例:オンプレからSharePoint Onlineへ移すときの手順です。
- 安全でないデシリアライゼーションとは?RCEに至る仕組みと言語別の防御実装を解説:今回の攻撃の2段目で使われた仕組みの基礎です。