Wie würde man diese einfache "Verschlüsslung" entschlüsseln?



  • zeroblack schrieb:

    Jemand meinte zu mir Decompilern.

    Dieser jemand meinte wohl eher Disassemblieren. Dann kriegt man schonmal Maschinencode raus. Dann Debuggen des Maschinencodes und die Stelle finden wo das Passwort überprüft wird. Meist kann man dann auch direkt sehen welche Werte verglichen werden. Dann spielt es gar keine Rolle wie kompliziert deine Berechnung vorher war, wenn man sich direkt das Ergebnis angucken kann.

    zeroblack schrieb:

    Also habe ich es ganz einfach Mathematisch "verschlüsselt". Also das Passwort und die Ausgabe werden beide erst Mathematisch berechnet. Das Passwort wird erst aus einer Wurzel berechnet.

    Wenn du Pech hast, berechnet der Compiler die Wurzel zur Compilezeit und es steht doch wieder das Ergebnis im Klartext in der ausführbaren Datei.

    PS: double als "Passwort" ist auch extrem ungünstig weil Tests auf Gleichheit aufgrund von Rundungsfehlern negativ ausfallen können. Besser int oder gleich Strings.


  • Mod

    Aus dem Disassembly ist das trivial herauszuholen.

    leaq	8(%rsp), %rsi
    	movl	std::cin, %edi
    	call	std::basic_istream<char, std::char_traits<char> >& std::basic_istream<char, std::char_traits<char> >::_M_extract<double>(double&)
    

    In 8(%rsp) , i.e. dem zweiten Quadword in diesem Frame was der zweiten double Deklaration in main entspricht, liegt deine Eingabe. Jetzt wird mit einem zur Compilezeit berechneten Wert verglichen.

    movsd	.LC1(%rip), %xmm0
    	ucomisd	8(%rsp), %xmm0
    	jp	.L2
    	je	.L8
    

    Wobei .LC1 als

    .LC1:
    	.long	0
    	.long	1076101120
    

    gegeben ist.
    Die Konstante, die in Form einer Ganzzahl im Maschinencode verankert ist, ist 1076101120 , oder, binär,

    01000000 00100100 00000000 00000000 00000000 00000000 00000000 00000000
    

    Da wir IEEE 754 annehmen dürfen, ist dies relativ einfach als 10 zu enttarnen. Das erste Bit ist 0 (positives Signbit). Die folgenden 11 geben den charakteristischen Exponenten an; 10000000010 , und wenn wir nun den Bias subtrahieren, der 1111111111 beträgt, bekommen wir 3 für den Exponenten. Schließlich hängen wir eine 1. vor die restlichen 52 Bits, welche die Mantisse darstellen, und erhalten 1.010000.. , welches in Dezimalform 1.25 gleicht, oder 54\frac{5}{4}. Offensichtlich ergibt letzteres mal 232^3 10.


  • Mod

    Ihr denkt alle viel zu ehrlch. Der Hacker spielt nicht nach den Regeln. Das Passwort brauch er gar nicht zu entschlüsseln. Stattdessen ändert er einfach die Zeile 17 (also deren Äquivalent im Maschinencode) zu

    if (true)
    

    und lacht über den Programmierer, der dachte, dass der Hacker versuchen würde, das Passwort zu entschlüsseln.


  • Mod

    SeppJ schrieb:

    Ihr denkt alle viel zu ehrlch. Der Hacker spielt nicht nach den Regeln. Das Passwort brauch er gar nicht zu entschlüsseln. Stattdessen ändert er einfach die Zeile 17 (also deren Äquivalent im Maschinencode) zu

    if (true)
    

    und lacht über den Programmierer, der dachte, dass der Hacker versuchen würde, das Passwort zu entschlüsseln.

    Ach, Quatsch. Natürlich hat der Programmierer eine SHA-Checksumme eingebaut mit der er den Maschinencode vorerst überprüft. Der Hacker müsste also eine zweite finden, welche den Maschinencode inklusive der Checksumme korrekt beschreibt.



  • Arcoth schrieb:

    Aus dem Disassembly ist das trivial herauszuholen.

    leaq	8(%rsp), %rsi
    	movl	std::cin, %edi
    	call	std::basic_istream<char, std::char_traits<char> >& std::basic_istream<char, std::char_traits<char> >::_M_extract<double>(double&)
    

    In 8(%rsp) , i.e. dem zweiten Quadword in diesem Frame was der zweiten double Deklaration in main entspricht, liegt deine Eingabe. Jetzt wird mit einem zur Compilezeit berechneten Wert verglichen.

    movsd	.LC1(%rip), %xmm0
    	ucomisd	8(%rsp), %xmm0
    	jp	.L2
    	je	.L8
    

    Wobei .LC1 als

    .LC1:
    	.long	0
    	.long	1076101120
    

    gegeben ist.
    Die Konstante, die in Form einer Ganzzahl im Maschinencode verankert ist, ist 1076101120 , oder, binär,

    01000000 00100100 00000000 00000000 00000000 00000000 00000000 00000000
    

    Da wir IEEE 754 annehmen dürfen, ist dies relativ einfach als 10 zu enttarnen. Das erste Bit ist 0 (positives Signbit). Die folgenden 11 geben den charakteristischen Exponenten an; 10000000010 , und wenn wir nun den Bias subtrahieren, der 1111111111 beträgt, bekommen wir 3 für den Exponenten. Schließlich hängen wir eine 1. vor die restlichen 52 Bits, welche die Mantisse darstellen, und erhalten 1.010000.. , welches in Dezimalform 1.25 gleicht, oder 54\frac{5}{4}. Offensichtlich ergibt letzteres mal 232^3 10.

    Also erst einmal vielen lieben Dank für die Antworten.
    Ich glaube das ist eindeutig zu hoch für mich. Bin da denke ich zu dumm für.

    Ich habe mittels objdump -d mir aus der Unix-Datei den Assembler Code ausgeben lassen. (Das ist doch richtig oder?)
    Um deine Anwort nun zu verstehen müsste man Fachwissen für was genau haben? Man müsste Assembler code lesen können? Oder was genau?

    Ich merke das mir als Laie jede Grundlage fehlt um das zuverstehen.
    Womit müsste ich mich beschäftigen um das verstehen zu können?



  • Du bist nicht zu dumm dafür, du hast dich nur nie mit Assembler beschäftigt.
    Ein paar Grundkenntnisse können nicht schaden, aber wirklich brauchen tust du die auch nur wenn du Treiber oder Betriebsysteme programmierst.

    Dein Programm würde ich so gestalten, dass in dem Programm nur ein Algorithmus ist, der aus einem verschüsselten String mit Hilfe des passoworts einen entschüsselten macht und ihn dann ausgibt.

    Kannst es ja Cäsar mäßig machen, mit ein paar kleinen Schwierigkeiten oder so.
    Wenn du interessiert an Zahlentheorie bist, kannst du ja mal gucken, was RSA so kann.
    Der kleine Fermat reicht glaube auch schon aus, für was halbwegs sicheres.



  • Bengo schrieb:

    Du bist nicht zu dumm dafür, du hast dich nur nie mit Assembler beschäftigt.
    Ein paar Grundkenntnisse können nicht schaden, aber wirklich brauchen tust du die auch nur wenn du Treiber oder Betriebsysteme programmierst.

    Dein Programm würde ich so gestalten, dass in dem Programm nur ein Algorithmus ist, der aus einem verschüsselten String mit Hilfe des passoworts einen entschüsselten macht und ihn dann ausgibt.

    Kannst es ja Cäsar mäßig machen, mit ein paar kleinen Schwierigkeiten oder so.
    Wenn du interessiert an Zahlentheorie bist, kannst du ja mal gucken, was RSA so kann.
    Der kleine Fermat reicht glaube auch schon aus, für was halbwegs sicheres.

    Danke dir. Das werde ich mir mal ansehen.



  • Du hast die Frage etwas falsch gestellt. Verschluesselungen (und Passwort-Abfragen) basieren darauf, dass der Angreifer keinen Zugriff auf die ausfuehrende Maschine hat. Du kannst nicht etwas vor dem System/Anwender selbst verstecken, auch wenn du den tollsten Algorithmus der Welt benutzt, kann immer noch jeder sich den Key einfach im Debugger angucken. (Dein Programm ist letztlich nur eine Reihe an Anweisungen an den Computer. Ein Debugger macht diese Reihe an Anweisungen anschaulig.)

    Die richtige Frage muesste lauten, wenn ein Anwender nur Zugriff auf eine Konsole haette in die er etwas eingeben kann, wie kann er das Programm dazu bringen p auszugeben ohne das Passwort zu kennen? Die Antwort ist gar nicht. Aber das liegt nicht daran dass diese "Verschluesselung" so toll ist, sondern daran dass das hier einfach nur eine Passwortabfrage ist. Um die Antwort "gar nicht" zu bekommen, waere if (input == "sicheres Password") bereits voellig ausreichend.



  • Bengo schrieb:

    Ein paar Grundkenntnisse können nicht schaden, aber wirklich brauchen tust du die auch nur wenn du Treiber oder Betriebsysteme programmierst.

    Soweit muss man nicht gehen, grundlegende Kenntnisse sind in der Praxis tatsächlich öfter relevant. Ich schau mir bei Crash Dumps unserer Software öfter mal das Disassembly an.


  • Mod

    AES Implementierungen werden z.T. auch in Assembler geschrieben, um cache-timing Attacken zu vermeiden.


Anmelden zum Antworten