Scrambled
Windows · Medium
10.10.11.168
Reconnaissance:
┌──(kali💀kali)-[~]
└─$ sudo nmap -sC -sV -O 10.10.11.168
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: Scramble Corp Intranet
|_http-server-header: Microsoft-IIS/10.0
| http-methods:
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-01-31 02:15:05Z)
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: scrm.local0., Site: Default-First-Site-Name)
|_ssl-date: 2024-01-31T02:16:44+00:00; -1s from scanner time.
| ssl-cert: Subject: commonName=DC1.scrm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC1.scrm.local
| Not valid before: 2024-01-31T02:01:11
|_Not valid after: 2025-01-30T02:01:11
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: scrm.local0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC1.scrm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC1.scrm.local
| Not valid before: 2024-01-31T02:01:11
|_Not valid after: 2025-01-30T02:01:11
|_ssl-date: 2024-01-31T02:16:44+00:00; -1s from scanner time.
1433/tcp open ms-sql-s Microsoft SQL Server 2019 15.00.2000.00; RTM
|_ssl-date: 2024-01-31T02:16:44+00:00; -2s from scanner time.
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2024-01-31T02:11:07
|_Not valid after: 2054-01-31T02:11:07
| ms-sql-info:
| 10.10.11.168:1433:
| Version:
| name: Microsoft SQL Server 2019 RTM
| number: 15.00.2000.00
| Product: Microsoft SQL Server 2019
| Service pack level: RTM
| Post-SP patches applied: false
|_ TCP port: 1433
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: scrm.local0., Site: Default-First-Site-Name)
|_ssl-date: 2024-01-31T02:16:44+00:00; -1s from scanner time.
| ssl-cert: Subject: commonName=DC1.scrm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC1.scrm.local
| Not valid before: 2024-01-31T02:01:11
|_Not valid after: 2025-01-30T02:01:11
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: scrm.local0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC1.scrm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC1.scrm.local
| Not valid before: 2024-01-31T02:01:11
|_Not valid after: 2025-01-30T02:01:11
|_ssl-date: 2024-01-31T02:16:44+00:00; -1s from scanner time.
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: Host: DC1; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2024-01-31T02:16:06
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
|_clock-skew: mean: -1s, deviation: 0s, median: -1s
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 149.17 secondsThese look like the typical ports I would expect on a Windows DC, plus 80 (HTTP), 5985 (WinRM), 1433 (MSSQL), and something unknown on 4411. LDAP shows the full hostname as DC1.scrm.local. I’ll add both DC1.scrm.local and scrm.local to my /etc/hosts file.
EM: Website - TCP 80
NTLM authentication is disabled:
News And Alerts 04/09/2021: Due to the security breach last month we have now disabled all NTLM authentication on our network. This may cause problems for some of the programs you use so please be patient while we work to resolve any issues
403 - Forbidden: Access is denied. http://10.10.11.168/images/ http://10.10.11.168/assets/
http://10.10.11.168/supportrequest.html Send your email to support@scramblecorp.com and we will respond as soon as possible
A screenshot leaks a username, ksimpson:
When submitting a support request via email please include your network information. You can collect this by doing the following:
Type (cmd.exe) into the start menu
In the new window that appears type (ipconfig > %USERPROFILE%\Desktop\ip.txt) and press Enter
There will now be a file named ip on your deskop. Add this file as an attachment to the email
http://10.10.11.168/newuser.html http://10.10.11.168/newuser.html?demo-category=1#
/salesorders.html has details on the “Sales Orders App”, which confirms the hostname / domain name from nmap, and also gives an indication of what TCP 4411 is used for:
http://10.10.11.168/salesorders.html
/passwords.html says: Our self service password reset system will be up and running soon but in the meantime please call the IT support line and we will reset your password. If no one is available please leave a message stating your username and we will reset your password to be the same as the username.
http://10.10.11.168/passwords.html
EM: KERBEROS
User Enumeration via Kerberos: One way to enumerate users through Kerberos is by using Kerbrute, a tool that uses impacket’s modules to brute-force Kerberos users. Since Kerberos is an authentication protocol, it tells us if the credentials provided are valid, and if the username is correct but the password is incorrect by outputting the error message “KDC_ERR_PREAUTH_FAILED”. If the username and password are incorrect, then the error is “KDC_ERR_C_PRINCIPAL_UNKNOWN”. This makes the brute-force easier. The point is, we don’t need the passwords for finding valid users. Also, add “scrm.local” and “dc1.scrm.local” to the hosts file.
/kerberos_enum_userlists /A-ZSurnames.txt
Password Spraying: I tried to check if any other users have the same passwords as their usernames using the “–user-as-pass” flag in Kerbrute. Note that the tool copies the password without converting it into smaller case. Only “ksimpson” has the same username and password.
Obtaining TGT: Once the credentials were verified to be valid, I used them to request the TGT (Ticket Granting Ticket) using Impacket’s “getTGT” script that saves the TGT as ccache (credential cache). ksimpson@scrm.local:ksimpson
Now that we have the TGT, we can request the ST/TGS (Service Ticket/Ticket Granting Service) from the KDC (Key Distribution Centre), if we can find the user’s SPN (Service Principal Name). A valid TGT and an existing SPN are required to request a ST from KDC. If the SPN is registered for the domain user, the ST is encrypted with the NT hash (NTLM hash) of the user’s account. Therefore, once the ST is obtained, we can crack it on our machine. This attack (Kerberoasting) will work if the account is using a weak password.
Obtaining SPN and ST/TGS: Using Impacket’s “GetUserSPNs” script, I was able to request the ticket. Note: The GetUserSPNs has an unfixed issue when using Kerberos credentials from a ccache file. So, to fix this error you need to edit the file GetUserSPNs.py changing target = self.__kdcHost by target = self.getMachineName(). Moreover, you need to use the domain in the -dc-ip parameter to make it work.
The “KRB5CCNAME” environment variable must set as the ccache file name. The “-k” flag uses this file to pass the cache (kerberos ticket), and the “-no-pass” flag is set so that the program understands that we will pass the ticket instead of a password:
Using the ticket, we can obtain the Service Principal Name of the account, which is an MSSQL service.
Cracking TGS using HashCat: Then, using john, we can crack the password, which will get us handy in the future.
In less than a minute on my system it breaks to “Pegasus60”.
FOOTHOLD: Shell as MiscSvc
139/tcp open netbios-ssn Microsoft Windows netbios-ssn 445/tcp open microsoft-ds?
TOOLS: Because NTLM authentication is disabled, I won’t be able to use many of the standard tools here, and I won’t be able to access any service by IP address if it requires authentication.
smbclient won’t work, and I wasn’t able to get crackmapexec to work either.
Since a username was found and port 445 was open during the initial nmap scan, you can use impacket’s smbclient with the -k option to use kerberos. This will help validate if you have a valid username and password pair. Since public shares can be browsed with the valid credential you can pull down the Network Security Changes.pdf file to view its contents.
Enumerating SMB shares using TGT: I used the TGT to access the SMB shares and found a file named “Network Security Changes.pdf”.
Most ksimpson can’t access:
There’s a single document in Public:
Network Security Changes.pdf: The document is a letter from the IT staff to all employees: This mentions again that NTLM is disabled because of an NTLM relay attack, and now everything is done via Kerberos. It also mentions that the SQL database has had access removed from the HR department.
Kerberoast:
Collect Challenge/Response GetUserSPNs.py (another Impactet script) is typically how fetch a potentially crackable challenge/response from a Windows Server. However, when Scrambled was released, it breaks:
Some Googling shows that the author of this box has raised an issue on the Impacket GitHub for this very error with the title “GetUserSpns.py fails when using -k option and NTLM auth is disabled”. The suggested fix in that issue is to edit one line, which I’ll do on line 260:
After making that change, it dumps a challenge/response (or “hash”, but not really a hash) for the MSSQLSvc user: GetUserSPNs.py scrm.local/ksimpson:ksimpson -dc-ip dc1.scrm.local -request -k
The issue has been fixed, and if I use the up to date Impacket, I just need to use -dc-host instead of -dc-ip:
MSSQL Access: Silver Ticket
These creds don’t actually directly allow access to anything new for me. But because this account is running the SQL service, I can use the password to perform a Silver Ticket attack. The overview linked there from adsecurity.org is really good. A Silver Ticket is a forged TGS (Ticket Granting Service) ticket, which is used directly between the client and the service, without necessarily going to the DC. Instead, the TGS ticket is signed by the service account itself, and thus the Silver Ticket is limited to authenticating only the service itself.
To create a Silver Ticket, an attacker needs:
The NTLM hash of the password for the service account;
The SID of the domain
The service principle name (SPN) associated with the account.
NTLM Hash: To get an NTLM hash of the password “Pegasus60”, I’ll use the commands from this post:
Domain SID: To get the domain SID, I’ll need to connect back to LDAP, but authenticated. It takes a good deal of troubleshooting and Goolging to get this working (thanks to TheCyberGeek for some tips on this one). If I try to connect as ksimpson, I get an error about SSL/TLS being required:
SPN: I already acquired the SPN with GetUserSPNS.py above, MSSQLSvc/dc1.scrm.local:1433.
Generate Ticket: ticketer.py (or impacket-ticketer) will generate a ticket using the information gathered:
The output file is administrator.ccache, which is a kerberos ticket as administrator that only the MSSQL service will trust.
Connect: On Linux, Kerberos looks in predefined places for tickets, like /tmp/krb5cc_[uid of current user] and any file pointed to by the KRB5CCACHE environment variable. If I just run klist, it will fail to find the new ticket: Using that same method, mssqlclient.py can connect to the DB using the ticket:
MSSQL Enumeration:
Find Password: I’ll start by listing the databases:
ScrambleHR seems interesting. It has three tables:
The Employees and Timesheets tables are empty. There’s one row in UserImport:
Execute: MSSQL has the ability to run commands via the xp_cmdshell stored procedure. It is possible to do so here, but the service account doesn’t have access to much of anything on the box, and it was meant to largely be a dead end.
In addition, if we enable the de xp_cmdshell module, we can execute commands on the machine.
In order to get a reverse shell, you can use the "PowerShell #3 (Base64)" from revshells.com.
Running a whoami /priv command shows us that we do have SeImpersonatePrivilege. Since we have those privileges we can run a potato attack against the sql server and should be able to obtain access as SYSTEM.
Using Powershell Credential Object to gain shell as MiscSvc
Now, we need to create another reverse shell in order to become MiscSvc, obtaining the user flag. For doing so, execute the following commands:
Create another Windows base64 encoded payload for the MiscSvc reverse shell and then execute the payload as MiscSvc.
PRIV ESC: Shell as System
Enumeration:
ScrambleClient Reverse:
Files: Both files are 32-bit .NET executables:
Connect: I’ll jump over to a Windows VM (this part is the same as the Windows Post). Running the EXE pops the same windows from the IT pages: With my VPN connected and my C:\Windows\System32\drivers\etc\hosts file updated, I’ll click “Edit” and enter the server (the port is already filled): I’ll also check the “Enable debug logging” box. Trying to “Sign In” with any of the creds I have fails: If I try that again with WireShark, it shows it’s a text-based protocol:
Credentials: Opening the binaries in DNSpy, I’ll start with an overview of the files:
LoginWindow seems promising. Several functions down, there’s a Logon function: Clicking on the Logon that’s called from this._Client.Logon jumps over into the ScrambleNetClient class in ScrambleLib, where Logon is defined: There’s a backdoor account if the username is “scrmdev”! Going back to the app, changing the username to that works:
LIST_ORDERS: In WireShark, there’s a new TCP stream (not from the login, as I bypassed that) fetching orders: The client send LIST_ORDERS; on successful login. The returned base64 string is a serialized .NET object:
Debug Log: If I enabled it in the connection settings, or by going to “Tools” > “Enable Debug Logging”, it will write ScrambleDebugLog.txt in the same directory as the exe. This is not only another way to see the serialized payloads, but there are some hints in there as well: “Binary formatter init successful” will be useful in the next attack. I can see exactly in the code where this happens, in the SalesOrder class in ScrambleLib.dll:
Deserialization Attack:
Generate Payload: I’ll download the latest copy of ysoserial.net from the release page. This is a tool that will generate .NET serialized payloads that will abuse different gadgets in the existing code to get code execution. I’ve not been able to get this tool to run on Linux, so I will have to jump to a Windows VM to generate this payload.
Some Googling about the binary formatter class specifically will show it’s insecure. From Microsoft doc:
Knowing the plugin that’s installed, I just need to pick a gadget. They are all listed on the GitHub page or with ysoserial.exe -h. I want one that works with BinaryFormatter, and I’ll start with ones that don’t require any special conditions. AxHostState seems like a good start (many will work). I’ll it:
Send Payload: I’ll listen with nc on TCP 444 and connect to 4411 with nc:
Just like in WireShark, I’ll enter UPLOAD_ORDER;[serialized object]:
It throws an error, and hangs. At nc:
Last updated