Automatizar la detecci贸n de posibles rutas de interceptaci贸n de DLL (DLL Hijacks)

Hola, Khabrovites. Contrataci贸n para la nueva corriente del curso 鈥淧entest. Pr谩ctica de prueba de penetraci贸n " . Anticip谩ndonos al inicio del curso, compartimos con ustedes la traducci贸n de material interesante.







Introducci贸n



En este art铆culo, veremos el concepto de secuestro de DLL y c贸mo se puede usar para lograr la persistencia del 谩rea de usuario en los sistemas Windows. Este m茅todo se describe en MITRE ATT & CK en: "Interceptaci贸n del orden de b煤squeda de DLL (T1038) ".



Los atacantes pueden utilizar la suplantaci贸n de DLL para muchos prop贸sitos diferentes, pero este art铆culo se centrar谩 en lograr la resistencia con aplicaciones de inicio autom谩tico. Por ejemplo, dado que Slack y Microsoft Teams se inician en el arranque (de forma predeterminada), la suplantaci贸n de DLL en una de estas aplicaciones permitir铆a al atacante obtener un acceso s贸lido a su objetivo, siempre que un usuario inicie sesi贸n.



Despu茅s de presentar el concepto de DLL, orden de b煤squeda de DLL y suplantaci贸n de DLL, lo guiar茅 a trav茅s del proceso de automatizaci贸n de la detecci贸n de interceptaci贸n de DLL . Este art铆culo hablar谩 sobre la detecci贸n de rutas de interceptaci贸n de DLL en Slack, Microsoft Teams y Visual Studio Code.



Finalmente, descubr铆 m煤ltiples rutas de interceptaci贸n de DLL utilizadas por diferentes aplicaciones, investigu茅 la causa ra铆z y descubr铆 que las aplicaciones que usan ciertas llamadas a la API de Windows son propensas a la interceptaci贸n de DLL cuando no se ejecutan desde C:\Windows\System32\.



Quiero agradecer a mi colega Josiah Massari ( @Airzero24) por ser el primero en descubrir algunas de estas intercepciones de DLL, explicar su metodolog铆a e inspirarme a automatizar la detecci贸n.



驴Qu茅 es una DLL?



Una DLL es una biblioteca que contiene c贸digo y datos que pueden ser utilizados simult谩neamente por m谩s de un programa. ( Fuente ) La



funcionalidad de una DLL puede ser utilizada por una aplicaci贸n de Windows usando una de las funciones LoadLibrary*. Las aplicaciones pueden hacer referencia a archivos DLL dise帽ados espec铆ficamente para esas aplicaciones, o archivos DLL de Windows que ya est谩n en el disco en System32. Los desarrolladores pueden cargar archivos DLL desde System32 para usar la funcionalidad ya implementada en Windows en sus aplicaciones sin tener que escribir esta funcionalidad desde cero.



Por ejemplo, un desarrollador que necesita realizar solicitudes HTTP puede usar la biblioteca WinHTTP ( winhttp.dll) en lugar de implementar solicitudes HTTP usando sockets sin formato.



Orden de b煤squeda e interceptaci贸n de DLL



Dado que las DLL existen como archivos en el disco, es posible que se pregunte c贸mo una aplicaci贸n sabe desde d贸nde cargar la DLL. Microsoft ha documentado el orden de b煤squeda de DLL en detalle aqu铆 .



A partir de Windows XP SP2, el modo de b煤squeda segura de DLL est谩 habilitado de forma predeterminada ( HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode). Cuando el modo seguro est谩 habilitado, el orden de b煤squeda de DLL es el siguiente:



  1. El directorio desde el que se carg贸 la aplicaci贸n.
  2. Directorio del sistema. Utilice la funci贸n GetSystemDirectory para obtener la ruta a este directorio.
  3. Directorio del sistema de 16 bits. No hay ninguna funci贸n que proporcione una ruta a este directorio, pero se busca.
  4. Directorio de Windows. Utilice la funci贸n GetWindowsDirectory para obtener la ruta a este directorio.
  5. Directorio actual.
  6. , PATH. , , App Paths. App Paths DLL.


Un sistema puede contener varias versiones de la misma DLL. Las aplicaciones pueden controlar la elecci贸n de la ubicaci贸n desde la que se debe cargar la DLL especificando la ruta completa o utilizando otro mecanismo como un manifiesto. ( Fuente )



