Sockets, Denkfehler und Serverabsturz



  • Wie kann es sein, dass der Angreifer in der gleichen Verbindung hängt wie der richtige Client? Es gibt sowas wie TCP-Sequenznummern, das geht eigentlich nicht. Oder wie funktioniert dein Protokoll, dass so etwas möglich ist?

    Ansonsten denke ich, es führt zu nichts, herausfinden zu wollen, was ein "echter" Header ist und was nicht. Geh einfach davon aus, dass alles echt ist und sorg dafür, dass dein Server dabei nicht abstürzt.



  • Hoffe das ist etwas verständlicher

    Nein. Beispiel: Bedeutet HHH das 3 Header gesendet werden?



  • Okay langsam glaube ich, dass die Ursache, die ich vermute, falsch ist 😕
    Seh ich das richtig: Egal wie die Verbindungen geknüpft sind, die empfangenen Daten werden in einen Speicher, quasi einer virtuellen Datei, gespeichert, die ich dann mit Read auslese. Dann habe ich gedacht die Ursache ist, dass falsche Bytes reinrutschen, und beispielsweise die Zeichen an Stelle 8 auf Stelle 12 rutschen. Aber das scheint ja nicht zu sein. Ich muss mal mit den Speichern bisschen rumexperimentieren^^

    Fakt ist: Sobald ich Daten über PuTTY einschleuse, stürtzt der Server ab, und das ist bei einem Server nun wirklich nicht witzig 😛

    Vll kann mir jemand von den Code-Schnipseln sagen, woran es liegen könnte.

    Es wird im moment nur eingeloggt, wobei der Databody das md5-verschlüsselte Passwort beinhaltet.

    Header:

    struct Header
    {
        char username[32];
        unsigned short id;
        unsigned int size;
        unsigned short reserved;
    };
    

    Senden des Logins(Client):

    Header header;
        strcpy(header.username, iUsername->GetValue().mb_str());
        header.id = S_LoginRequest;
        header.size = password.length()+1;
        header.reserved = 0x0000;
    
        stringstream stream;
        stream.write(reinterpret_cast<char*>(&header), sizeof(Header));
        stream.write(datablock, header.size);
        char checkbyte = CHECKBYTE;
        stream.write(&checkbyte, 1);
    
        socket->Write(stream.str().c_str(), sizeof(Header) + header.size + 1);
    

    Empfangen der Daten(Server):

    Header header;
        socket->Read(reinterpret_cast<char*>(&header), sizeof(Header));
        char *data = new char[header.size+1];
        char checkbyte;
        socket->Read(data, header.size);
        socket->Read(&checkbyte, 1);
    


  • Warum schreibst du nicht mittels socket->write genauso wie du mit socket->read liesst? Warum der Umweg ueber stringstream? Warum verwendest du strcpy?



  • Ich hab mir gedacht, dass dadurch die Daten in einem Rutsch durch die Leitung geht und dadurch die Wahrscheinlichkeit auf Fehler sinkt. Liege ich damit Falsch? Wenn ja, werde ich das abändern^^

    header.username ist ja ein C-String. iUsername ist eine Instanz vom Typ wxTextCtrl, das Eingabefelt. Mit ->GetValue() bekomme ich ein wxString zurück, und mit ->mb_str() den C-String. Mit strcpy kopiere ich den einen String in den anderen. Aber das funktioniert doch?



  • Fehler? Beim Übertragen? Schau dir doch mal die Wikipedia-Seite vom TCP Protokoll an (davon ausgehend, dass du TCP benutzt, falls nicht: Wieso sollten dadurch weniger Fehler auftreten?).



  • Alles mit 1x send abschicken ist schon gut (zumindest so lange "alles" nicht extrem gross wird).
    send-send-recv ist so ziemlich die schlechteste Abfolge die man haben kann.

    Dabei geht's aber um Performance und nicht um Sicherheit.



  • @-Infected-
    Ich benutze TCP, UDP währ für einen Instant Messenger wohl die falsche Wahl. Mit Write werden die Daten doch direkt ausgesendet oder? Wenn ich jetzt den Header und den Datenteil mit zwei Write-Methoden aussende, so werden die ja getrennt voneinander gesendet oder? Ich weiß, dass TCP dafür sorgt, dass die Pakete in der richtigen Reihenfolge und auch Vollständig ankommen, aber wenn 2 Clients gleichzeitig senden hatte ich die Befürchtung, dass zuerst der Header von Person A, dann der Header von Person B, dann der Datenteil von Person A und dann erst der Datenteil von Person B kommt, und dachte dies so vorgebeugt zu haben. Oder wird das erst in einen Buffer geschrieben und dann direkt ausgesendet?

    @hustbaer
    Ich benutz zum Login-Test den Benutzername Test und das Passwort hallo. Das Paket ist dann 77 Byte groß. Sobald es zum Dateitransfer geht (wovon ich noch weit weg bin) werde ich warscheinlich den reserved-Teil benutzen um das Paket als Write oder Append zu beschreiben und dann nur Bruchteile senden.

    Ich glaube aber wir kommen vom Problem ab. Ich hab zwar im Code herumgespielt aber nichts dabei erreicht. Wenn ich in Putty eindach irgendwelche Daten sende, hängt sich der Server auf, samt grafischer Oberfläche...
    -EDIT-
    Nochmal kurz: Die ganze Anwendung funktioniert. Nur wenn sich ein Skriptkiddy denkt, er müsse mal den Server zur Leistungsverweigerung anstiften, braucht er nichts weiter, als Putty oder ein vergleichbares Programm, das Daten an den gewählten Port senden, zu nutzen und der Server hängt.

    ---EDIT---
    PROBLEM GELÖßT!
    Habe das Problem gelöst. Es funktioniert jetzt alles. Der Thread kann gelschlossen werden.

    Wen es interessiert: ich habe dem Server-Socket die Eigenschaft wxSOCKET_NOWAIT beigefügt. Danke euch allen. 😃



  • OK.
    Warum guckst du nicht nach wo der Server hängt statt rumzuraten bzw. uns darum zu bitten für dich zu raten?

    Um die Antwort auf die nächste Frage vorwegzunehmen: Du startest das Programm im Debugger, machst dass es hängenbleibt und drückst dann auf "Pause".

    ps: ich behaupte mal dass wir die wesentlichen Teile deines Servers her nicht sehen. Nämlich die die dafür sorgen dass mehrere Verbindungen gleichzeitig "bedient" werden können.



  • MatStorm schrieb:

    Habe das Problem gelöst. Es funktioniert jetzt alles. Der Thread kann gelschlossen werden.

    Was passiert denn jetzt wenn ich dir einen Header schicke, der als Größe riesige oder von deinem Programm als negativ interpretierte Zahlen enthält? Allokierst du dann gigabyteweise Speicher?

    Ganz abgesehen davon, dass dein direktes Einlesen von Netzwerkdaten in eine C-Struktur ziemlich verrückt ist. Das wird doch niemals über verschiedene Systeme (mit anderen Compilern, Alignmentanforderungen, usw/) hinweg funktionieren.



  • Vergiss den negativ-Halbsatz.


Anmelden zum Antworten