痕跡は消せない。Shimcacheが暴く「侵入者の足跡」と、その防御戦略
インシデントレスポンスの現場で、攻撃者が最も嫌うものの一つが「Shimcache(AppCompatCache)」だ。
侵入に成功した攻撃者は、痕跡を消すためにログを削除し、タイムスタンプを改ざん(Timestomp)し、さらにはイベントログをクリアする。だが、WindowsのOS内部には、そんな小賢しい工作をあざ笑うかのように、実行ファイルの実行履歴をメモリ上にキャッシュし続ける仕組みがある。それがShimcacheだ。
今日は、フォレンジックの観点からShimcacheの重要性を説きつつ、攻撃者がここをどう悪用しようとするのか、そして開発・運用サイドとしてどう立ち回るべきかを、現場の視点で語ろう。
—
Shimcacheとは何か:Windowsが仕掛けた「記憶の貯蔵庫」
Shimcacheは、Windowsがアプリケーションの互換性を維持するために管理しているデータベースだ。ユーザーが実行ファイルを実行するたびに、OSは「このアプリはどの互換モードが必要か?」を判定するため、そのフルパスと最終更新日時(Last Modified Time)をキャッシュする。
重要なのは、これが「実行した」という事実を、ディスク上のログとは別の場所(レジストリ)に刻み込むという点だ。
なぜこれが攻撃者の悪夢なのか
攻撃者が malware.exe を実行し、その後すぐに削除したとしても、Shimcacheのメモリ上にはその実行パスが残る。マシンを再起動しても、レジストリに永続化されるため、調査員は数週間前の不審なバイナリの起動時刻を即座に特定できる。攻撃者がどれだけ隠蔽工作をしても、Shimcacheだけは「実行された時刻」という動かぬ証拠を突きつけるのだ。
—
攻撃者の盲点:Shimcacheを回避しようとする試み
最近の高度な攻撃者は、Shimcacheの性質を理解し、以下のような「PoC的な回避」を試みることがある。
1. ファイルレス実行: PowerShellやWMIを利用し、ディスクにバイナリを落とさずに実行する(Shimcacheにパスが記録されない)。
2. 合法的なプロセスへのインジェクション: notepad.exe などの正規プロセスに悪意あるコードを注入することで、Shimcacheには「notepad.exeを実行した」という正規の記録だけを残す。
これらに対抗するには、Shimcacheだけに依存せず、メモリフォレンジック全般の知見が必要だが、まずは「Shimcacheに記録されないようなコードの実行」を未然に防ぐ防御策を講じるのが先決だ。
—
実務で使える防御策:攻撃の入り口を塞ぐ
Shimcacheに残るようなバイナリ実行を許さないためには、アプリケーションやサーバ側で「実行権限の制御」を徹底することが最も泥臭く、かつ最も強力な防御だ。
1. PHP/Webアプリでの防御(exec関数の禁止)
WebアプリケーションからOSコマンドを叩くのは、マルウェアを落とす最大の入り口だ。php.ini での制御は必須である。
; php.iniで危険な関数を無効化する
; これにより、Webシェル経由でバイナリを実行する攻撃を防ぐ
disable_functions = exec, passthru, shell_exec, system, proc_open, popen
2. Nginx/WAFでのインジェクション対策
不正なバイナリを外部からダウンロードさせないために、特定のディレクトリ以外への書き込みを許さない設計が必要だ。
# Nginx設定例:アップロードディレクトリでの実行権限を剥奪
location /uploads/ {
# .exe, .php, .sh などの実行をブロック
location ~* \.(exe|php|sh|bat|cmd)$ {
deny all;
}
}
3. Pythonによる監視スクリプト(簡易版)
システム上で「未知のプロセス」が立ち上がったことを検知するスクリプトの一部だ。Shimcacheを調査する前の「一次検知」として活用してほしい。
import psutil
import datetime
def monitor_processes():
"""
実行中のプロセスを監視し、不審なパスがあれば警告する
"""
# 監視対象のディレクトリ(本来はここにバイナリがあるはずがない場所)
suspicious_dirs = ['/tmp/', '/var/tmp/', '/dev/shm/']
for proc in psutil.process_iter(['pid', 'name', 'exe']):
try:
exe_path = proc.info['exe']
if exe_path and any(d in exe_path for d in suspicious_dirs):
print(f"[!] 警告: 不審なパスからプロセス起動: {exe_path} (PID: {proc.info['pid']})")
# ここでログ出力やSlack通知などのインシデントハンドリングへ連携
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
if __name__ == "__main__":
monitor_processes()
—
最後に:フォレンジックは「日常の延長」にある
エンジニア諸君、Shimcacheのようなアーティファクトを「調査員が使う特殊なツール」だと考えていないだろうか?
それは間違いだ。フォレンジックとは、インシデントが起きてから慌てて調べるものではなく、日常のシステム運用の中で「何が起きているか」を可視化し続ける習慣のことだ。
- どのプロセスが、どこから起動したのか?
- 不要な実行権限は付与されていないか?
- ログは改ざん不可能な場所に送られているか?
これらの問いを設計段階から持っているチームは、万が一侵入されても、Shimcacheを読み解くことで即座に「攻撃の全貌」を把握できる。技術は、それを正しく理解し、設計に組み込んだ者だけを守ってくれる。
今日から、自社のシステムのプロセス監視をもう一度見直してみてほしい。それが、最強の防御への第一歩だ。
コメント