Si la aplicaci贸n no especifica desde d贸nde cargar la DLL, Windows usa el orden de b煤squeda de DLL predeterminado que se muestra arriba. La primera posici贸n en el orden de b煤squeda de DLL (el directorio desde el que se carga la aplicaci贸n) es de inter茅s para los atacantes.



Si el desarrollador de la aplicaci贸n tiene la intenci贸n de cargar la DLL desdeC:\Windows\System32, pero no lo escribi贸 expl铆citamente en la aplicaci贸n, la DLL maliciosa ubicada en el directorio de la aplicaci贸n se cargar谩 antes que la DLL leg铆tima de System32. La carga de una DLL maliciosa se denomina suplantaci贸n de DLL (o interceptaci贸n) y los atacantes la utilizan para cargar c贸digo malicioso en aplicaciones confiables / firmadas.



Uso de la suplantaci贸n de identidad de DLL para lograr resiliencia



La suplantaci贸n de DLL se puede utilizar para lograr resistencia cuando se inicia una aplicaci贸n / servicio vulnerable y una DLL maliciosa se coloca en una ubicaci贸n vulnerable. Un colega m铆o @Airzero24descubri贸 la suplantaci贸n de DLL en Microsoft OneDrive, Microsoft Teams y Slack como userenv.dll.



Fueron estos programas los que se convirtieron en el objetivo de la interceptaci贸n, porque de forma predeterminada est谩n configurados para iniciarse al inicio de Windows. Esto se puede ver a continuaci贸n en el Administrador de tareas:





Aplicaciones de Windows configuradas para inicio autom谩tico



Para probar la suplantaci贸n de DLL, cre茅 un cargador de shellcode DLL que inici贸 Cobalt Strike Beacon. Cambi茅 el nombre de la DLL maliciosa userenv.dlly la copi茅 en el directorio de la aplicaci贸n afectada. Abr铆 la aplicaci贸n y vi mi nueva devoluci贸n de llamada de Beacon.





Baliza de impacto de cobalto a trav茅s de la intercepci贸n de DLL



usandoProcess Explorer , puedo verificar si mi DLL malicioso fue realmente cargado por una aplicaci贸n vulnerable.





Explorador de procesos que muestra la DLL maliciosa cargada



Detecci贸n autom谩tica del potencial de interceptaci贸n de DLL



Despu茅s de confirmar el secuestro de DLL previamente conocido, quer铆a ver si pod铆a encontrar otras capacidades de suplantaci贸n de DLL que pudieran explotarse.



El c贸digo utilizado en mi pago se puede encontrar aqu铆 .



Usando Slack como ejemplo



Para iniciar este proceso, ejecut茅 Process Monitor (ProcMon) con los siguientes filtros:



  • Nombre del proceso -slack.exe
  • El resultado contieneNOT FOUND
  • El camino termina con .dll.




Encuentre archivos DLL que faltan en ProcMon.



Luego, inici茅 Slack y examin茅 ProcMon en busca de cualquier DLL que Slack estuviera buscando pero no pudiera encontrar.





Posibles rutas de interceptaci贸n de DLL descubiertas por ProcMon Export茅



estos datos de ProcMon como un archivo CSV para facilitar el an谩lisis en PowerShell.



Con mi DLL de cargador de shellcode actual, no pude averiguar f谩cilmente los nombres de DLL que Slack carg贸 con 茅xito. Cre茅 una nueva DLL, que se usa GetModuleHandleEx, y GetModuleFileNamepara determinar el nombre de la DLL cargada y escribirla en un archivo de texto .



Mi siguiente objetivo era analizar el archivo CSV en busca de rutas DLL en la lista, ver esa lista, copiar mi DLL de prueba en la ruta especificada, iniciar el proceso de destino, detener el proceso de destino y eliminar la DLL de prueba. Si la DLL de prueba se carg贸 correctamente, escribir谩 su nombre en el archivo resultante.



Cuando finalice este proceso, tendr茅 una lista de posibles secuestros de DLL (espero) escrita en un archivo de texto.



