SQL Server-Injektion - wie viel Schaden in 26 Zeichen?

21

Ich teste die Widerstandsfähigkeit gegen Injektionsangriffe auf eine SQL Server-Datenbank.

Alle Tabellennamen in der Datenbank sind Kleinbuchstaben, und die Sortierung unterscheidet zwischen Groß- und Kleinschreibung ( Latin1_General_CS_AS) .

Die Zeichenfolge, die ich senden kann, muss in Großbuchstaben geschrieben werden und darf maximal 26 Zeichen lang sein. Daher kann ich keine DROP TABLE senden, da der Tabellenname in Großbuchstaben geschrieben ist und die Anweisung daher aufgrund der Sortierung fehlschlagen würde.

Also - was ist der maximale Schaden, den ich mit 26 Charakteren anrichten kann?

BEARBEITEN

Ich weiß alles über parametrisierte Abfragen und so weiter. Stellen wir uns vor, dass die Person, die das Front-End entwickelt hat, das die Abfrage zum Senden erstellt, in diesem Fall keine Parameter verwendet hat.

Ich versuche auch nicht, etwas Schändliches zu tun, dies ist ein System, das von jemand anderem in derselben Organisation erstellt wurde.

Alan B
quelle
1
Stellen wir uns vor, oder testen Sie tatsächlich Stifte und haben Anforderungen, die es Ihnen nicht erlauben, eine Injektion zu vermeiden? Suchen Sie nach einem Weg, um seine mangelnde Sicherheit zu brechen?
LowlyDBA
41
Warum ist es überhaupt möglich, die Tür offen zu lassen? Dies scheint, als hätten Sie bereits mehr Zeit damit verbracht, darüber nachzudenken, als es kosten würde, die Tür zu verriegeln. Ich empfinde dies als fruchtlose Übung - wenn Sie 10 Schwachstellen finden, werden diese 10 Schwachstellen beseitigt, und es wird mit Sicherheit keine 11. geben. Dies ist, wo "Reinigung" Saiten uns haben. / facepalm
Aaron Bertrand
5
Dies ist eine wahnsinnig vage und willkürliche Frage, und sie kann theoretisch nicht einmal angesprochen werden. Es gibt andere systemeigene mildernde Funktionen von SQL Injection (Berechtigungen, Sandbox, Firewalls usw.), und Sie müssten all diese Dinge berücksichtigen, um diese Frage zu beantworten.
Evan Carroll
2
Was setzt die Beschränkung auf 26 Zeichen durch? Die Anwendung?
Jonathan Fite
7
Hör auf. Hör einfach auf. Wenn parametrisierte Abfragen per Fernzugriff möglich sind, verwenden Sie sie . Wenn jemand anderes nicht weiß, wie man sie benutzt, finden Sie eine anständige Ressource und lassen Sie sie lesen. Wenn sie nicht zuhören, benachrichtigen Sie einen Manager oder Vorgesetzten, der kritische Sicherheitslücken aufweist (eine zerstörungsfreie Demo würde nicht schaden), und lehnen Sie es ab, ausgebildet zu werden.
jpmc26

Antworten:

38

Einfach:

GRANT EXECUTE TO LowlyDBA

Oder ich denke in diesem Fall wäre es

grant execute to lowlydba 

Wählen Sie Variationen aus.

Es ist sehr wahrscheinlich, dass Sie dies jetzt auf Ihrem aktuellen System testen können, aber eine Reihe kleiner Änderungen in der Datenbank im Laufe der Zeit können Ihre Tests ungültig machen. Die Zeichenfolge könnte sich ändern, jemand könnte eine gespeicherte Prozedur in Kleinbuchstaben erstellen, die destruktiv sein kann - alles. Man kann niemals mit hundertprozentiger Sicherheit sagen, dass es keinen zerstörerischen Angriff mit 26 Charakteren gibt, den jemand erstellen könnte.

Ich schlage vor, dass Sie einen Weg finden, den Entwickler dazu zu bringen, die grundlegenden Best-Security-Praktiken des Industriestandards zu befolgen , wenn auch nur zu Ihrem eigenen Vorteil, da jemand, von dem ich annehme, zumindest teilweise verantwortlich ist, falls Sicherheitsverletzungen auftreten.

