DLL Search Order Hijacking vs DLL Side-Loading

DLL Search Order HijackingとDLL Side-Loadingの違いについてのメモ。

どちらも正規の実行ファイルに悪意のあるDLLを読み込ませるという点は共通しているが、そこに至るまでの原理は厳密には異なる。

両者の違いについて自分なりに調べてまとめてみた。

※ただし、近年では単純にEXEファイルが同一ディレクトリに存在する悪意のあるDLLをロードしていた場合、DLL Side-Loadingと呼称するケースが増えているようである。

DLL Search Order Hijackingとは

WindowsにはKnownDLLsというレジストリ・キーがある。実行ファイルがDLLを読み込む際、対象のDLL名がKnownDLLsキーに定義されていた場合、常に特定のフォルダ配下(system32syswow64)にあるDLLが読み込まれる。KnownDLLsキーは以下のレジストリ・パスに格納されている:

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

実行ファイルがKnownDLLsキーで定義されていないDLLを読み込む場合、WindowsはSafeDllSearchModeの検索順序に基づいて対象のDLL名を検索する。近年のWindowsではSafeDllSearchModeはデフォルトで有効になっている。無効にしたい場合は以下のレジストリ・キーを作成して、値を0に設定する:

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\SafeDllSearchMode

MicrosoftのドキュメントによるとSafeDllSearchModeが有効の場合と無効の場合のDLL名の検索順序はそれぞれ以下の通り:

SafeDllSearchModeが無効 (0)SafeDllSearchModeが有効 (1)
1. 実行ファイルと同じディレクトリ内にあるDLL名を検索する1. 実行ファイルと同じディレクトリ内にあるDLL名を検索する
2. カレント・ディレクトリ内にあるDLL名を検索する2. システム・ディレクトリ内にあるDLL名を検索する ( %systemroot%system32)
3. システム・ディレクトリ内にあるDLL名を検索する ( %systemroot%system32)3. 16ビット・システムのシステム・ディレクトリ内にあるDLL名を検索する
4. 16ビット・システムのシステム・ディレクトリ内にあるDLL名を検索する4. Windows ディレクトリ内にあるDLL名を検索する (%systemroot%)
5. Windows ディレクトリ内にあるDLL名を検索する (%systemroot%)5. カレント・ディレクトリ内にあるDLL名を検索する
6. %PATH%変数で定義されたディレクトリ内にあるDLL名を検索する6. %PATH%変数で定義されたディレクトリ内にあるDLL名を検索する

上の表から分かるようにSafeDllSearchModeが有効の場合も無効の場合も、Windowsはまず最初に実行ファイルと同じディレクトリ内にあるDLL名を検索する。

以下の条件を満たした場合、実行ファイルと同じディレクトリに正規のDLLと同じファイル名を持つ悪意のあるDLLを配置することで、実行ファイルに悪意のあるDLLを読み込ませることが出来る:

  1. 正規のDLLがKnownDLLsで定義されていない
  2. 正規のDLLが実行ファイルと同じディレクトリ内に配置されていない
  3. 実行ファイルがDLLを読み込む際に、絶対パスでDLLを参照していない

DLL Side-Loadingとは

WindowsにはWindows side-by-side (WinSxS) assembly と呼ばれる仕組みがある。
ざっくり説明すると、DLLの競合・欠落などの問題を解消するための仕組みのこと。詳しくはこちら

WinSxSディレクトリ (%systemroot%winsxs, C:\Windows\winsxs)には複数のバージョンのDLLが格納されており、Side-by-Sideを利用するアプリケーションはマニフェスト・ファイルに基づいて読み込むべきDLLのバージョンを判断する。
WinSxSのマニフェスト・ファイルはAssembly ManifestsとしてXML形式で実行ファイルに埋め込まれており、アプリケーションが利用するライブラリやDLLの情報が記載されている。
以下はマニフェスト・ファイルの例である (こちらの記事より引用)

<?xml version=”1.0” encoding=”UTF-8” standalone=”yes”?>
<assembly xmlns=”urn:schemas-microsoft-com:asm.v1” manifestVersion=”1.0”>
<assemblyIdentity publicKeyToken=”75e377300ab7b886” type=”win32”
name=”Test4Dir”
version=”1.0.0.0” processorArchitecture=”x86”/>
<file name=”DirComp.dll” hash=”35ca6f27b11ed948ac6e50b75566355f0991d5d9”
hashalg=”SHA1”>
<comClass clsid=”{6C6CC20E-0F85-49C0-A14D-D09102BD7CDC}” progid=”DirComp.
PathInfo”
threadingModel=”apartment”/>
<typelibtlbid=”{AA56D6B8-9ADB-415D-9E10-16DD68447319}” version=”1.0”
helpdir=””/>
</file>
</assembly>

上記の例ではアプリケーションが利用するDLL名と、そのハッシュ値を記載することで、読み込むDLLの真正性を確認している。
もし、マニフェスト・ファイルの記述が不十分だった場合 (DLL名しか記述していない、DLLのバージョンを明記していない、ハッシュ値の確認をしていない、など)、アプリケーションに対して正規のDLLと同じファイル名を持つ悪意のあるDLLを読み込ませることが出来る。

ちなみにAssembly ManifestsはCFF Explorerで確認できる。(Resource Editor -> Configuration Files)

以下はnotepad.exeのAssembly Manifestsである。

まとめ

DLL Search Order HijackingはKnownDLLsおよびSafeDllSearchModeの隙を突いて、実行ファイルに悪意のあるDLLを読み込ませる。
DLL Side-LoadingはWindows side-by-side (WinSxS) assemblyのマニフェスト・ファイルの隙を突いて、実行ファイルに悪意のあるDLLを読み込ませる。

参考
DLL Search Order Hijacking
McGraw-Hill Education発行 Incident Response & Computer Forensics Third Edition P.373 - 375
https://www.fireeye.com/blog/threat-research/2010/08/dll-search-order-hijacking-revisited.html
https://www.fireeye.com/blog/threat-research/2010/07/malware-persistence-windows-registry.html
https://attack.mitre.org/techniques/T1574/001/

DLL Side-Loading
https://www.fireeye.com/content/dam/fireeye-www/global/en/current-threats/pdfs/rpt-dll-sideloading.pdf
https://www.fireeye.com/blog/threat-research/2020/01/abusing-dll-misconfigurations.html
https://www.fireeye.com/blog/threat-research/2014/04/dll-side-loading-another-blind-spot-for-anti-virus.html
https://attack.mitre.org/techniques/T1574/002/

Leave a Reply

Your email address will not be published. Required fields are marked *