Toda la magia en mi proyecto DLLHijackTest se realiza mediante un script de PowerShell . Acepta la ruta al archivo CSV generado por ProcMon, la ruta a su DLL malicioso, la ruta al proceso que desea ejecutar y cualquier argumento que desee pasar al proceso.





Par谩metros de





Get-PotentialDLLHijack Get-PotentialDLLHijack.ps1



Despu茅s de unos minutos, verifico el archivo de texto que aparece en mi DLL "malicioso" en busca de posibles secuestros de DLL. Encontr茅 las siguientes posibles rutas de interceptaci贸n para 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


Usando Microsoft Teams como ejemplo



Realizamos de nuevo el proceso descrito anteriormente:



  1. Utilice ProcMon para identificar posibles rutas de interceptaci贸n de DLL, exporte estos datos como un archivo CSV.
  2. Determine la ruta para iniciar el proceso.
  3. Defina los argumentos que desee pasar al proceso.
  4. Ejecutar Get-PotentialDLLHijack.ps1con argumentos apropiados.


Encontr茅 las siguientes posibles rutas de interceptaci贸n para 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


Nota : Tuve que hacer peque帽os cambios en el script de PowerShell para completar Teams.exe, ya que mi script est谩 intentando terminar el proceso que estaba intentando iniciar, en este caso es Update.exe.


Usando Visual Studio Code como ejemplo



Al repetir el proceso anterior, encontr茅 las siguientes posibles rutas de interceptaci贸n para Visual Studio Code:



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


Compartir archivos DLL



Not茅 que Slack, Microsoft Teams y Visual Studio Code comparten las siguientes DLL:



  • WINSTA.dll
  • LINKINFO.dll
  • ntshrui.dll
  • srvcli.dll
  • cscapi.dll


Encontr茅 esto interesante y quer铆a entender qu茅 causa este comportamiento.



Metodolog铆a: comprensi贸n de las formas de interceptar archivos DLL compartidos



Vi pila cuando Tracy Una mala tratado de carga WINSTA.dll, LINKINFO.dll, ntshrui.dll, srvcli.dlly cscapi.dll.



DLL con carga diferida



me di cuenta de las similitudes en la pila al cargar Tracy WINSTA.dll, LINKINFO.dll, ntshrui.dlly srvcli.dll.





Seguimiento de pila cuando Code.exe intenta cargar WINSTA.dll





un seguimiento de pila al Teams.exeintentar cargar LINKINFO.dll,





seguimiento de pila cuando Slack intenta cargarntshrui.dll



un seguimiento de pila contiene constantemente una llamada _tailMerge_<dllname>_dll, delayLoadHelper2seguido LdrResolveDelayLoadedAPI. Este comportamiento fue el mismo para las tres aplicaciones.



He determinado que este comportamiento est谩 relacionado con la carga lenta de DLL . Desde la pila de seguimiento en el arranqueWINSTA.dllPude ver que el m贸dulo responsable de esta carga diferida era wtsapi32.dll.



Abr铆 wtsapi32.dllen Ghidra y us茅 Search -> For Strings -> Filter: WINSTA.dll. Haga doble clic en la l铆nea encontrada y lo llevar谩 a su ubicaci贸n en la memoria.





La l铆nea " WINSTA.dll" enwtsapi32.dll



Haciendo clic derecho en una ubicaci贸n en la memoria, podemos encontrar cualquier referencia a esta direcci贸n.





Enlaces aWINSTA.dll



Siguiendo los enlaces, podemos ver que la cadena WINSTA.dllse pasa a una estructura llamada ImgDelayDescr. Al mirar la documentaci贸n de esta estructura, podemos confirmar que est谩 relacionada con DLL de carga diferida.



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;


Esta estructura se puede pasar a __delayLoadHelper2, que utilizar谩 LoadLibrary/ GetProcAddresspara cargar la DLL especificada y fijar la direcci贸n de la funci贸n importada en la tabla de direcciones de importaci贸n de carga diferida (IAT).



FARPROC WINAPI __delayLoadHelper2(
   PCImgDelayDescr pidd,  //     ImgDelayDescr
   FARPROC * ppfnIATEntry //     IAT  
);


Al encontrar otras referencias a nuestra estructura ImgDelayDescr, podemos encontrar una llamada __delayLoadHelper2que luego llama ResolveDelayLoadedAPI. He cambiado el nombre de la funci贸n, los tipos y las variables para que sea m谩s f谩cil de entender.





