3.6 KiB
Reversible Logic
Reversible Logic ist eine Kryptographie-Challenge, die auf den Eigenschaften der XOR-Operation basiert. Uns wird ein Dienst bereitgestellt, der unsere Eingabe mit einer versteckten Flagge als Schlüssel verschlüsselt.
Informationsbeschaffung
Wir verbinden uns mit dem Challenge-Dienst und werden mit einer Eingabeaufforderung begrüßt:
--- Secure XOR Encryption Service ---
Enter a message to encrypt:
Die Beschreibung besagt: "Dieses Programm implementiert eine einfache XOR-Chiffre unter Verwendung einer versteckten Flagge als Schlüssel."
Testen wir es, indem wir eine einfache Eingabe wie "AAAA" senden:
Enter a message to encrypt: AAAA
Encrypted Result (Hex): 3a272d20
Schwachstellenanalyse
Der Dienst implementiert eine Standard-XOR-Chiffre, wobei:
Chiffretext = Klartext \oplus Schlüssel
Wir kontrollieren den Klartext (unsere Eingabe) und erhalten den Chiffretext (die Hex-Ausgabe). Der Schlüssel ist die versteckte Flagge, die wir wiederherstellen wollen.
Eine fundamentale Eigenschaft der XOR-Operation ist, dass sie ihre eigene Umkehrung ist (reversibel):
A \oplus B = C \implies C \oplus B = A
Daher können wir den Schlüssel wiederherstellen, indem wir den Chiffretext mit unserem bekannten Klartext XORen:
Schlüssel = Chiffretext \oplus Klartext
Um die vollständige Flagge wiederherzustellen, müssen wir nur einen Klartext senden, der mindestens so lang wie die Flagge ist. Da wir die genaue Länge nicht kennen, stellt das Senden eines langen Strings (z.B. 100 Zeichen) sicher, dass wir sie vollständig abdecken.
Lösung
Wir können diesen Prozess mit einem Python-Skript automatisieren:
- Verbinde mit dem Server.
- Sende einen langen String bekannter Zeichen (z.B. 100 'A's).
- Empfange den hex-kodierten Chiffretext.
- Dekodiere das Hex und XOR es mit unserem String von 'A's, um die Flagge zu enthüllen.
Solver-Skript
from pwn import *
# Log-Level setzen, damit wir die "Opening connection" Nachrichten sehen
context.log_level = 'info'
def main():
# 1. Verbinde mit der Challenge-Instanz
# (Passt zur IP/Port aus deiner vorherigen Nachricht)
io = remote('127.0.0.1', 1315)
# 2. Behandle die Server-Prompts
# Wir lesen, bis der Server nach Eingabe fragt
io.recvuntil(b"Enter a message to encrypt: ")
# 3. Sende unseren "Bekannten Klartext"
# Wir senden einen langen String von 'A's (0x41), um sicherzustellen, dass wir die volle Flagge erfassen.
# Wenn die Flagge länger als 100 Zeichen ist, erhöhe einfach diese Zahl.
plaintext = b"A" * 100
io.sendline(plaintext)
# 4. Empfange die Antwort
io.recvuntil(b"Encrypted Result (Hex): ")
# Lies die Hex-String-Zeile und entferne Whitespace/Newlines
hex_output = io.recvline().strip().decode()
log.info(f"Received Hex Ciphertext: {hex_output}")
# 5. Dekodiere das Hex
cipher_bytes = bytes.fromhex(hex_output)
# 6. XOR zur Wiederherstellung des Schlüssels
# pwntools hat eine eingebaute xor() Funktion, die sehr robust ist.
# Logik: Key = Cipher ^ Plaintext
recovered_key = xor(cipher_bytes, plaintext)
# 7. Ausgabe der Flagge
# Wir verwenden 'errors=ignore' nur für den Fall seltsamer Bytes,
# aber für eine Text-Flagge sollte es sauber sein.
log.success(f"Recovered Flag: {recovered_key.decode('utf-8', errors='ignore')}")
io.close()
if __name__ == "__main__":
main()
Ausführung
Das manuelle Ausführen der Logik oder via Skript enthüllt die Flagge.
{flag: xor_logic_is_reversible_123}