Bearbeiten:

Und aus Bösartigkeit / Spaß könnten Sie versuchen, jedes Ablaufverfolgungsflag zu aktivieren . Das wäre interessant zu beobachten. Fühlt sich an wie ein Blogbeitrag, den Brent Ozar machen würde ...

DBCC TRACEON(xxxx, -1)
LowlyDBA
quelle
1
Neben der Möglichkeit , Trace - Flags: Ändern verschiedene zufällige Einstellungen: SET LOCK_TIMEOUT 0;, SET LANGUAGE Malaysian;, SET ANSI_NULLS OFF:...
ypercubeᵀᴹ
2
@ ypercubeᵀᴹ sie würden alle nur Ihre eigene Sitzung beeinflussen.
Martin Smith
2
@MartinSmith danke. Wenn SETnur Sitzungseinstellungen betroffen sind, wie werden Satabase- und Servereinstellungen geändert ( ALTER DATABASE ...;?), DROP DATABASE ..;Würde dies mehr Schaden verursachen, wenn dies erfolgreich war;)
ypercubeᵀᴹ
1
Ändern Sie die Datenbank und sp_configure hauptsächlich für Einstellungen auf DB- und Serverebene. Allerdings könnten Sie damit das Limit von 26 Zeichen überschreiten. Auch diese spezifischen Einstellungen auf Datenbankebene werden nur verwendet, wenn die Client-Verbindung sie nicht festlegt. Und standardmäßig tun es die meisten oder alle.
Martin Smith
7
Ich ähnele dieser Bemerkung.
Brent Ozar
22

Der SHUTDOWNBefehl oder KILLBefehl (wählen Sie eine Zufallszahl über 50 aus) dauert beide deutlich weniger als 26 Zeichen, obwohl das Konto, das die Anwendungsabfragen ausführt, hoffentlich nicht über ausreichende Berechtigungen verfügt, um diese auszuführen.

Martin Smith
quelle
Normalerweise würde der Account auch keinen Drop Table benötigen ...
Greg
3
@ Greg yep. Sie können jedoch davon ausgehen, dass in einer Umgebung, in der eine SQL-Injektion in Betracht gezogen wird, die Länge kurz ist, nicht den bewährten Sicherheitsmethoden entspricht und die Konten möglicherweise nicht mit minimalen Berechtigungen konfiguriert sind.
Martin Smith
14

Sie können eine Tabelle erstellen, die Sie dann füllen, bis das Ende der Zeit oder der Speicherplatz abläuft, je nachdem, was zuerst eintritt.

declare @S char(26);

set @S = 'create table t(c char(99))';
exec (@S);

