101 lines
3.6 KiB
Markdown
101 lines
3.6 KiB
Markdown
# 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:
|
|
1. Verbinde mit dem Server.
|
|
2. Sende einen langen String bekannter Zeichen (z.B. 100 'A's).
|
|
3. Empfange den hex-kodierten Chiffretext.
|
|
4. Dekodiere das Hex und XOR es mit unserem String von 'A's, um die Flagge zu enthüllen.
|
|
|
|
### Solver-Skript
|
|
|
|
```python
|
|
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}`
|