Deutschlands Bester Hacker - Homebrew (Crypto) - Das Writeup

Disclaimer: Im August 2026 fand die Qualifikation für das Finale von Deutschlands Bester Hacker statt, welches ich auf Platz 1 abschließen konnte. Nur zwei Teilnehmer waren in der Lage, alle Challenges zu lösen. Dieses Writeup wurde mit KI auf Basis meiner Notizen erstellt und kann Fehler enthalten, bei Fragen bitte direkt an mich wenden im DBH-Discord.

Wettbewerb Deutschlands Bester Hacker 2026 — Qualifikation
Kategorie Crypto
Punkte 475
Angriffsklasse ECDSA Nonce ReuseNonce ReuseWiederholte Verwendung eines Einmalwerts, die je nach Verfahren Klartexte oder private Schlüssel preisgibt. → Private-Key-Recovery
Flag DBH{N0NC3_ZW31M4L_1ST_31NM4L_ZU_V13L_XXX}

Die Challenge

Die Konsole NEXUS Portable akzeptiert nur Software, deren Freigabe mit dem aktuellen Herstellerschlüssel signiert wurde. Das Signaturportal veröffentlicht:

  • die bisherigen Releases
  • die zugehörigen Signaturen
  • den exakt signierten Text
  • den aktuellen öffentlichen Schlüssel

Signiert wird mit:

  • Kurve: NIST P-256 / secp256r1
  • Hash: SHA-256
  • Signaturformat: roh r || s, jeweils 32 Byte, Base64

Laut Changelog musste im Oktober 2024 eine Charge auf einer Notfall-Signierstation nachsigniert werden. Das ist der Hinweis.

Aufklärung

Bei zwei Releases unter NX-SIGN-2023 ist der r-Wert identisch:

  • NEXUS Portable System Firmware 3.0.1
  • NEXUS Portable System Firmware 3.1.0-rc2

Die Signaturen:

3.0.1     hm0jo0IOSVU5MsOLVPEIzqQGmw2koOQFGbPSScKAK+kj0YSGgBY9lg1M4G3XTfZTEGN42V9ZyfXKiI7VecUcVw==
3.1.0-rc2 hm0jo0IOSVU5MsOLVPEIzqQGmw2koOQFGbPSScKAK+nEQnN3AEJSLdMxUHtpFFTgSP05hGxQ4RyVxprM7Oh9Dg==

Dasselbe r bei ECDSA bedeutet praktisch, dass derselbe NonceNonceWert, der in einem kryptografischen Kontext nur einmal verwendet werden soll. k wiederverwendet wurde.

Die Schwachstelle

ECDSA verwendet:

s = k^-1 (z + r*d) mod n

mit d = privater Schlüssel, k = einmaliger Nonce, z = Hash der Nachricht als Zahl.

Für zwei verschiedene Nachrichten mit demselben k gilt:

s1 = k^-1 (z1 + r*d) mod n
s2 = k^-1 (z2 + r*d) mod n

Daraus folgt direkt:

k = (z1 - z2) * (s1 - s2)^-1 mod n
d = (s1*k - z1) * r^-1 mod n

Da das Portal die exakten signierter_text-Werte liefert, lassen sich z1 und z2 unmittelbar aus SHA-256(signierter_text) berechnen:

NEXUS Portable System Firmware|3.0.1|ef286bf548761f4733e305a9b1e3715be43f07c30b2f6f10eb5d939dac0cdb9d|2024-05-30T10:15:00Z
NEXUS Portable System Firmware|3.1.0-rc2|2a8d4d6dd56f2277677dde632c7331bc0df9d882739997304b9f1609f5c2028f|2024-10-19T17:03:00Z

Der Angriff

Mit den beiden Signaturen und den beiden signierten Texten ergibt sich der private Schlüssel von NX-SIGN-2023:

d = 0x6f7e9e5d11ca022f848d215ae14132cb9c6794f4125b6e54c718f7154af6ed3a

Der daraus abgeleitete öffentliche Schlüssel passt zum vom Portal veröffentlichten Punkt — die Rekonstruktion stimmt also.

Zuerst wird ein einmaliges Freigabe-Token angefordert:

curl -s '<URL>/api/sign/challenge'

Antwort:

{
  "token": "464a5c48241de0d303fc670b18b06252",
  "vorlage": "<titel>|<version>|<sha256>|<token>"
}

Dann ein eigener Titel:

DBH Homebrew|1.0.0|e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855|464a5c48241de0d303fc670b18b06252

Mit dem rekonstruierten privaten Schlüssel signiert ergibt das:

8HktU63MGjbBD/ktM+GlFaGHpoJIFKNqaRJb7/ILDDy1+YRJvvbWu1Hq3q8JMsPS9WsnjRp1n4evjalVZYiSjg==

Finaler Request:

curl -s -X POST '<URL>/api/sign' \
  -H 'Content-Type: application/json' \
  --data '{"titel":"DBH Homebrew","version":"1.0.0","sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","token":"464a5c48241de0d303fc670b18b06252","signatur":"8HktU63MGjbBD/ktM+GlFaGHpoJIFKNqaRJb7/ILDDy1+YRJvvbWu1Hq3q8JMsPS9WsnjRp1n4evjalVZYiSjg=="}'

Serverantwort:

{
  "freigabecode": "DBH{N0NC3_ZW31M4L_1ST_31NM4L_ZU_V13L_XXX}",
  "meldung": "DBH Homebrew 1.0.0 ist zur Installation freigegeben.",
  "status": "freigegeben"
}

Die Flag

DBH{N0NC3_ZW31M4L_1ST_31NM4L_ZU_V13L_XXX}

Was ich mitnehme

Die Notfall-Signierstation hat denselben ECDSA-Nonce für zwei verschiedene Nachrichten wiederverwendet. Das ist bei ECDSA fatal: aus zwei Signaturen mit identischem r lässt sich der private Schlüssel geschlossen berechnen — kein Brute ForceBrute-Force-AngriffSystematisches Ausprobieren vieler Zugangsdaten oder kryptografischer Schlüssel., reine Algebra.

In der Praxis heißt das: deterministische Nonces nach RFC 6979 verwenden, und ein identisches r in zwei Signaturen ist ein sofort alarmierender Befund. Wer Signaturen öffentlich publiziert, publiziert damit auch das Beweismaterial für diesen Fehler.