MSSQL Injection
Last updated
Last updated
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Es kann möglich sein, Domänenbenutzer über SQL-Injection innerhalb eines MSSQL-Servers mit den folgenden MSSQL-Funktionen aufzulisten:
SELECT DEFAULT_DOMAIN()
: Aktuellen Domänennamen abrufen.
master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator'))
: Wenn du den Namen der Domäne (DOMAIN in diesem Beispiel) kennst, gibt diese Funktion die SID des Benutzers Administrator im Hex-Format zurück. Dies wird wie 0x01050000000[...]0000f401
aussehen, beachte, dass die letzten 4 Bytes die Zahl 500 im Big Endian-Format sind, was die gemeinsame ID des Benutzers Administrator ist.
Diese Funktion ermöglicht es dir, die ID der Domäne zu kennen (alle Bytes außer den letzten 4).
SUSER_SNAME(0x01050000000[...]0000e803)
: Diese Funktion gibt den Benutzernamen der angegebenen ID zurück (falls vorhanden), in diesem Fall 0000e803 im Big Endian == 1000 (normalerweise ist dies die ID des ersten regulären Benutzerkontos, das erstellt wurde). Dann kannst du dir vorstellen, dass du Benutzer-IDs von 1000 bis 2000 brute-forcen kannst und wahrscheinlich alle Benutzernamen der Benutzer der Domäne erhältst. Zum Beispiel mit einer Funktion wie der folgenden:
Error-basierte SQL-Injektionen ähneln typischerweise Konstruktionen wie +AND+1=@@version--
und Varianten, die auf dem «OR»-Operator basieren. Abfragen, die solche Ausdrücke enthalten, werden normalerweise von WAFs blockiert. Als Umgehung können Sie einen String mit dem %2b-Zeichen an das Ergebnis spezifischer Funktionsaufrufe anhängen, die einen Datentypkonvertierungsfehler bei den gesuchten Daten auslösen.
Einige Beispiele für solche Funktionen:
SUSER_NAME()
USER_NAME()
PERMISSIONS()
DB_NAME()
FILE_NAME()
TYPE_NAME()
COL_NAME()
Beispiel für die Verwendung der Funktion USER_NAME()
:
Diese SSRF-Tricks wurden hierher übernommen
fn_xe_file_target_read_file
Es erfordert die Berechtigung VIEW SERVER STATE
auf dem Server.
fn_get_audit_file
Es erfordert die CONTROL SERVER
Berechtigung.
fn_trace_gettabe
Es erfordert die CONTROL SERVER
Berechtigung.
xp_dirtree
, xp_fileexists
, xp_subdirs
Gespeicherte Prozeduren wie xp_dirtree
, obwohl von Microsoft nicht offiziell dokumentiert, wurden von anderen online aufgrund ihrer Nützlichkeit in Netzwerkoperationen innerhalb von MSSQL beschrieben. Diese Prozeduren werden häufig bei Out of Band Data Exfiltration verwendet, wie in verschiedenen Beispielen und Beiträgen gezeigt.
Die gespeicherte Prozedur xp_dirtree
wird beispielsweise verwendet, um Netzwerkrequests zu machen, ist jedoch auf den TCP-Port 445 beschränkt. Die Portnummer ist nicht änderbar, erlaubt jedoch das Lesen von Netzwerkfreigaben. Die Verwendung wird im folgenden SQL-Skript demonstriert:
Es ist bemerkenswert, dass diese Methode möglicherweise nicht auf allen Systemkonfigurationen funktioniert, wie zum Beispiel auf Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)
, der auf einem Windows Server 2016 Datacenter
mit Standardeinstellungen läuft.
Zusätzlich gibt es alternative gespeicherte Prozeduren wie master..xp_fileexist
und xp_subdirs
, die ähnliche Ergebnisse erzielen können. Weitere Details zu xp_fileexist
finden Sie in diesem TechNet-Artikel.
xp_cmdshell
Offensichtlich könnten Sie auch xp_cmdshell
verwenden, um etwas auszuführen, das eine SSRF auslöst. Für weitere Informationen lesen Sie den entsprechenden Abschnitt auf der Seite:
Die Erstellung einer CLR UDF (Common Language Runtime Benutzerdefinierte Funktion), die in einer beliebigen .NET-Sprache verfasster Code ist und in eine DLL kompiliert wird, um innerhalb von MSSQL für die Ausführung benutzerdefinierter Funktionen geladen zu werden, ist ein Prozess, der dbo
-Zugriff erfordert. Das bedeutet, dass es normalerweise nur möglich ist, wenn die Datenbankverbindung als sa
oder mit einer Administratorrolle hergestellt wird.
Ein Visual Studio-Projekt und Installationsanweisungen sind in diesem Github-Repository bereitgestellt, um das Laden der Binärdatei in MSSQL als CLR-Assembly zu erleichtern, wodurch die Ausführung von HTTP GET-Anfragen aus MSSQL heraus ermöglicht wird.
Der Kern dieser Funktionalität ist in der Datei http.cs
gekapselt, die die Klasse WebClient
verwendet, um eine GET-Anfrage auszuführen und Inhalte wie unten dargestellt abzurufen:
Bevor Sie den CREATE ASSEMBLY
SQL-Befehl ausführen, wird empfohlen, den folgenden SQL-Snippet auszuführen, um den SHA512-Hash der Assembly zur Liste der vertrauenswürdigen Assemblies des Servers hinzuzufügen (einsehbar über select * from sys.trusted_assemblies;
):
Nach dem erfolgreichen Hinzufügen der Assembly und der Erstellung der Funktion kann der folgende SQL-Code verwendet werden, um HTTP-Anfragen durchzuführen:
Eine prägnante Methode zum Extrahieren des vollständigen Inhalts einer Tabelle in einer einzigen Abfrage besteht darin, die FOR JSON
-Klausel zu verwenden. Dieser Ansatz ist kürzer als die Verwendung der FOR XML
-Klausel, die einen bestimmten Modus wie "raw" erfordert. Die FOR JSON
-Klausel wird aufgrund ihrer Kürze bevorzugt.
So rufen Sie das Schema, die Tabellen und die Spalten aus der aktuellen Datenbank ab:
To check if you have the VIEW SERVER STATE permission, the following query can be used:
Non-standard whitespace characters: %C2%85 или %C2%A0:
Scientific (0e) and hex (0x) notation for obfuscating UNION:
A period instead of a whitespace between FROM and a column name:
\N separator between SELECT and a throwaway column:
According to this blog post it's possible to stack queries in MSSQL without using ";":
So for example, multiple queries such as:
Can be reduced to:
Therefore it could be possible to bypass different WAFs that doesn't consider this form of stacking queries. For example:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)