Binäres Netzwerk Protokoll
-
@-Infected-
Dein Problem ist, dass du glaubst, dich zwingend auf die Längenangaben in den empfangenen Daten verlassen zu müssen. Doch das stimmt gar nicht.
Wenn in der Nachricht steht, es kommt jetzt ein 100 Byte Parameter, es fehlen jedoch 80 Bytes, dann darfst du natürlich nicht blind ein memcpy 100 machen, sondern immer maximal bis zur Gesamtlänge des Empfangsbuffers.
Dann kann nichts crashen, höchstens die Daten sind dann aus Anwendungssicht invalid, aber da musst du eben validations einbauen.
-
Zudem sollte man beim Versenden von binären Datenblöcken darauf achten, dass unterschiedliche Systeme ( 32Bit, 64Bit ) unterschiedliche Binärblöcke generieren, weil einfach Datentypen unterschiedlich groß sind. Ganz am Anfang, unwissend wie ich war und teilweise noch bin (
), bin ich damit ganz bitterböse auf die Nase gefallen
-
-Infected- schrieb:
Meine Frage ist also, wie kann ich verhindern (oder es zumindest schwer machen), dass ein Angreifer meinen Server lahmlegt?
Alle Eingaben (dazu gehört auch ein Datenstrom per TCP), die man sich nicht selbst im Programm erzeugt, muss man prüfen, da sie ggf. manipuliert sind. Wenn Dein Progamm eine unplausible Eingabe erhält (z.B. "Parameterlänge 2Mrd"), dann loggst Du das in deinem Logfile und beendest die Verbindung zur Gegenstelle.
Was eine unplausible Eingabe ist, musst Du selbst wissen, denn Du bist ja Entwickler deines Protokolls. z.B. könnte man halt in die Protokolldefinition reinschreiben, Parameter können maximal 32Byte lang sein. Dann kannst Du auf genau das prüfen. Wenn Dein Protokoll aber halt potentiell mit 2Mrd Bytes langen Parametern klar kommen soll, dann sind natürlich alle Längen < 2Mrd erlaubte Eingaben und Du darfst damit dann auch nicht auf die Nase fallen.
Das Dein memcpy schief geht hat damit allerdings nichts zu tun. Das ist ein simpler Programmierfehler. Wenn im Protokoll gestanden hat es kämen noch x Bytes, Du hast aber gerade nur y < x Bytes, musst Du halt so lange warten bis dir die Gegenstelle ausreichend Bytes gesendet hat bevor Du da irgendwas in der Länge x umherkopierst.
-
Es werden Parameterlängen bis zu der maximalen Integerlänge möglich (das is zuviel, aber 2 Bytes (WORD) ist eventuell zu wenig
Ich hatte einen prinzipiellen Denkfehler drin:
Wenn Daten ankommen, mit denen ich nix anfangen kann, kommen ja aus demselben Datenstrom nicht auchnoch sinnvolle Daten an -> Ich kann die Verbindung trennen, ich mache auch kein memcpy() ohne das genug Daten da sind (ich bin ja nicht blöd :D)
Das Problem war anderer Natur, ich habe alle Daten in eine globale Schlange gestellt -> wenn einmal nicht valide Daten ankommen, muss ich den Server runterfahren, da ich nichtmehr zwischen den Befehlen unterscheiden kannIch verarbeite die Daten nun direkt nach dem Empfangen im Socket-Thread -> Verbindung trennen (und loggen), wenn das gegenüber Müll sendet
Problem gelöst
Danke
-
Aber ob Garbage gesendet wird oder nicht weist du immer noch nicht. Deshalb Integrität Prüfen! Protokoll overhead musst du halt in kauf nehmen.
Ausser du legst keine Wert darauf...
-
Am besten noch jeden Parameter auf Plausibilität prüfen, denn es könnte noch eine fake-message mit eigenem hash ankommen.
-
Er kann auch jeden Müll annehmen und verarbeiten, das ist ihm überlassen...
-
Doch, Befehle (die bei denen es halt nötig ist) benötigen Authentifizierung (also eine Art Cookie), dass heißt es ist einem Angreifer nicht möglich irgendwas zu machen außer Befehle zu senden die keine "Cookies" brauchen (wobei ich da natürlich nochmal die Parameter checke (und wenn er mir hier nen Integer als String andrehen möchte, dann wird disconnected)) oder unauthentifiziert Befehle zu senden, die ich halt auch entsprechend behandle...
Mein eigentliches Problem war, das er mir (als ich noch die globale Schlange benutzt habe) natürlich alles durcheinander bringen kann, mehr Probleme gabs nicht
-
Anstatt da jetzt ewig lange rum zu frickeln solltest du einfach mal bei Media Markt nachfragen!
-
Bevor du in bereits erledigten Forenbeiträgen rumtrollst solltest du dir Freunde suchen