MSSQL Injection
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Możliwe jest enumerowanie użytkowników domeny za pomocą SQL injection wewnątrz serwera MSSQL przy użyciu następujących funkcji MSSQL:
SELECT DEFAULT_DOMAIN()
: Pobierz nazwę bieżącej domeny.
master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator'))
: Jeśli znasz nazwę domeny (DOMAIN w tym przykładzie), ta funkcja zwróci SID użytkownika Administratora w formacie hex. Będzie to wyglądać jak 0x01050000000[...]0000f401
, zwróć uwagę, że ostatnie 4 bajty to liczba 500 w formacie big endian, co jest wspólnym ID użytkownika administratora.
Ta funkcja pozwoli Ci poznać ID domeny (wszystkie bajty oprócz ostatnich 4).
SUSER_SNAME(0x01050000000[...]0000e803)
: Ta funkcja zwróci nazwa użytkownika wskazanego ID (jeśli istnieje), w tym przypadku 0000e803 w big endian == 1000 (zwykle jest to ID pierwszego regularnego użytkownika). Możesz sobie wyobrazić, że możesz brute-forcować ID użytkowników od 1000 do 2000 i prawdopodobnie uzyskać wszystkie nazwy użytkowników domeny. Na przykład używając funkcji podobnej do poniższej:
Wstrzyknięcia SQL oparte na błędach zazwyczaj przypominają konstrukcje takie jak +AND+1=@@version--
oraz warianty oparte na operatorze «OR». Zapytania zawierające takie wyrażenia są zazwyczaj blokowane przez WAF. Jako obejście, konkatenować ciąg za pomocą znaku %2b z wynikiem określonych wywołań funkcji, które wywołują błąd konwersji typu danych na poszukiwanych danych.
Niektóre przykłady takich funkcji:
SUSER_NAME()
USER_NAME()
PERMISSIONS()
DB_NAME()
FILE_NAME()
TYPE_NAME()
COL_NAME()
Przykład użycia funkcji USER_NAME()
:
Te sztuczki SSRF zostały wzięte stąd
fn_xe_file_target_read_file
Wymaga uprawnienia VIEW SERVER STATE
na serwerze.
fn_get_audit_file
Wymaga uprawnienia CONTROL SERVER
.
fn_trace_gettabe
Wymaga uprawnienia CONTROL SERVER
.
xp_dirtree
, xp_fileexists
, xp_subdirs
Procedury składowane, takie jak xp_dirtree
, choć nieudokumentowane oficjalnie przez Microsoft, zostały opisane przez innych w Internecie z powodu ich użyteczności w operacjach sieciowych w MSSQL. Procedury te są często wykorzystywane w exfiltracji danych Out of Band, co zostało pokazane w różnych przykładach i postach.
Procedura składowana xp_dirtree
, na przykład, jest używana do wykonywania żądań sieciowych, ale jest ograniczona tylko do portu TCP 445. Numer portu nie jest modyfikowalny, ale pozwala na odczyt z udziałów sieciowych. Użycie jest pokazane w poniższym skrypcie SQL:
Warto zauważyć, że ta metoda może nie działać na wszystkich konfiguracjach systemu, takich jak Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)
działający na Windows Server 2016 Datacenter
z ustawieniami domyślnymi.
Dodatkowo istnieją alternatywne procedury składowane, takie jak master..xp_fileexist
i xp_subdirs
, które mogą osiągnąć podobne wyniki. Dalsze szczegóły dotyczące xp_fileexist
można znaleźć w tym artykule TechNet.
xp_cmdshell
Oczywiście można również użyć xp_cmdshell
, aby wykonać coś, co wyzwala SSRF. Aby uzyskać więcej informacji, przeczytaj odpowiednią sekcję na stronie:
Tworzenie CLR UDF (Common Language Runtime User Defined Function), czyli kodu napisanego w dowolnym języku .NET i skompilowanego do DLL, który ma być załadowany w MSSQL w celu wykonywania niestandardowych funkcji, to proces, który wymaga dostępu dbo
. Oznacza to, że zazwyczaj jest to wykonalne tylko wtedy, gdy połączenie z bazą danych jest nawiązywane jako sa
lub z rolą Administratora.
Projekt Visual Studio oraz instrukcje instalacji są dostępne w tym repozytorium Github, aby ułatwić załadowanie binarnego pliku do MSSQL jako zestawu CLR, co umożliwia wykonywanie żądań HTTP GET z poziomu MSSQL.
Rdzeń tej funkcjonalności jest zawarty w pliku http.cs
, który wykorzystuje klasę WebClient
do wykonania żądania GET i pobrania treści, jak pokazano poniżej:
Przed wykonaniem polecenia SQL CREATE ASSEMBLY
, zaleca się uruchomienie następującego fragmentu SQL, aby dodać hash SHA512 zestawu do listy zaufanych zestawów serwera (widocznej za pomocą select * from sys.trusted_assemblies;
):
Po pomyślnym dodaniu zestawu i utworzeniu funkcji, poniższy kod SQL może być wykorzystany do wykonywania żądań HTTP:
Zwięzła metoda na wyodrębnienie pełnej zawartości tabeli w jednym zapytaniu polega na wykorzystaniu klauzuli FOR JSON
. To podejście jest bardziej zwięzłe niż użycie klauzuli FOR XML
, która wymaga określonego trybu, takiego jak "raw". Klauzula FOR JSON
jest preferowana ze względu na swoją zwięzłość.
Oto jak pobrać schemat, tabele i kolumny z bieżącej bazy danych:
For users granted the VIEW SERVER STATE
permission on the server, it's possible to see all executing sessions on the SQL Server instance. However, without this permission, users can only view their current session. The currently executing SQL query can be retrieved by accessing sys.dm_exec_requests and sys.dm_exec_sql_text:
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)