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.
Ich hatte bisher große Plattformen und dedizierte Editorkomponenten auf Verwundbarkeit durch TrojanSource-Angriffe untersucht. Ich hatte dabei völlig ganz normale GUI-Komponenten außer Acht gelassen.
Das holte ich nunmehr nach, indem in eine einfache Swing-Oberfläche in einem Java-Programm erstellte mit einem einzeiligen Texteingabefeld und einer mehrzeiligen Texteingabekomponente. Beide waren - auch in der neuesten Java-Version noch gegen solche Angriffe verwundbar. Nachdem ich meine diesbezügliche NEugierde befriedigt hatte überlegte ich, wie man dieses Verhalten eventuell für Angriffe ausnützen könnte.
Man könnte zunächst die Usability einer Anwendung beschneiden: Man stelle sich vor, dass ein Angreifer Daten in der Datenbank der Anwendung manipuliert und dort solche Unicode-Zeichen in die Felder einfügt, wie sie auch für TrojanSource-Angriffe verwendet werden. Wird dies korrekt erledigt, ändert sich an der Anzeige in der Applikation, die darauf nicht vorbereitet ist nichts. Allerdings kann nun nichtmehr erfolgreich gesucht werden, weil die Texte in der Datenbank nun nicht mehr mit etwaigen Suchbegriffen übereinstimmen.
Ein weiteres Szenario ist die Validierung eingegebener (oder über eine externe Schnittstelle empfangener) numerischer Werte:
Ich habe dazu einige Versuche angestellt und dazu nicht nur Java, sondern auch C, C++ und Python daraufhin untersucht, was passiert, wenn ein String in eine Integerzahl umgewandelt werden soll, der Zeichen aus einem TrojanSource-Angriff enthalten:
//...
System.out.println(de.elbosso.util.Utilities.hexdump(tf.getText().getBytes()));
java.text.NumberFormat nf=java.text.NumberFormat.getIntegerInstance();
System.out.println(nf.parse(tf.getText()));
System.out.println(Integer.valueOf(tf.getText()));
//...
Java Programmierer können sich auf Bordmittel verlassen - jeder der hier gezeigten Wege zum Parsen eines Strings in eine Zahl schlägt wegen nicht erlaubter Zeichen im String fehl.
<stdio.h>
<stdlib.h>
<errno.h>
int main() {
printf("300400500\n");
int a=atoi("300400500");
printf("%d\n",a);
a=0;
printf("sscanf: %d\n",sscanf("300400500","%d",&a));
printf("%d\n",a);
char * end;
a=0;
a=strtol ("300400500", &end, 10);
if (*end != '\0' || errno == ERANGE)
printf("error %d\n",a);
else
printf("%d\n",a);
return 0;
}
Mit C war es schon problematischer: nur strtol bietet die Möglichkeit, einen solchen Angriff zu erkennen - dazu muss amn aber die hier skizzierte Fehlererkennung explizit durchführen. Ansonsten verhält sich auch diese Methode exakt wie die anderen: sie liest so lange Zeichen ein und wandelt sie um, bis sie auf ein Zeichen stößt, das laut Grammatik in einer Ganzzahl nicht vorkommt und beendet das Parsen - das Ergebnis wird aus den erfolgreich eingelesenen Zeichen gebildet.
<iostream>
<sstream>
int main() {
std::cout << "300400500\n";
int i = std::stoi("300400500");
std::cout << i << "\n";
i=0;
if(std::istringstream("300400500") >> i)
std::cout << i << "\n";
else
std::cout << "error " << i << "\n";
i==0;
if(std::istringstream("huhu") >> i)
std::cout << i << "\n";
else
std::cout << "error\n";
i=0;
char c;
std::istringstream ss("300400500");
ss >> i;
if (ss.fail() || ss.get(c))
std::cout << i << "\n";
else
std::cout << "error " << i << "\n";
return 0;
}
C++ ist in meinen Tests der schwierigste Kandidat gewesen: Keiner der hier als Bordmittel getesteten Varianten zeigte einen Fehler auf - nicht einmal der letzte Codeabschnitt, in dem der Stream explizit nach dem Auftreten von Fehlern gefragt wird. Meine Empfehlung daher ist die gleiche, die auch das Internet gibt: lieber auch in C++ Programmen auf strtol zurückgreifen!
import string
from ast import literal_eval
print(literal_eval('300400500'))
print(eval('300400500'))
print(int('300400500'))
Python hingegen schlägt sich ungefähr so gut wie Java - egal, welche der hier gezeigten drei Möglichkeiten man anwendet, um einen String in eine Ganzzahl umzuwandeln - jede wirft eine Exception, sobald versucht wird, TrojanSource-Controlcharacters in die Inputstrings zu schmuggeln.
Testdatengeneratoren als Microservices mit Docker
02.11.2019
Ich habe die verschiedenen Testdatengeneratoren mittels Microservices über HTTP zugänglich gemacht, um sie unabhängig von der verwendeten Programmiersprache und/ oder Version (Java 11) verwenden zu können.
Weiterlesen...Android Basteln C und C++ Chaos Datenbanken Docker dWb+ ESP Wifi Garten Geo Git(lab|hub) Go GUI Gui Hardware Java Jupyter Komponenten Links Linux Markdown Markup Music Numerik PKI-X.509-CA Python QBrowser Rants Raspi Revisited Security Software-Test sQLshell TeleGrafana Verschiedenes Video Virtualisierung Windows Upcoming...
Nachdem ich neulich auf einen sehr interessanten Link gestoßen war, habe ich mich dafür interessiert, ob es möglich wäre - und falls ja: wie einfach - GIF-Animationen aus Java heraus zu erzeugen - und zwar mit Bordmitelln und ohne Zuhilfenahme externer Biblioheken
Weiterlesen...Nach der letzten losen Zusammenstellung (für mich) interessanter Links aus den Tiefen des Internet von 2024 folgt hier gleich die nächste:
Weiterlesen...Nachdem es nun bereits seit einiger Zeit ein wenig stiller um meine diversen Generatoren für Testdaten geworden ist, habe ich über den Feiertag in Thüringen einen neuen begonnen.
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, muß 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 GitHub-Repositories findet man hier - meine öffentlichen GitLab-Repositories finden sich dagegen hier.