__delayLoadHelper2y ResolveDelayLoadedAPIen Ghidra



隆Excelente! Esto es consistente con lo que vimos en nuestro seguimiento de pila de ProcMon cuando Slack intent贸 cargar WINSTA.dll.





__delayLoadHelper2 y ResolveDelayLoadedAPIen ProcMon.



Este comportamiento fue uniforme para WINSTA.dll, LINKINFO.dll, ntshrui.dlly srvcli.dll. La principal diferencia entre cada DLL de carga diferida era la DLL "principal". En las tres aplicaciones:



  • wtsapi32.dll diferido cargado WINSTA.dll
  • shell32.dll vago cargado LINKINFO.dll
  • LINKINFO.dll diferido cargado ntshrui.dll
  • ntshrui.dll diferido cargado srvcli.dll


驴Notaste algo interesante? Parece que shell32.dlldescarga LINKINFO.dll, que descarga ntshrui.dll, que finalmente descarga srvcli.dll. Esto nos lleva a nuestra 煤ltima opci贸n potencial com煤n DLL spoofing - cscapi.dll.



Sustituci贸n de DLL en NetShareGetInfo y NetShareEnum



Segu铆 el seguimiento de la pila cuando Slack intent贸 cargar cscapi.dlly vi una llamada LoadLibraryExWque aparentemente proven铆a de srvcli.dll. Abr铆 el





seguimiento decscapi.dll



la pila al arrancarsrvcli.dll en Ghidra y us茅 Search -> For Strings -> Filter: cscapi.dll. Hacer doble clic en la l铆nea encontrada y seguir los enlaces conduce a la LoadLibraryllamada esperada .





srvcli.dllllama a LoadLibrary paracscapi.dll



cambiar el nombre de la funci贸n que contiene la llamada LoadLibraryy siguiendo los enlaces, obtuve dos lugares donde se usa la funci贸n:







Descargas de NetShareEnum





cscapi.dll Descargas de NetShareGetInfocscapi.dll



Verifiqu茅 esto con programas PoC que llamaron NetShareEnumy NetShareGetInfo:





NetShareEnum.exedescargas cscapi.dll





NetShareGetInfo.exedescargascscapi.dll



resultados



Las siguientes rutas de suplantaci贸n de DLL est谩n disponibles en 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


Las siguientes rutas de suplantaci贸n de DLL est谩n disponibles en 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


Las siguientes rutas de suplantaci贸n de DLL est谩n disponibles en Visual Studio Code:



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


Adem谩s, descubr铆 que los programas que usan NetShareEnumy NetShareGetInfobrindan la capacidad de reemplazar archivos DLL en el formulario cscapi.dlldebido a la llamada codificada LoadLibrary. He verificado este comportamiento con Ghidra y PoC.



Conclusi贸n



Como recordatorio, la interceptaci贸n de DLL es un m茅todo mediante el cual los atacantes pueden interferir con la ejecuci贸n del c贸digo en aplicaciones firmadas / confiables. He creado herramientas para ayudar a automatizar la detecci贸n de rutas de interceptaci贸n de DLL. Con esta herramienta descubr铆 las rutas de intercepci贸n de DLL en Slack, Microsoft Teams y Visual Studio Code.



Not茅 que las rutas de interceptaci贸n de DLL de estas tres aplicaciones se superponen e investigu茅 la causa. Destaqu茅 mi m茅todo para entender esta coincidencia. Aprend铆 acerca de las DLL de carga diferida y descubr铆 dos llamadas a la API que hacen posible interceptar las DLL en cualquier programa que las llame:



  • NetShareEnum cargas cscapi.dll
  • NetShareGetInfo cargas cscapi.dll


Gracias por tomarse el tiempo de leer este art铆culo, espero que haya aprendido un par de cosas sobre la API de Windows, Ghidra, ProcMon, DLL y la intercepci贸n de DLL.



Enlaces



隆Un gran saludo a mis colegas Daniel Heinsen ( @hotnops), Lee Christensen ( @tifkin_) y Matt Hand ( @matterpreter) por ayudar con Ghidra / ProcMon!






Comprobaci贸n de PoC p煤blicas para su uso en pentesting






Lee mas:






All Articles