Mengotomatiskan deteksi kemungkinan jalur intersepsi DLL (DLL Hijacks)

Halo, Khabrovites. Perekrutan untuk aliran baru kursus β€œPentest. Praktek Penetration Testing " . Untuk mengantisipasi dimulainya kursus, kami membagikan terjemahan materi yang menarik kepada Anda.







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:



  1. Direktori tempat aplikasi dimuat.
  2. Direktori sistem. Gunakan fungsi GetSystemDirectory untuk mendapatkan jalur ke direktori ini.
  3. Direktori sistem 16-bit. Tidak ada fungsi yang menyediakan jalur ke direktori ini, tetapi akan dicari.
  4. Direktori Windows. Gunakan fungsi GetWindowsDirectory untuk mendapatkan jalur ke direktori ini.
  5. Direktori saat ini.
  6. , 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 dariC:\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 mengandungNOT 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:



  1. Gunakan ProcMon untuk mengidentifikasi jalur intersepsi DLL potensial, ekspor data ini sebagai file CSV.
  2. Tentukan jalur untuk memulai proses.
  3. Tentukan argumen yang ingin Anda sampaikan ke proses.
  4. 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 diselesaikan Teams.exe, karena skrip saya mencoba menghentikan proses yang coba dimulainya, dalam hal ini adalah Update.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.dll
  • LINKINFO.dll
  • ntshrui.dll
  • srvcli.dll
  • cscapi.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 memuatntshrui.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 bootWINSTA.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 keWINSTA.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.dll tangguhan dimuat WINSTA.dll
  • shell32.dll malas dimuat LINKINFO.dll
  • LINKINFO.dll tangguhan dimuat ntshrui.dll
  • ntshrui.dll tangguhan dimuat srvcli.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 bootcscapi.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





NetShareGetInfocscapi.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:



  • NetShareEnum beban cscapi.dll
  • NetShareGetInfo beban cscapi.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






Baca lebih banyak:






All Articles