For the complete documentation index, see llms.txt. This page is also available as Markdown.

SQL

DarkHaven Technologies - Range (Medium) - by Ryan Yager

The following post by 0xb0b is licensed under CC BY 4.0


Entry Point

Reference:

Recon

We use rustscan -b 500 -a sql.ext.darkhaven.local --top -- -sC -sV -Pn to enumerate all TCP ports on the target machine, piping the discovered results into Nmap which runs default NSE scripts -sC, service and version detection -sV, and treats the host as online without ICMP echo -Pn.

A batch size of 500 trades speed for stability, the default 1500 balances both, while much larger sizes increase throughput but risk missed responses and instability.

As expected with SQL Server, we have an MSSQL service running on port 1433.

Remote access is also available via RDP 3389 and WinRM 5985.

MSSQL

For your reference, we can use the following cheat sheet. First, we want to connect to the MSSQL service, and we'll use the credentials for sql_svc to do so.

We use impackets' mssqlclient. We can connect.

We're performing basic enumeration, but we haven't found anything unusual in the databases.

We see that we are sysadmin.

And we are able to use xp_cmdshell, which allows us to execute code. We perform command execution as NT AUTHORITY SYSTEM.

Shell as NT AUTHORITY SYSTEM

Since we have code execution via xp_cmdshell, we want to extend this to an interactive shell. To do this, we're now bringing out the big guns and retrieving knowledge from Staged. Specifically, we want to leverage Sliver.

Startup Sliver Server

We run the sliver server.

Prepare a cusom stager

First we need to prepare the stager.

The stager fetches raw shellcode from a chosen url and loads it directly into memory as bytes. The payload is not embedded in the binary, allowing it to be changed without recompiling.

It calls VirtualAlloc to reserve and commit memory with execute, read, and write permissions, then copies the downloaded shellcode into that memory using unsafe pointer operations.

The execution is transferred to the allocated memory address using syscall.Syscall, handing control to the shellcode.

We compile the stager as follows on our exegol instance:

Generate shell code

During generation without the -G tag, which disables the encoder, no shellcode could be successfully generated. The resulting shellcode was always empty. This may be related to the underlying architecture on which I am operating, namely ARM:

https://github.com/BishopFox/sliver/issues/1114

Next, we need to generate the shell code. We do this as follows:

Setup listener

We set up the listener.

Run web server

And run a web server from which the stager and the shellcode can be fetched.

Download and execute stager

As before, we prepare the payload for downloading and executing the stager. We encode this payload so that we don't encounter any problems with the web shell during execution with regard to special characters, etc.

We'll receive the following base64 encoded command.

With the web server prepared, we execute the payload.

We see that the stager and the shellcode gets downloaded...

... and executed. We receive a session in SliverC2.

Without spawning a shell we can retrieve the current user and the privileges. Furthermore we are able to retrieve the first flag from the SQL server at C:\Users\Administrator\Desktop\root.txt.

Post Compromise

Exfiltration of Files

We see two users on the system: yager and sql_svc_int.

While listing the user directories, we notice that a KeePass installer is located in the admin directory structure.

However, we were unable to locate the key database, and even a manual check did not yield any results.

We dig through the system and find the stored_passwords folder in the root directory. Here we find an it_passwords.kdbx file and a README. We download both.

Here we find an it_passwords.kdbx file and a README. We download both.

In the README file, we find the master password for the KeePass file.

We unlock the database and find a lot of credentials.

We create a list of usernames and passwords, with each row corresponding to an entry in KeePass, so that we can perform a password spray using NetExec later on. Based on the password policy, we know that accounts will not be locked immediately after the first incorrect login attempt.

We run a simple password spray using NetExec and got some hits, including for the users svc_backup and showard.

SharpHound / BloodHound Enumeration

Since we are NT AUTHORITY SYSTEM and the computer appears to be connected to a domain, we will now attempt to enumerate it. We upload the latest version of SharpHound.exe from the BloodHound CE project.

Unfortunately, I haven't found a way to run this outside of a shell, so we'll spawn a shell here.

Now we are able to run SharpHound.exe and collect the data.

We deatach our shell session with CTRL+D.

And download the BloodHound loot as follows.

We can see that the svc_backup user can enroll in several certificate templates, including a GenericAll template for the domain controller certificate. Technically speaking, this would allow an ESC4.

ESC4 is when a user has write/control permissions over a certificate template, allowing them to modify it, enabling client authentication and allowing arbitrary subject names. By reconfiguring the template this way, they turn it into an ESC1 scenario, where they can request a certificate impersonating a high-privilege account.

However, we also note that this applies to all users in the group authenticated users.

It turns out this quick win isn't feasible. If anyone manages to pull it off, please let me know. In testing, I was not able to exploit this using Certify.exe locally on the CA and via Certipy. It seems to have been patched in a sloppy way; RPC calls are not allowed. Well, something you could face in an engagemnet and fall for.

We'll look at the shortest path.

It is interesting to note that the ca_svc_accounts$ account has an AllowedToAct permission on the CA.EXT.DARKHAVEN.LOCAL machine, which in turn has a CoerceToTGT permission on the EXT.DARKHAVEN.LOCAL domain. This allows us to chain resource-based constrained delegation with coercion to force authentication from the domain controller, relay it, and obtain a TGT on its behalf. This would enable a full domain compromise by impersonating the DC account and leveraging it for privileged access.

Furthermore, we see another path, the ldap_svc account is a domain admin, maybe we are able compromise this account later...

Last updated