set @S = 'insert t values('''')'
exec (@S);

set @S = 'insert t select c from t'
exec (@S);
exec (@S);
exec (@S);
exec (@S);
-- etc
Mikael Eriksson
quelle
19
@ AlanB Nun, dann brauchst du etwas, das mich davon abhält, die Schwäche mehr als einmal auszunutzen.
Mikael Eriksson
1
tarnations ... while 1=1 insert t values('')is 30 ... create table x(i int)=> while 1=1 insert t select 0is 27
WernerCD
1
Könnten Sie dies verwenden, um einen längeren Befehl als die Zeichenbeschränkung zu erstellen und diesen dann auszuführen?
Lawtonfogle
1
@MartinSmith Ich dachte, ich würde einfach so gehen, aber jetzt muss ich es einfach ausprobieren :). Lass es dich wissen, wenn ich es herausfinde.
Mikael Eriksson
7
@ WernerCD x:insert t select 0 GOTO xist aber genau 26.
Martin Smith
4

Abhängig von Ihrer Definition des Schadens können Sie Folgendes ausführen: WAITFOR DELAY '23: 59 'Um wirklich böse zu sein, können Sie ein Auslastungstest-Tool verwenden, um dies von 32.768 Clients auszuführen.

user143642
quelle
1
Wenn die Zeichenfolge in einen Ad-hoc-Stapel eingefügt wird, der Sperren enthält, kann dies als einzelner Aufruf zu einem Denial-of-Service führen, ohne dass ein Thread-Hunger verursacht werden muss.
David Spillett
3

Variation basierend auf der Antwort von @ MikaelEriksson und der Antwort von @ MartinSmith auf meinen ersten Kommentar:

declare @S char(26);

set @S = 'create table x(i int)';
exec (@S);

Anfangs hatte ich versucht, eine WHILE-Anweisung auszuführen, aber das Beste, was ich tun konnte, waren 27 Zeichen:

set @S = 'while 1=1 insert t select 0'; -- fails at 27 characters
exec (@S);

Aber Martin wies auf GOTO hin:

set @S = 'x:insert t select 0 GOTO x';
exec (@S);

GOTO ... die Wurzel allen Übels und der Schöpfer einer Endlosschleifen-Einfügeanweisung in 26 Zeichen.

Vor diesem Hintergrund ... könnte es vorteilhaft sein, CHAR (99) anstelle von int zu verwenden, da dies mehr Speicherplatz beanspruchen würde. Andere Optionen verwenden entweder längere Namen und überschreiten das Limit von 26 Zeichen ... oder belegen weniger Speicherplatz pro Zeile.

Vollständiger Testcode:

declare @S char(26);
set @S = 'drop table t;';
exec (@S);
GO

declare @S char(26);

set @S = 'create table t(c CHAR(99))';
exec (@S);

set @S = 'x:insert t select 0 GOTO x';
exec (@S);
GO
WernerCD
quelle
1
set @S = 'x:insert t;select 0;GOTO x';für die zukünftige Kompatibilität Ihres Injektionsangriffs;)
ypercubeᵀᴹ
@ ypercubeᵀᴹ Sie haben zwei ;s hinzugefügt ... die zweite ist in Ordnung - ersetzt ein Leerzeichen und ist funktionsfähig, wenn sie nicht benötigt wird. Das erste unterbricht die Abfrage - trennt die INSERT-Anweisung von der SELECT-Anweisung.
WernerCD
Ah ja. Das passiert, wenn man keine Trennzeichen verwendet! Wir wissen nicht, wo jede Abfrage endet und wann die nächste beginnt!
ypercubeᵀᴹ
1
@ WarnerCD Ich weiß. Es war eher ein Scherz über das Abschreibungsverfahren in SQL Server. Es scheint ewig zu dauern. Es hat sich jedoch bewährt, Semikolons zwischen Anweisungen zu verwenden und nicht nur dort, wo dies erforderlich ist.
ypercubeᵀᴹ
2
@yper Ich bezweifle, dass es jemals durchgesetzt wird. Wahrscheinlich gibt es eine Menge Legacy-Code, für den fehlende Semikolons hinzugefügt werden müssten, ohne dass dies einen besonderen geschäftlichen Nutzen hätte. Und es könnte in Anwendungen eingebettet sein, deren Aktualisierung schwierig oder nicht möglich ist.
Martin Smith
0
XP_CMDSHELL 'SHUTDOWN -PF'

Abhängig davon, wie schädlich Sie einen Stromausfall finden. :-)

Dazu muss xp_cmdshell auf dem Server aktiviert sein, was bei den letzten Versionen von SQL Server nicht der Fall ist. Außerdem muss das Dienstkonto über das Recht zum Herunterfahren verfügen, über das es möglicherweise verfügt oder nicht.

Das Aktivieren von xp_cmdshell überschreitet wahrscheinlich die maximal zulässige Länge von 26 Zeichen. Würden Sie mehrere Injektionen erlauben?

SP_CONFIGURE 'SHOW ADV',1

RECONFIGURE

SP_CONFIGURE 'XP', 1

RECONFIGURE
Greenstone Walker
quelle
1
Die EXEC ist nur optional, wenn dies die erste Anweisung im Stapel ist. Was hier wahrscheinlich nicht der Fall sein wird.
Martin Smith
@ Martin Smith, guter Kommentar. EXEC fügt jeder Prozeduraufrufzeile 5 Zeichen hinzu, wodurch die meisten von ihnen über 26 Zeichen verschoben werden. Ich frage mich, ob CREATE ALIAS hier helfen würde?
Greenstone Walker