Trojan Source mit SQL und Postgres

vorhergehende Artikel in: Markup Datenbanken Security
12.11.2021

Nachdem ich das hochinteressante Paper Trojan Source: Invisible Vulnerabilities gelesen hatte kam ich durch einen Post auf Mastodon (leider nicht öffentlich einsehbar) auf Ideen... auf Ideen...

Der Mastodon-Post zeigte eine Tabelle in psql, die eine Spalte beinhaltete, deren Name ein Kätzchen war (Unicode-Emoji). Der sorgte dafür, dass sämtliche Projekte einen Platz auf meiner Liste nach unten rutschten, denn ich wollte nun wissen, ob das in dem Paper vorgestellte Verfahren auch dazu benutzt werden könnte, schadhaften SQL-Code vor einem Reviewer zu verstecken.

Dazu stellte ich mir zunächst eine einfache Aufgabe: Ich wollte einen Spaltennamen oder allgemeiner: Identifier mit solchen nicht sichtbaren Unicode-Zeichen versehen, sodass der Code in einem Editor, Terminal oder dem Datenbanktool des Vertrauens anders aussähe, als das, was die Datenbank verarbeitet. Dazu bereitete ich ein SQL-Statement vor, das einen zusammengesetzten Spaltennamen SpaltenName enthielt, der allerdings mit entsprechenden Bidi-Codes so ergänzt war, dass eine Software, die diese Codes interpretiert stattdessen NameSpalten anzeigen müsste.

Hier ein Beispiel dafür in Gedit 2.36.2 unter Ubuntu Focal Fossa:

Screenshot SQL-Script in Gedit 2.36.2

Ich freue mich sagen zu können, dass auch die sQLshell sich hier nicht hereinlegen lässt (und damit auch den Anwender nicht hereinlegt) - sie zeigt an, dass im SQL weitere Zeichen enthalten sind:

Screenshot SQL-Script in sQLshell

Intellij Idea stellt die Goldrandlösung dar: solche Codes werden nicht nur nicht interpretiiert, sondern stattdessen als Pseudo-Zeichen dargestellt:

Screenshot SQL-Script in sQLshell

Nachdem ich mir also verschiedene Editoren und IDEs zum Umgang mit diesen speziallen UInicode-Characters angesehen hate, wollte ich herausbekommen, wie sich eine Datenbank verhält, wenn sie ein mit solchen Zeichen versehenes Statement vorgesetzt bekommt. Meine ersten Tests führte ich mit einer etwas veralteten Version Postgres durch:

Screenshot Postgres Version im Test

Ich benutzte zur Interaktion damit zunächst psql in verschiedenen Terminals - darunter gnome-terminal und CoolRetroTerm. Interessant fand ich dabei zunächst, dass in diesen Terminals die Steuercodes im Statement nicht angezeigt und auch nicht interpretiert wurden - Man hätte meinen können, dass dieses Statement überhaupt keine Steuerzeichen enthielt:

Screenshot SQL-Script in CoolRetroTerm

Jetzt wurde ich natürlich neugierig, ob sich das Statement absetzen lassen würde - es funktionierte. Und bei der Abfrage der Tabellenstruktur in psql mittels \d bidi erhielt ich daraufhin folgendes Ergebnis:

Screenshot Tabellenstruktur mittels psql in CoolRetroTerm

Ein entsprechendes Select schlug aber fehl:

Screenshot Select-Statement und Ergebnis mittels psql in CoolRetroTerm

Ein normaler Mensch wäre jetzt zunächst erst einmal verwirrt: Er sieht den Spaltennamen, aber wenn er ihn benutzen möchte, bekommt er als Fehlermeldung, dass exakt dieser - den erwomöglich auch noch aus der Antwort auf das vorhergehende Statement kopiert hat - nicht existiert? Was ist denn hier passiert? Die Erklärung wird offensichtlich, wenn man sich die Tabellenstruktur in anderen Datenbank-Werkzeugen ansieht - zum Beispiel in der sQLshell:

Screenshot Tabellenstruktur in der sQLshell

Man erkennt, dass die Control-Characters einfach Teil des Identifiers geworden sind. Um die Anfrage korrekt zu formulieren, müssen diese also auch wieder im Namen auftauchen.

Postgres ist auch konsistent: Wenn die Tabelle mittels pg_dump exportiert wird, ist das Ergebnis eine Text-Datei in Unicode-Encoding, in dem - mit Gedit betrachtet - wieder der Name NameSpalten auftaucht, da alle Zeichen exportiert wurden und diese natürlich wieder interpretiert werden:

Screenshot Ergebnis von pg_dump in Gedit 2.36.2

Leider (oder glücklicherweise - kommt ganz auf die Perspektive an) konnte ein tatsächlicher, ernstzunehmender Angriff auf Postgres nicht durchgeführt werden, weil alle Zeichen in einem Statement interpretiert werden und die Bidi-Codes in diesem Kontext keine gültigen Zeichen für Postgres darstellen. Das sind sie nur in Identifiern und mit dieser Einschränkung war es (zumindest mir) nicht möglich, klassische Szenarien wie sie beispielsweise aus SQL-Injection bekannt sind - etwa Tabellen löschen oder Datensätze ändern - umzusetzen.

Artikel, die hierher verlinken

Datenvalidierung UTF8 mit BiDi-Steuerzeichen (TrojanSource 2.0)

15.07.2024

Ich bin heute nochmal inspiriert worden, weiter über die Trojan Source Vulnerability nachzudenken. Meiner Meinung nach bestehen hier noch Probleme - speziell bei Nutzereingaben oder Daten, die über externe Schnittstellen ampfangen werden.

Trojan SQL

09.12.2021

Ich habe bereits über Ideen geschrieben, die TrojanSource-Vulnerability in anderen Kontexten zu untersuchen - ein Vorkommnis in dem Job, mit dem ich mir das Geld für Kuchen verdiene hat mich jetzt angestachelt, diese Untersuchung tatsächlich umfangreich und gründlich durchzuführen. Dieser Beitrag wurde zum CCC End-of-year event 2021 eingereicht und abgelehnt.

Alle Artikel rss Wochenübersicht Monatsübersicht Codeberg Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Multi-User-WebDAV, Docker, GitHub

    17.11.2019

    Nachdem ich mich in letzter Zeit verstärkt mit Docker und dem zugehörigen Ökosystem beschäftige, habe ich begonnen, verschiedenste Dienste in Containern zu testen um zu sehen, ob in manchen Fällen LXC oder KVM nicht doch die bessere Wahl wäre...

    Weiterlesen...

Neueste Artikel

  • Migration der Webseite und aller OpenSource Projekte

    In eigener Sache...

    Weiterlesen...
  • AutoHideToolbar für Java Swing

    Ich habe eine neue Java Swing Komponente erstellt: Es handelt sich um einen Wrapper für von JToolBar abgeleitete Klassen, die die Werkzeugleiste minimieren und sie nur dann einblenden, wenn der Mauszeiger über ihnen schwebt.

    Weiterlesen...
  • Integration von EBMap4D in die sQLshell

    Ich habe bereits in einem früheren Artikel über meine ersten Erfolge berichtet, der sQLshell auf Basis des bestehenden Codes aus dem Projekt EBMap4D eine bessere Integration für Geo-Daten zu spendieren und entsprechende Abfragen, bzw. deren Ergebnisse auf einer Kartenansicht zu visualisieren.

    Weiterlesen...

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muss damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen Codeberg-Repositories findet man hier.