pengantar
Pada artikel ini, kita akan melihat konsep DLL hijacking dan bagaimana hal itu dapat digunakan untuk mencapai persistensi userland pada sistem Windows. Metode ini dijelaskan dalam MITRE ATT & CK di bawah: "Intercepting DLL Search Order (T1038) ".
Spoofing DLL dapat digunakan oleh penyerang untuk berbagai tujuan, tetapi artikel ini akan berfokus pada pencapaian ketahanan dengan aplikasi mulai otomatis. Misalnya, karena Slack dan Microsoft Teams diluncurkan saat boot (secara default), DLL spoofing di salah satu aplikasi ini akan memungkinkan penyerang mendapatkan akses terus-menerus ke target mereka - setiap kali pengguna masuk.
Setelah memperkenalkan konsep DLL, urutan pencarian DLL, dan spoofing DLL, saya akan memandu Anda melalui proses mengotomatiskan deteksi intersepsi DLL . Artikel ini akan membahas tentang mendeteksi jalur intersepsi DLL di Slack, Microsoft Teams, dan Visual Studio Code.
Akhirnya, saya menemukan beberapa jalur intersepsi DLL yang digunakan oleh aplikasi yang berbeda, menyelidiki akar penyebabnya, dan menemukan bahwa aplikasi yang menggunakan panggilan Windows API tertentu rentan terhadap intersepsi DLL saat tidak dijalankan
C:\Windows\System32\.
Saya ingin berterima kasih kepada kolega saya Josiah Massari (
@Airzero24) karena menjadi orang pertama yang menemukan beberapa pengait DLL ini, menjelaskan metodologi mereka, dan menginspirasi saya untuk mengotomatiskan pendeteksian.
Apa itu DLL?
DLL adalah pustaka yang berisi kode dan data yang dapat digunakan secara bersamaan oleh lebih dari satu program. ( Sumber )
Fungsionalitas DLL dapat digunakan oleh aplikasi Windows menggunakan salah satu fungsi
LoadLibrary*. Aplikasi dapat mereferensikan DLL yang dirancang khusus untuk aplikasi tersebut, atau DLL Windows yang sudah ada di disk di System32. Pengembang dapat memuat DLL dari System32 untuk menggunakan fungsionalitas yang telah diterapkan di Windows dalam aplikasi mereka tanpa harus menulis fungsionalitas ini dari awal.
Misalnya, pengembang yang perlu membuat permintaan HTTP dapat menggunakan pustaka WinHTTP (
winhttp.dll) daripada mengimplementasikan permintaan HTTP menggunakan soket mentah.
Perintah pencarian dan intersepsi DLL
Karena DLL ada sebagai file di disk, Anda mungkin bertanya-tanya bagaimana aplikasi mengetahui dari mana harus memuat DLL? Microsoft telah mendokumentasikan urutan pencarian DLL secara rinci di sini .
Dimulai dengan Windows XP SP2, Mode Pencarian Aman DLL diaktifkan secara default (
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode). Ketika mode aman diaktifkan, urutan pencarian DLL adalah sebagai berikut:
- Direktori tempat aplikasi dimuat.
- Direktori sistem. Gunakan fungsi GetSystemDirectory untuk mendapatkan jalur ke direktori ini.
- Direktori sistem 16-bit. Tidak ada fungsi yang menyediakan jalur ke direktori ini, tetapi akan dicari.
- Direktori Windows. Gunakan fungsi GetWindowsDirectory untuk mendapatkan jalur ke direktori ini.
- Direktori saat ini.
- , PATH. , , App Paths. App Paths DLL.
Suatu sistem dapat berisi beberapa versi DLL yang sama. Aplikasi dapat mengontrol pilihan lokasi tempat DLL harus dimuat dengan menentukan jalur lengkap atau menggunakan mekanisme lain seperti manifes. ( Sumber )
Jika aplikasi tidak menentukan dari mana memuat DLL, Windows menggunakan urutan pencarian DLL default yang ditunjukkan di atas. Posisi pertama dalam urutan pencarian DLL (direktori tempat aplikasi dimuat) menarik bagi penyerang.
Jika pengembang aplikasi bermaksud memuat DLL dari
C:\Windows\System32, tetapi tidak secara eksplisit menuliskannya dalam aplikasi, DLL berbahaya yang ditempatkan di direktori aplikasi akan dimuat sebelum DLL yang sah dari System32. Memuat DLL berbahaya disebut spoofing DLL (atau intersepsi) dan digunakan oleh penyerang untuk memuat kode berbahaya ke dalam aplikasi tepercaya / bertanda tangan.
Menggunakan DLL Spoofing untuk Mencapai Ketahanan
Spoofing DLL dapat digunakan untuk mencapai ketahanan saat aplikasi / layanan yang rentan dimulai dan DLL berbahaya ditempatkan di lokasi yang rentan. Kolega saya
@Airzero24menemukan spoofing DLL di Microsoft OneDrive, Microsoft Teams, dan Slack sebagai userenv.dll.
Program-program inilah yang menjadi sasaran intersepsi, karena secara default mereka dikonfigurasi untuk memulai saat startup Windows. Ini dapat dilihat di bawah di Task Manager:
Aplikasi Windows Dikonfigurasi ke Autostart
Untuk menguji spoofing DLL, saya membuat pemuat kode shell DLL yang memulai Cobalt Strike Beacon. Saya mengganti nama DLL berbahaya menjadi
userenv.dlldan menyalinnya ke direktori aplikasi yang terpengaruh. Saya meluncurkan aplikasi dan melihat panggilan balik Beacon baru saya.
Cobalt Strike Beacon Melalui
Penggunaan Interupsi DLLProcess Explorer , saya dapat memeriksa apakah DLL jahat saya benar-benar dimuat oleh aplikasi yang rentan.
Process Explorer menampilkan DLL berbahaya yang dimuat
Deteksi otomatis potensi intersepsi DLL
Setelah mengonfirmasi pembajakan DLL yang sebelumnya diketahui, saya ingin melihat apakah saya dapat menemukan kemampuan spoofing DLL lain yang dapat dieksploitasi.
Kode yang digunakan saat checkout dapat ditemukan di sini .
Menggunakan Slack sebagai contoh
Untuk memulai proses ini, saya menjalankan Process Monitor (ProcMon) dengan filter berikut:
- Nama proses -
slack.exe - Hasil mengandung
NOT FOUND - Jalan itu berakhir dengan
.dll.
Temukan DLL yang hilang di ProcMon.
Kemudian saya memulai Slack dan memeriksa ProcMon untuk menemukan DLL yang dicari Slack tetapi tidak dapat ditemukan.
Kemungkinan Jalur Interception DLL Ditemukan oleh ProcMon
Saya mengekspor data ini dari ProcMon sebagai file CSV untuk memudahkan parsing di PowerShell.
Dengan DLL shellcode loader saya saat ini, saya tidak dapat dengan mudah mengetahui nama DLL yang berhasil dimuat oleh Slack. Saya membuat DLL baru, yang digunakan
GetModuleHandleEx, dan GetModuleFileNameuntuk menentukan nama DLL yang dimuat dan menuliskannya ke file teks .
Tujuan saya berikutnya adalah untuk mengurai file CSV untuk jalur DLL dalam daftar, melihat daftar itu, menyalin DLL pengujian saya ke jalur yang ditentukan, memulai proses target, menghentikan proses target, dan menghapus DLL pengujian. Jika tes DLL berhasil dimuat, itu akan menulis namanya ke file yang dihasilkan.
Ketika proses ini selesai, saya akan memiliki daftar kemungkinan pembajakan DLL (saya harap) yang ditulis ke file teks.
Semua keajaiban dalam proyek DLLHijackTest saya dilakukan dengan skrip PowerShell . Ini menerima jalur ke file CSV yang dihasilkan oleh ProcMon, jalur ke DLL berbahaya Anda, jalur ke proses yang ingin Anda jalankan, dan setiap argumen yang ingin Anda sampaikan ke proses tersebut.
Get-PotentialDLLHijack Parameters
Get-PotentialDLLHijack.ps1
Setelah beberapa menit, saya memeriksa file teks yang terdaftar di DLL "jahat" saya untuk kemungkinan pembajakan DLL. Saya menemukan kemungkinan jalur intersepsi berikut untuk Slack:
PS C:Users\John\Desktop> Get-PotentialDLLHijack -CSVPath .\Logfile.CSV -MaliciousDLLPath .\DLLHijackTest.dll -ProcessPath "C:\Users\John\AppData\Local\slack\slack.exe"
C:\Users\John\AppData\Local\slack\app-4.6.0\WINSTA.dll
C:\Users\John\AppData\Local\slack\app-4.6.0\LINKINFO.dll
C:\Users\John\AppData\Local\slack\app-4.6.0\ntshrui.dll
C:\Users\John\AppData\Local\slack\app-4.6.0\srvcli.dll
C:\Users\John\AppData\Local\slack\app-4.6.0\cscapi.dll
C:\Users\John\AppData\Local\slack\app-4.6.0\KBDUS.DLL
Menggunakan Microsoft Teams sebagai contoh
Kami melakukan proses yang dijelaskan di atas lagi:
- Gunakan ProcMon untuk mengidentifikasi jalur intersepsi DLL potensial, ekspor data ini sebagai file CSV.
- Tentukan jalur untuk memulai proses.
- Tentukan argumen yang ingin Anda sampaikan ke proses.
- Jalankan
Get-PotentialDLLHijack.ps1dengan argumen yang sesuai.
Saya menemukan kemungkinan jalur intersepsi berikut untuk Microsoft Teams:
PS C:Users\John\Desktop> Get-PotentialDLLHijack -CSVPath .\Logfile.CSV -MaliciousDLLPath .\DLLHijackTest.dll -ProcessPath "C:\Users\John\AppData\Local\Microsoft\Teams\Update.exe" -ProcessArguments '--processStart "Teams.exe"'
C:\Users\John\AppData\Local\Microsoft\Teams\current\WINSTA.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\LINKINFO.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\ntshrui.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\srvcli.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\cscapi.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\WindowsCodecs.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\TextInputFramework.dll
Catatan : Saya harus membuat perubahan kecil pada skrip PowerShell untuk diselesaikanTeams.exe, karena skrip saya mencoba menghentikan proses yang coba dimulainya, dalam hal ini adalahUpdate.exe.
Menggunakan Visual Studio Code sebagai contoh
Dengan mengulangi proses di atas, saya menemukan jalur intersepsi potensial berikut untuk Kode Visual Studio:
PS C:Users\John\Desktop> Get-PotentialDLLHijack -CSVPath .\Logfile.CSV -MaliciousDLLPath .\DLLHijackTest.dll -ProcessPath "C:\Users\John\AppData\Local\Programs\Microsoft VS Code\Code.exe"
C:\Users\John\AppData\Local\Programs\Microsoft VS Code\WINSTA.dll
C:\Users\John\AppData\Local\Programs\Microsoft VS Code\LINKINFO.dll
C:\Users\John\AppData\Local\Programs\Microsoft VS Code\ntshrui.dll
C:\Users\John\AppData\Local\Programs\Microsoft VS Code\srvcli.dll
C:\Users\John\AppData\Local\Programs\Microsoft VS Code\cscapi.dll
Berbagi DLL
Saya melihat bahwa Slack, Microsoft Teams dan Visual Studio Code berbagi DLL berikut ini:
WINSTA.dllLINKINFO.dllntshrui.dllsrvcli.dllcscapi.dll
Saya menemukan ini menarik dan ingin memahami apa yang menyebabkan perilaku ini.
Metodologi: Memahami Cara Interception DLL Bersama
Aku melihat Tracy tumpukan ketika kendur mencoba untuk beban
WINSTA.dll, LINKINFO.dll, ntshrui.dll, srvcli.dlldan cscapi.dll.
DLL dengan lazy loading
saya melihat kesamaan dalam Tracy tumpukan saat pemuatan
WINSTA.dll, LINKINFO.dll, ntshrui.dlldan srvcli.dll.
Pelacakan tumpukan saat Code.exe mencoba memuat
WINSTA.dll
pelacakan tumpukan saat
Teams.exemencoba memuat LINKINFO.dll,
pelacakan tumpukan saat Slack mencoba memuat
ntshrui.dll
pelacakan tumpukan terus-menerus berisi panggilan
_tailMerge_<dllname>_dll, delayLoadHelper2diikuti LdrResolveDelayLoadedAPI. Perilaku ini sama untuk ketiga aplikasi tersebut.
Saya telah menentukan bahwa perilaku ini terkait dengan DLL pemuatan lambat . Dari tumpukan jejak saat boot
WINSTA.dllSaya dapat melihat bahwa modul yang bertanggung jawab atas pemuatan lambat ini adalah wtsapi32.dll.
Saya membuka
wtsapi32.dlldi Ghidra dan menggunakan Search -> For Strings -> Filter: WINSTA.dll. Klik dua kali pada baris yang ditemukan akan membawa Anda ke lokasinya di memori.
Baris "
WINSTA.dll" diwtsapi32.dll
Dengan mengklik kanan pada lokasi di memori, kita dapat menemukan referensi ke alamat ini.
Tautan ke
WINSTA.dll
Mengikuti tautan, kita dapat melihat bahwa string
WINSTA.dllditeruskan ke struktur bernama ImgDelayDescr. Dengan melihat dokumentasi untuk struktur ini, kami dapat mengonfirmasi bahwa ini terkait dengan DLL pemuatan lambat.
typedef struct ImgDelayDescr {
DWORD grAttrs; //
RVA rvaDLLName; // RVA dll
RVA rvaHmod; // RVA
RVA rvaIAT; // RVA IAT
RVA rvaINT; // RVA INT
RVA rvaBoundIAT; // RVA IAT
RVA rvaUnloadIAT; // RVA IAT
DWORD dwTimeStamp; // 0, ,
// O.W. / DLL, (Old BIND)
} ImgDelayDescr, * PImgDelayDescr;
Struktur ini dapat diteruskan ke
__delayLoadHelper2, yang akan menggunakan LoadLibrary/ GetProcAddressuntuk memuat DLL yang ditentukan dan memperbaiki alamat fungsi yang diimpor di tabel alamat impor (IAT) lazy load load.
FARPROC WINAPI __delayLoadHelper2(
PCImgDelayDescr pidd, // ImgDelayDescr
FARPROC * ppfnIATEntry // IAT
);
Dengan menemukan referensi lain ke struktur
ImgDelayDescrkita, kita dapat menemukan panggilan __delayLoadHelper2yang kemudian memanggil ResolveDelayLoadedAPI. Saya telah mengganti nama fungsi, tipe, dan variabel agar lebih mudah dipahami.
__delayLoadHelper2dan ResolveDelayLoadedAPIdi Ghidra
Luar Biasa ! Ini konsisten dengan apa yang kami lihat di pelacakan tumpukan ProcMon kami saat Slack mencoba memuat
WINSTA.dll.
__delayLoadHelper2 dan ResolveDelayLoadedAPIdi ProcMon.
Perilaku ini adalah seragam untuk
WINSTA.dll, LINKINFO.dll, ntshrui.dlldan srvcli.dll. Perbedaan utama antara setiap DLL lazy-load adalah DLL "induk". Di ketiga aplikasi:
wtsapi32.dlltangguhan dimuatWINSTA.dllshell32.dllmalas dimuatLINKINFO.dllLINKINFO.dlltangguhan dimuatntshrui.dllntshrui.dlltangguhan dimuatsrvcli.dll
Apakah Anda memperhatikan sesuatu yang menarik? Sepertinya itu
shell32.dllmengunduh LINKINFO.dll, yang mengunduh ntshrui.dll, yang akhirnya mengunduh srvcli.dll. Ini membawa kita ke opsi spoofing DLL potensial umum terakhir kita - cscapi.dll.
Substitusi DLL di NetShareGetInfo dan NetShareEnum
Saya mengikuti jejak tumpukan saat Slack mencoba memuat
cscapi.dlldan melihat panggilan LoadLibraryExWyang tampaknya berasal srvcli.dll.
Saya membuka
jejak tumpukan saat boot
cscapi.dll di Ghidra dan digunakan . Mengklik dua kali pada baris yang ditemukan dan mengikuti tautan mengarah ke panggilan yang diharapkan . memanggil LoadLibrary untuk
Mengganti nama fungsi yang berisi panggilan dan mengikuti tautan, saya mendapat dua tempat di mana fungsi tersebut digunakan:
srvcli.dllSearch -> For Strings -> Filter: cscapi.dllLoadLibrary
srvcli.dllcscapi.dll
LoadLibrary
NetShareEnum mengunduh cscapi.dll Unduhan
NetShareGetInfo
cscapi.dll
Saya memeriksa ini dengan program PoC yang memanggil
NetShareEnumdan NetShareGetInfo:
NetShareEnum.exemengunduh cscapi.dll
NetShareGetInfo.exeunduhancscapi.dll
hasil
Jalur spoofing DLL berikut tersedia di Slack:
C:\Users\John\AppData\Local\slack\app-4.6.0\WINSTA.dll
C:\Users\John\AppData\Local\slack\app-4.6.0\LINKINFO.dll
C:\Users\John\AppData\Local\slack\app-4.6.0\ntshrui.dll
C:\Users\John\AppData\Local\slack\app-4.6.0\srvcli.dll
C:\Users\John\AppData\Local\slack\app-4.6.0\cscapi.dll
C:\Users\John\AppData\Local\slack\app-4.6.0\KBDUS.DLL
Lintasan spoofing DLL berikut ini tersedia di Microsoft Teams:
C:\Users\John\AppData\Local\Microsoft\Teams\current\WINSTA.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\LINKINFO.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\ntshrui.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\srvcli.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\cscapi.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\WindowsCodecs.dll
C:\Users\John\AppData\Local\Microsoft\Teams\current\TextInputFramework.dll
Lintasan spoofing DLL berikut ini tersedia dalam kode Visual Studio:
C:\Users\John\AppData\Local\Programs\Microsoft VS Code\WINSTA.dll
C:\Users\John\AppData\Local\Programs\Microsoft VS Code\LINKINFO.dll
C:\Users\John\AppData\Local\Programs\Microsoft VS Code\ntshrui.dll
C:\Users\John\AppData\Local\Programs\Microsoft VS Code\srvcli.dll
C:\Users\John\AppData\Local\Programs\Microsoft VS Code\cscapi.dll
Selain itu, saya menemukan bahwa program menggunakan
NetShareEnumdan NetShareGetInfomenyediakan kemampuan untuk menggantikan DLL dalam bentuk cscapi.dllkarena panggilan hard-code LoadLibrary. Saya telah memverifikasi perilaku ini dengan Ghidra dan PoC.
Kesimpulan
Sebagai pengingat, intersepsi DLL adalah metode di mana penyerang dapat mengganggu eksekusi kode dalam aplikasi yang ditandatangani / dipercaya. Saya telah membuat alat untuk membantu mengotomatiskan deteksi jalur intersepsi DLL. Menggunakan alat ini, saya menemukan jalur intersepsi DLL di Slack, Microsoft Teams dan Visual Studio Code.
Saya melihat bahwa jalur intersepsi DLL dari ketiga aplikasi ini tumpang tindih, dan menyelidiki penyebabnya. Saya menyoroti metode saya untuk memahami kebetulan ini. Saya belajar tentang pemuatan lambat DLL dan menemukan dua panggilan API yang memungkinkan untuk mencegat DLL dalam program apa pun yang memanggilnya:
NetShareEnumbebancscapi.dllNetShareGetInfobebancscapi.dll
Terima kasih telah meluangkan waktu untuk membaca artikel ini, saya harap Anda telah mempelajari satu atau dua hal tentang Windows API, Ghidra, ProcMon, DLL dan intersepsi DLL!
Tautan
Halo kolega saya Daniel Heinsen (
@hotnops), Lee Christensen ( @tifkin_) dan Matt Hand ( @matterpreter) karena telah membantu dengan Ghidra / ProcMon!
Memeriksa PoC publik untuk digunakan dalam pentesting