DVB TS Vollverschlüsselung geknackt

Transcription

DVB TS Vollverschlüsselung geknackt
DVB TS Vollverschlüsselung geknackt
DVB TS Vollverschlüsselung
geknackt
Erstmals wurde die DVB Transport Stream (TS)
Vollverschlüsselung, bei der nicht nur Teile wie Video und
Audio, sondern alle PIDs (PAT, NIT, PMT, …) verschlüsselt
werden, geknackt. Ein vollverschlüsselter TS wird über
eine einzelne Data-PID über einen normalen TS getunnelt.
16.12.2011 (Version 1.00) aktuelle Version auf http://colibri.net63.net bzw. http://colibri-dvb.info
Colibri <[email protected]>
Einige Screenshots der geknackten Programme
DVB TS Vollverschlüsselung geknackt
Inhalt
Einleitung ................................................................................................................................................. 2
Getunnelter TS ........................................................................................................................................ 3
Normaler ungetunnelter TS................................................................................................................... 19
Performance .......................................................................................................................................... 20
Empfehlungen ....................................................................................................................................... 20
Literatur ................................................................................................................................................. 20
DVB TS Vollverschlüsselung geknackt
Einleitung
Programme die mit einem festen Schlüssel dem Control Word (CW) verschlüsselt über Satelliten
übertragen werden, wurden ja bereits vor geraumer Zeit geknackt. Man macht sich hier zunutze,
dass der Schlüsselraum mit nur 248 verschiedenen Möglichkeiten zu klein ist, um mit der heutigen
gigantischen Rechenleistung von Grafikkarten mithalten zu können. Der Anfang (MPEG-Header) von
einem entschlüsselten Video und Audio Paket ist immer bekannt (Bytefolge „00 00 01“). So kann
einfach mit Brute-Force jeder mögliche Schlüssel ausprobiert werden. Der Anfang von solch einem
Paket, wird mit dem Payload Unit Start Indicator (PUSI)-Bit, im immer unverschlüsselten TS-Header,
signalisiert. Somit kann man, je nach Grafikkarte, das CW innerhalb von ein paar Wochen knacken.
Deshalb nutzen auch die meisten Anbieter nicht Constant CW oder Basic Interoperable Scrambling
System (BISS), sondern CA-Systeme wie z.B. Nagravision, Cryptoworks, CONAX oder Viaccess bei
denen alle paar Sekunden ein neues CW zum Verschlüsseln verwendet wird.
Im Gegensatz zur reinen Verschlüsselung von Video und Audio kommt seit Jahren auch die TS
Vollverschlüsselung zum Einsatz. Hier wird ein kompletter TS mit seinen vielen Programmen und den
ganzen Verwaltungsinfos PAT, NIT, SDT, EIT, PMT zu einer einzigen Data-PID gemultiplext. Diese
Data-PID wird dann mit BISS verschlüsselt.
Im Internet habe ich dazu folgendes gefunden:
Für Leute in Spanien, die DVB-T nicht empfangen können, gibt es einen Sat Receiver Televes 5110 um
diese Programme direkt über den Hispasat Satelliten (30°W) empfangen zu können. Einen solchen
Receiver kann man nicht einfach kaufen, sondern ein zugelassender Händler, der für Abertis Telecom
arbeitet, muss zuerst sicherstellen, dass wirklich kein DVB-T Empfang möglich ist. Erst dann werden
die Schüssel und der Receiver durch ihn eingerichtet.
Das Problem der Hacker war, dass sie nicht mehr wussten wo innerhalb der Data-PID, die den
gesamten TS enthält, die Video oder Audio Pakete anfangen. Ohne diesen Anhaltspunkt für den
Known-Plaintext scheitert auch der Brute-Force.
Hier wird erläutert wie es mir trotzdem gelungen ist das System zu knacken. Ein Highlight ist auch die
erstmals zum Einsatz gekommene Common-Scrambling-Algorithmus (CSA)-Rainbow Table. Nie zuvor
Seite 2
DVB TS Vollverschlüsselung geknackt
wurden CWs mit einer CSA-Rainbow Table geknackt. Zwar dauert das einmalige Erstellen der Table
auch sehr lange, aber damit habe ich dann mehrere verschiedene CWs in Minuten geknackt.
Im nächsten Kapitel wird nur auf die Spanischen DVB-T Programme, die über den Hispasat Satelliten
(30°W) übertragen werden, eingegangen. Ich bin an Feedback interessiert ob es auch noch andere
Systeme gibt, die einen ganzen TS über eine einzelne Data-PID getunnelt übertragen.
Die gefundenen CWs sind hier nicht enthalten.
Getunnelter TS
Zur Analyse habe ich mir so eine verschlüsselte PID, über die ein ganzer TS getunnelt wird, mal
aufgezeichnet. Die relevanten Frequenzen und PIDs habe ich weiter unten im Dokument aufgeführt.
Ich habe dann das Binary-File in HEX konvertiert und alle 188 Bytes, das ist die genormte Paketlänge,
einen Zeilenumbuch einfügen lassen. Im Spaltenmodus habe ich dann die den TS Paket Header (4
Bytes) entfernt. Anschliessend habe ich die Zeilen sortiert, um besser Muster erkennen zu können.
Byte 0
Bit
7..0
Sync
byte
47h
1
7
Transport
error
indicator
1
6
Payload
unit
start
indicator
1
5
Transport
priority
1
4..0
PID
2
7..0
3
7..6
Transport
scrambling
control
3
5..4
Adaptation
field
control
3
3..0
Continuity
counter
Tabelle 1:TS Paket Header
Das Ergebnis war überraschend. Zwischen den meisten Zeilen, die wie erwartet nur ein einziges Mal
vorkamen, waren doch tatsächlich immer wieder Blöcke mit identischen Zeilen zu sehen.
Doch wie war das möglich? MPEG ist ein sehr effizientes Format und selbst wenn die da ein Standbild
übertragen, sind ähnlich wie in einem komprimierten File, keine sich wiederholenden Daten zu
erwarten.
Zwar gibt es neben Audio und Video auch noch andere Pakettypen wie z.B. PAT, CAT, NIT, SDT oder
PMT die mehr oder weniger statisch sind. Doch diese haben im Verhältnis zu den Video Paketen
einen viel zu geringen Anteil im TS und können die vielen Blöcke mit gleichem Inhalt eigentlich nicht
verursachen.
Also ging ich einen Schritt zurück und sah mir nicht nur eine verschlüsselte PID vom TS an, sondern
die Statistik vom gesamten TS.
Da waren PAT, CAT, NIT, TDT, EMMs, PMTs, einige verschlüsselte PIDs und PIDs mit der ID 0x1FFF.
Die PIDs mit der ID 0x1FFF sind Füllpakete die übertragen werden um von einer variablen Bitrate, die
z.B. durch die MPEG Video Pakete verursacht wird, auf die fixe Bitrate die ein Transponder hat zu
kommen.
In der Statistik war auch die Anzahl der Pakete pro PID zu sehen. Das war sehr aufschlussreich, denn
die Counter waren für alle verschlüsselten PIDs identisch. Das bedeutet die verschüsselten PIDs
hatten bereits eine fixe Bitrate und sie mussten somit auch Füllpakete enthalten. Das heisst die
vielen identischen Zeilen im Textfile waren verschlüsselte Füllpakete und das war entscheident für
den Hack. Denn der Inhalt der Füllpakete ist in der Regel statisch, manchmal eine aufsteigende
Seite 3
DVB TS Vollverschlüsselung geknackt
Bytefolge aber meist einfach lauter Nullbytes. Bei bekannten Plaintext des Füllpakets ist es möglich
einmalig eine Rainbow Table für diesen Plaintext zu erzeugen. Anschliessend kann man innerhalb von
Minuten an Hand des verschlüsselten Füllblocks, der an den vielen identischen verschlüsselten
Paketen erkennbar ist, sich das CW mit der Rainbow Table berechnen lassen.
Aber warum gibt es nicht nur einen einzigen Zeileninhalt (das verschlüsselte Füllpaket) der öfters
vorkommt, sondern 47 Zeileninhalte die mehrmals vorhanden sind?
Das hängt mit dem Multiplexen (Tunneln) eines TS über eine einzige PID zusammen. Ein TS Paket, mit
seinen 188 Bytes, besteht immer aus 4 Header Bytes + 184 Bytes Payload.
Als Payload der verschlüsselten PID stehen aber nur 184 Bytes zur Verfügung um den TS
aufzunehmen, aber nicht die nötigen 188 Bytes. Die letzten 4 übrigen Bytes des ersten Pakets
wandern an den Anfang es zweiten Pakets und die dann übrigen 8 Bytes des zweiten Pakets kommen
an den Anfang des dritten Pakets.
OuterPkt1 Header
InnerPkt1 Header 4 Byte
OuterPkt2 Header
InnerPkt1 Payload 4 Byte
InnerPkt2 Header 4 Byte
OuterPkt3 Header
InnerPkt2 Payload 8 Byte
InnerPkt3 Header 4 Byte
OuterPkt4 Header
InnerPkt3 Payload 12
Byte
InnerPkt4 Header 4 Byte
OuterPkt44 Header
OuterPkt45 Header
OuterPkt46 Header
OuterPkt47 Header
…
InnerPkt43 Payload 172
InnerPkt44 Header 4
Byte
Byte
InnerPkt44 Payload 176
InnerPkt45 Header 4
Byte
Byte
InnerPkt45 Payload 180
InnerPkt46 Header 4 Byte
Byte
InnerPkt46 Payload 184 Byte
InnerPkt1
Payload 180 Byte
InnerPkt2
Payload 176 Byte
InnerPkt3
Payload 172 Byte
InnerPkt4
Payload 168 Byte
InnerPkt44
Payload 8 Byte
InnerPkt45
Payload 4 Byte
Um 46 Paketen zu tunneln benötigt man also 47 Pakete.
Entschlüsselt sehen die 47 verschiedenen Füllpakete wie folgt aus:
47
00
…
00
00
00
1F FF 10 00 00 00 00 <168 weitere Bytes> 00 00 00 00 00 00 00 00
00 00 00 47 1F FF 10 <168 weitere Bytes> 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 <168 weitere Bytes> 47 1F FF 10 00 00 00 00
00 00 00 00 00 00 00 <168 weitere Bytes> 00 00 00 00 47 1F FF 10
00 00 00 00 00 00 00 <168 weitere Bytes> 00 00 00 00 00 00 00 00
Basierend auf welchen bekannten Plaintext man die Rainbow Table aufbaut kann man sich
aussuchen. Ich habe für meine Experimente den letzen mit 184 Nullbytes genommen. Das hat den
Vorteil, dass man von Headeränderungen unabhängig ist. Header für die Füllpakete gibt’s nämlich in
zwei Varianten einmal statisch 47 1F FF 10 und einmal mit hochzählenden continuity counter 47 1F
FF 10, 47 1F FF 11, 47 1F FF 12, …, 47 1F FF 1F. Beim hochzählenden continuity counter ergeben sich
Seite 4
DVB TS Vollverschlüsselung geknackt
dann mehr als die 47 Varianten, jedoch kommt dann eine Variante sehr viel häufiger vor. Das ist dann
Die mit den verschlüsselten 184 Nullbytes.
Doch welches, der etwa gleichhäufigen vorkommenden verschlüsselten Pakete, nimmt man bei
einem feststehen continuity counter um mit der Rainbow Table das CW zu berechnen?
Man könnte es natürlich mit allen 47 verschiedenen Paketen probieren, was aber die Zeit zum
Berechnen des CWs um diesen Faktor verlängert.
Zur Lösung dieses Problems müssen wir uns mit dem Adaptation Field (AF) befassen.
Im TS Header gibt es ein zwei Bit langes „Adaptation field control“ das angibt ob vor der eigentlichen
Payload noch ein AF vorhanden ist. Die Bits haben folgende Bedeutung:
00
01
10
11
Reserviert
Kein AF, nur Payload
Nur AF, keine Payload
AF und Payload vorhanden
Sehen wir uns mal ein Beispielpaket mit AF und Payload an:
47 08 37 F2
13 12 5F 2D 60 2E 81 00 0B B5 80 96 B0 F8 52 00 00 00 00 00
AF 61 50 13 <156 weitere Bytes> 10 05 32 06
Die erste Zeile ist der TS Header. Im Hi-Nibble (F) des letzen Byte sind alle Bits gesetzt (1111). Die
ersten beiden Bits gehören zum Transport scrambling control Feld und 11 bedeutet dass die Payload
mit dem Odd-CW verschlüsselt ist (10 wäre Even-CW, 00 wäre unverschlüsselt und 01 ist reserviert).
Die letzten zwei 11 Bits bedeuten das AF und Payload vorhanden sind.
In der zweiten Zeile ist das AF zu sehen. Das erste Byte (13h) gibt die Länge des restlichen AF Feldes
an. Insgesamt (1 Längenbyte + 13h Folgende) ist es 14h = 20 Bytes lang.
In der dritten Zeile ist die verschlüsselte Payload abgebildet. Zieht man von den 184 zur Verfügung
stehenden Bytes die die Länge des AF mit seinen 20 Bytes ab, dann bleiben 164 Bytes für die Payload
übrig.
Ein AF wird immer unverschlüsselt übertragen. Es kann z.B. Zeitstempel (PCR) und Provider
spezifische Daten enthalten. Der Inhalt ist für den Hack nicht relevant. Aber dass es ab und zu
vorhanden ist und bei diesem Provider immer eine Länge von 20 Bytes hat ist entscheidend. Es
bewirkt somit, dass die verschlüsselte Payload nicht mehr ein Vielfaches von 8 ist.
Ohne AF hat die Payload immer 184 Bytes bestehend aus 23 Blöcken zu je 8 Bytes.
Mit 20 Byte AF hat die Payload immer 164 Bytes bestehend aus 20 Blöcken zu je 8 Bytes und einen
Rest von 4 Bytes.
Doch warum hilft es uns, wenn die Payload Länge nicht ein Vielfaches von 8 ist, bei unserem Hack?
Seite 5
DVB TS Vollverschlüsselung geknackt
Dazu müssen wir und genauer ansehen wie die Payload mit dem Common-Scrambling-Algorithmus
(CSA) verschlüsselt wird.
Für die Verschlüsselung wird der Plaintext von vorne nach hinten in 8 Blöcke aufgeteilt und der Rest
(Plain Residue) erst mal beiseitegelassen.
Der letzte 8 Byte Block wird mit dem IV, der beim DVB-CSA immer Null ist, XOR verknüpft und dann
mit dem Block cipher mit dem CW verschlüsselt. Das Ergebnis ist ein Intermediate Block (IB). Er wird
mit dem vorletzen Plaintext XOR verknüpft und dann wieder mit dem Block cipher mit dem CW
verschlüsselt. Das Ergebnis ist dann der vorletzte Intermediate Block. Hat man dann alle IBs
berechnet, dann wird der Stream cipher mit dem CW und mit dem Inhalt des ersten IBs initialisiert.
Der erste IB ist gleichzeitig auch der erste verschlüsselte Block. Die restlichen IBs werden mit dem
Output des Stream ciphers XOR verknüpft und ergeben die restlichen verschlüsselten jeweils 8 Byte
langen Blöcke. Jetzt kommt der erst mal beiseitegelassener Plain Residue zum Einsatz. Er wird mit
dem Output des Stream cipher XOR verknüpft und ergibt den verschlüsselten Rest.
Header
CB0
Stream
cipher
init
CW
CB1
SB1
IB0
CB2
SB2
IB1
CB3
…
SB3
IB2
CBn-1
SBn-1
IB3
…
CR
SB0
IBn-1
IV
Block
cipher
encr.
Block
cipher
encr.
Block
cipher
encr.
Block
cipher
encr.
Block
cipher
encr.
CW
CW
CW
CW
CW
PB0
CB: Cipher Block
111101
IB: Intermediate Block
PB: Plain Block
PB1
PB2
…
SB: Stream Cipher Block
CW: Control Word (Key)
PBn-2
PBn-1
PR
CR: Crypt Residue
PR: Plain Residue
IV: Initialization Vector
Abbildung 1: CSA Verschlüsselung
Seite 6
DVB TS Vollverschlüsselung geknackt
Bei der Entschlüsselung funktioniert es dann umgekehrt, wie aus folgendem Bild zu entnehmen ist:
Header
CB0
Stream
cipher
init
CW
CB1
SB1
IB0
CB2
SB2
IB1
CB3
…
SB3
IB2
CBn-1
SBn-1
IB3
…
CR
SB0
IBn-1
IV
Block
cipher
decr.
Block
cipher
decr.
Block
cipher
decr.
Block
cipher
decr.
Block
cipher
decr.
CW
CW
CW
CW
CW
PB0
CB: Cipher Block
111101
IB: Intermediate Block
PB: Plain Block
PB1
PB2
…
PBn-2
SB: Stream Cipher Block
CW: Control Word (Key)
PBn-1
PR
CR: Crypt Residue
PR: Plain Residue
IV: Initialization Vector
Abbildung 2: CSA Entschlüsselung
Das Besondere bei der Verschlüsselung von unseren letzten 4 Bytes der Payload ist also, dass sie gar
nicht von dem Block cipher, sondern nur von dem Stream cipher verschlüsselt wird.
Aber warum hilft uns das, die Eine der 47 Varianten zu ermitteln, die nur aus verschlüsselten Nullen
besteht? Das CW ist uns ja noch nicht bekannt und wir können doch somit eigentlich nicht wissen wie
die 4, nur mit dem Stream cipher verschlüsselten Bytes, entschlüsselt aussehen.
Wenn wir allerdings wüssten, dass die entschlüsselten Bytes den Wert 47 1F FF 10 haben, dann wäre
unser Problem gelöst, da dieser Header mit der PID 1FFF das Füllpaket mit seinen 184 Nullbytes
einleitet. Wir könnten also mit der Payload des folgenden Pakets und der Rainbow Table das CW
berechnen.
Verschlüsselt man zwei Pakete mit dem CSA, bei dem innerhalb der ersten 180 Bytes nur ein einziges
Bit unterschiedlich ist, dann unterscheiden sich die verschlüsselten Pakete total. Selbst die letzten 4
Bytes wären total unterschiedlich, weil der erste Intermediate Block, der zum Initialisieren des
Stream ciphers verwendet wird, anders wäre und somit auch der Keystream der die letzten 4
verschlüsselten Bytes.
Anders ist es allerdings, wenn eine Änderung nicht in den ersten 180 Bytes, sondern nur in den letzen
4 Bytes stattfindet. Dann sind die ersten 180 verschlüsselten Bytes identisch und nur die restlichen 4
Bytes sind unterschiedlich. Unterscheidet sich der Plaintext der letzten 4 Bytes nur in einem einzigen
Bit, dann unterscheiden sich auch die beiden verschlüsselten 4 Bytes nur an genau dieser Bitposition
und der Rest ist identisch.
Sehen wir uns mal die letzten Beiden der 47 Varianten (ohne AF) von oben an:
Seite 7
DVB TS Vollverschlüsselung geknackt
00 00 00 00 00 00 00 00 <168 weitere Bytes> 00 00 00 00 47 1F FF 10
00 00 00 00 00 00 00 00 <168 weitere Bytes> 00 00 00 00 00 00 00 00
Auch in den Paketen mit AF wird es folgende um 20 Byte kürzere Payload geben.
00 00 00 00 00 00 00 00 <148 weitere Bytes> 00 00 00 00 47 1F FF 10
00 00 00 00 00 00 00 00 <148 weitere Bytes> 00 00 00 00 00 00 00 00
Auch verschlüsselt sind diese beiden Payloads zu erkennen. Dazu filtert man aus dem TS nur die
Pakete die ein AF haben, schreibt dann nur die Payload jeweils ein eine Zeile und sortiert das Textfile
anschliessend. Jetzt wird man verschlüsselte Blöcke finden, die zwar innerhalb der ersten 160 Bytes
identisch sind, sich aber innerhalb der letzen 4 Bytes unterscheiden.
Da die ersten 160 Bytes identisch sind, ist auch der Keystream des Stream ciphers identisch.
Beim Stream cipher gilt:
Plain XOR Key = Crypt
Crypt XOR Key = Plain
Plain1 XOR Plain2 XOR Key1 XOR Key2 = Crypt1 XOR Crypt2
Da Key1 und Key2 identisch sind, kann man sie wegkürzen:
Plain1 XOR Plain2 = Crypt1 XOR Crypt2
Jetzt setzt man die Werte ein:
47 1F FF 10 XOR 00 00 00 00 = Crypt1 XOR Crypt2
47 1F FF 10 = Crypt1 XOR Crypt2
Folgender Mitschnitt der zeigt wie vier Payloads enden:
128
8
2
3
mal:
mal:
mal:
mal:
…
…
…
…
66
66
66
66
8B
8B
8B
8B
84
84
84
84
01
01
01
01
ED
ED
ED
ED
A4
A4
A4
A4
49
49
49
49
C2
C2
C2
C2
1A
5D
5D
5D
51
4E
54
54
7F
80
A2
A2
94
84
84
8B
(=
(=
(=
(=
00
47
47
47
00
1F
05
05
00
FF
DD
DD
00)
10)
10)
1F)
Bis auf die letzten 4 Bytes ist der vordere Payloadteil identisch.
1A 51 7F 94 (Crypt1) XOR 5D 4E 80 84 (Crypt2) = 47 1F FF 10 (Plain1
XOR Plain2)
Also entweder entspricht 1A 51 7F 94 dem Plaintext 00 00 00 00 und 5D 4E 80 84 entspricht 47 1F FF
10 oder 1A 51 7F 94 entspricht dem Plaintext 47 1F FF 10 und 5D 4E 80 84 entspricht dem Plaintext
00 00 00 00.
Nur wenn man in diesem Fall für 1A 51 7F 94 den Plaintext 00 00 00 00 annimmt ergeben sich für die
restlichen zwei Zeilen sinnvolle Werte (fangen mit Sync-Byte = 47h an). Wenn man nur zwei Zeilen
hat, kann man davon ausgehen das die Zeile die Häufiger vorkommt dem Plaintext 00 00 00 00
Seite 8
DVB TS Vollverschlüsselung geknackt
entspricht. Kommen beide Zeilen etwa gleich häufig vor, muss man halt den Knackversuch zweimal
durchführen, aber das ist immer noch besser als es mit allen 47 Varianten zu tun.
Man sucht jetzt das dem Plaintext … 47 1F FF 10 entsprechendes Paket mit der Bytefolge … 66 8B 84
01 ED A4 49 C2 5D 4E 80 84 im original TS der auf die verschlüsselte PID gefiltert wurde, überspringt
dann die nächsten 4 Header Bytes und hat eine 184 Byte lange verschlüsselte Nullbytefolge vor sich
mit der man sich aus der Rainbow Table das CW berechnen lassen kann.
Doch es gibt nicht nur die Variante bei der der Header genau 4 Byte vor Ende der Payload beginnt:
00 00 00 00 00 00 00 00 <148 weitere Bytes> 00 00 00 00 47 1F FF 10
Es gibt noch folgende drei weitere Varianten:
00 00 00 00 00 00 00 00 <148 weitere Bytes> 00 00 00 00 00 47 1F FF
00 00 00 00 00 00 00 00 <148 weitere Bytes> 00 00 00 00 00 00 47 1F
00 00 00 00 00 00 00 00 <148 weitere Bytes> 00 00 00 00 00 00 00 47
Der Multiplexer, der mit dem TS gefüttert wird und dann eine verschlüsselte PID erzeugt,
synchronisiert nämlich nicht die Header so dass sie 4 Byte aligned sind. Das ist für eine einwandfreie
Funktion auch nicht nötig. Ich habe mal so eine Aktuelle mit einer älteren Aufzeichnung verglichen
und da waren die Sync Bytes an unterschiedlichen stellen. Eine zeitgleiche Aufzeichnung von einem
anderen Transponder zeigte, dass sich hier die Position des Sync Bytes nicht verändert hatte.
Vielleicht ändert sich die Position des Sync Bytes immer dann, wenn der Multiplexer mal bootet oder
mal kurz der Kontakt zur Quelle, die den Multiplexer speist, abbricht.
Ich hatte sogar noch eine Aufzeichnung vor einem Jahr. Damals hatten die zusätzlich noch auf 9° Ost
gesendet. Die verwendeten CWs sind jetzt immer noch identisch auf 30° West im Einsatz. Vermutlich
hatten die die CWs noch nie geändert. Allerdings kommt nicht nur ein einziges CW für die
verschlüsselten PIDs zum Einsatz. Ist in der folgenden Tabelle die CW Nr. bei zwei verschiedenen PIDs
gleich, dann wurden sie auch mit einem identischen CW verschlüsselt:
Freq.
PID
(hex.)
Prg.
Nr.
CW
Nr.
11222H
SR:30000ks
(08.12.2011)
7DA
7E4
7E5
7E6
7E7
7E8
848
3010
3020
3021
3022
2023
3024
3120
8
8
8
8
8
8
4
849
3121
84A
3122
11262H
SR:30000ks
(08.12.2011)
TV , Radio oder Data\
Provider\
Programm
TSID
Org.
NetID
TV\RTVE\La 2
TV\RTVE\24h
TV\RTVE\Clan
041A
22D4
4
TV\RTVE\La 1
R\RNE\Radio Nacional
R\RNE\Radio 5 Todo Noticias
0455
22D4
4
TV\RTVE\La 1
R\RNE\Radio Nacional
03F3
22D4
Seite 9
DVB TS Vollverschlüsselung geknackt
R\RNE\Radio 5 Todo Noticias
11302H
SR:30000ks
(08.12.2011)
11653H
SR:19680ks
(08.12.2011)
11677H
SR:19684ks
(08.12.2011)
12523V
SR:10400ks
(08.12.2011)
12548V
SR:29600ks
(08.12.2011)
84B
3123
4
TV\RTVE\La 1
R\RNE\Radio Nacional
R\RNE\Radio 5 Todo Noticias
03F5
22D4
84C
3124
4
TV\RTVE\La 1
R\RNE\Radio Nacional
R\RNE\Radio 5 Todo Noticias
03F6
22D4
84D
84E
3125
3126
10
4
TV\RTVE\La 1
R\RNE\Radio Nacional
R\RNE\Radio 5 Todo Noticias
044D
22D4
84F
89D
89E
89F
8A0
8A2
8AC
8AD
8AE
8AF
12D
12F
3127
3205
3206
3207
3208
3210
3220
3221
3222
3223
1301
1303
10
9
9
9
9
9
9
9
9
9
5
5
191
192
1401
1402
5
5
582
2410
7
2BD
1701
2
TV\La Sexta\laSexta2
000E
22D4
TV\La Sexta\laSexta3
TV\La Sexta\laSexta HD
TV\SOGECABLE\CANAL+ Dos
R\SOGECABLE\SER
R\SOGECABLE\40 PRINCIPALES
R\SOGECABLE\CADENA DIAL
TV\TELECINCO\CUATRO
2BE
1702
2
2BF
1703
2
TV\Tele5\Boing
TV\Tele5\Telecinco HD
TV\TELSON\MTV
TV\La 10\La 10
R\La 10\ABC Punto Radio
TV\ANTENA3 TELEVISION\NITRO
TV\ANTENA3 TELEVISION\Antena3 HD
000F
22D4
0010
22D4
R\ANTENA3 TELEVISION\ONDA CERO
R\ANTENA3 TELEVISION\EUROPA FM
R\ANTENA3 TELEVISION\ONDA
Seite 10
DVB TS Vollverschlüsselung geknackt
MELODIA
TV\MARCA TV\MARCA TV
TV\VEOTV\13 TV
TV\VEOTV\MundoInteractivo
R\COPE\COPE
R\Radio Maria\Radio Maria
12631V
SR:30000ks
(08.12.2011)
1F41
1F42
1001
1002
11
3
1F43
1003
12
TV\RTVE\TVE-HD Pruebas
TV\RTVE\TDP
R\RNE\Radio Clasica HQ
R\RNE\Radio 3
Data\RTVE\Canal Ingenieria
TV\La Sexta\laSexta
TV\La Sexta\GOL TELEVISION
9C40
22D4
0002
22D4
TV\La Sexta\laSexta3
TV\TELECINCO\CUATRO
TV\TELECINCO\DIVINITY
TV\TELECINCO\LA TIENDA EN CASA
12671V
SR:30000ks
(08.12.2011)
1F44
1F45
1F46
1004
1005
1006
13
14
12
TV\RTVE\La 1
TV\RTVE\La 2
TV\RTVE\24h
TV\RTVE\Clan
R\RNE\ Radio Nacional
R\RNE\ Radio 5 Todo Noticias
03F0
22D4
Tabelle 2: Sendetabelle
Normalerweise bräuchte man für die 4 möglichen Sync Byte Positionen auch 4 Rainbow Tables, die
auf 4 verschiedenen Klartexten basieren, um alle PIDs knacken zu können. Die Sync Byte Positionen
der verschiedenen PIDs sind ja kunterbunt gemischt.
Da aber mehrere PIDs, die unterschiedliche Sync Byte Positionen haben, mit dem gleichen CW
verschlüsselt wurden, genügt es dass eine einzige Sync Byte Position mit der eigenen Rainbow Table
übereinstimmt. Hat man das CW dann berechnet, kann man mit dem CW auch die anderen PIDs
entschlüsseln. Ist die eigene Sync Byte Position nicht dabei und will man keine weiteren Rainbow
Tables erstellen, dann kann man ja in ein paar Wochen mal wieder nachsehen ob sich die Sync Byte
Positionen geändert haben.
Ich habe mir für diesen Hack nur eine vollständige Rainbow Table für eine einzige Sync Byte
Positionen, die die 184 Nullbytes knacken kann, erstellt. Darum hat die obige Tabelle auch noch
einige Lücken. Ist kein Programname angegeben ist auch das CW noch nicht bekannt.
Wenn in dem Paket mit dem AF die letzten 4 verschlüsselten Bytes, die den Wert 00 00 00 00
repräsentieren, bei verschiedenen PIDs identisch war, dann habe ich in der Tabelle die gleiche CW
Nr. vergeben. Somit weiss man auch bei den noch nicht gefundenen CWs wie viele es noch sind.
Seite 11
DVB TS Vollverschlüsselung geknackt
Eine Unsitte die ich bei neueren Aufzeichnungen feststellen konnte ist, dass die Füllpakete jetzt bei
einigen Transpondern dynamische Zusatzdaten enthalten und somit leider nicht mehr für Rainbow
Tables geeignet sind.
Die ersten 8 Byte des Füllpakets enthalten dann Zusatzdaten, die Restlichen sind Null.
Das erste Byte ist anscheinend immer 01h wenn Zusatzdaten vorhanden sind.
Das zweite Byte ist 00h.
Das dritte und das vierte Byte ist ein zwei Byte Counter der um eins hochzählt wenn der Multiplexer
ein Füllpaket oder auch ein Nutzpaket entgegen nimmt. So kann man leicht erkennen ob es einen
Paketverlust auf der Übertragungsstrecke gab und sogar ob es nur ein Paket war oder gleich 20.
Das fünfte und sechste Byte ist statisch.
Das siebte und achte Byte ist die TSID.
Eine Sicherheitsmassnahme ist das Ganze anscheinend nicht. Es wird ja nur teilweise verwendet.
Auch ist der 16 Bit Counter viel zu klein für eine Sicherheismassnahme. Alle 65536 Pakete wäre das
Füllpaket wieder identisch und kann somit für das Erstellen einer Rainbow Table verwendet werden.
Das brachte mich auf die Idee, als Plaintext zum Erstellen der Rainbow Table nicht den Inhalt der
Füllpakete heranzuziehen. Ein positiver Nebeneffekt ist auch, dass man sich nicht mehr mit der Sync
Byte Position herumschlagen muss, sondern nur Eine und nicht gleich vier Rainbow Tables benötigt.
Doch welche statische Daten gibt es noch im TS?
Es gibt Tabellen wie z.B. PAT, CAT, NIT, TDT oder PMT die regelmässig ausgestrahlt werden. Die
Tabellen benutzen oft nicht die ganze Payload. Der Rest der Payload wird immer mit 0xFF Bytes
aufgefüllt. Die Time and Date Table (TDT) z.B. enthält ja nur das Datum und Zeit. Das macht ja nur ein
paar Bytes aus. Selbst bei in der Regel grossen Paketen wie einer Network Information Table (NIT) die
sich über mehrere Pakete erstrecken kann, ist es doch möglich das sie zwei komplette Pakete
benötigt und vom dritten Paket nur ein paar Bytes. Dann sind auch im dritten Paket jede Menge 0xFF
Bytes. Selbst in der Video PID gibt’s immer wieder Pakete die nur ein AF aber keine Payload haben.
Im AF ist dann nur die Program Clock Reference (PCR) enthalten, der ganze Rest ist mit 0xFF Bytes
aufgefüllt.
Als Plaintext jetzt einfach 184 * FFh (statt 184 * 00h) herzunehmen wird aber nicht zum Erfolg
führen. So viele FFh Bytes am Stück werden wir nicht finden, da sie ja nur zum Auffüllen verwendet
werden. Der Trick ist bei der verschlüsselten PID nicht die Pakete zu verwenden die nur eine Payload
von 184 Bytes haben, sondern nur die Pakete mit AF und Payload. Da das AF bei diesem Provider
immer 20 Bytes hat, hat die Payload nur noch 164 Bytes. Da wir für das Erzeugen der Rainbow Table
nur den Block cipher verwenden und nicht den Stream cipher, fallen auch noch die letzten 4 Byte
weg. Wir benötigen also jetzt nur noch 160 Bytes mit dem Wert FFh und das ist jetzt kein Problem
mehr.
Doch wie erkennt man verschlüsselte FFh Bytes?
Seite 12
DVB TS Vollverschlüsselung geknackt
Filtern wir einfach mal aus den TS nur die Pakete die neben der Payload auch ein AF (mit 20 Bytes)
haben. Die Payload mit den 164 Bytes lassen wir in eine Textdatei schreiben. Dann sortieren wir die
Textdatei, damit die Pakete mit den gleichen Anfang haben beieinander sind. Wir interessieren uns
nur für die Zeilen bei denen jeweils die ersten 160 Bytes identisch sind. Hier ein Beispiel aus der
Praxis:
17
18
4
7
201
mal
mal
mal
mal
mal
…
…
…
…
…
91
91
91
91
91
B8
B8
B8
B8
B8
04
04
04
04
04
49
49
49
49
49
71
71
71
71
71
8D
8D
8D
8D
8D
04
04
04
04
04
51
51
51
51
51
F4
F4
F4
F4
F4
7D
7D
7D
7D
7D
87
87
87
87
C0
8E
91
92
94
91
(=
(=
(=
(=
(=
…00
…00
…00
…00
…00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
47
47
47
47
00
1F)
00)
03)
05)
00)
13 mal … 27 AD F5 03 5B 04 F1 23 2C B5 37 09 (= …FF FF FF FF FF FF)
2 mal … 27 AD F5 03 5B 04 F1 23 2C B5 8F F6 (= …FF FF FF FF 47 00)
Es wurden zwei verschiedene Blöcke gefunden die öfters vorkommen und innerhalb der ersten 160
Bytes jeweils identisch sind.
Wir schauen uns jetzt vom ersten Block jeweils die letzen 4 Bytes, die nur mit den Stream cipher
verschlüsselt worden sind, an.
Jeweils das erste (F4h) der vier letzen Bytes ist identisch und deshalb überspringen wir es.
Jeweils das zweite Byte (7Dh) ist auch identisch und wir überspringen es wieder.
Das dritte Byte ist öffters 87h, aber nur einmal C0h. Einer dieser Werte sollte entschlüsselt das Sync
Byte 47h sein.
Doch Welchen Wert hat das andere Plainbyte?
Wir kennen die Vorgehensweise ja schon von weiter oben.
Crypt1 XOR Crypt2 = Plain1 XOR Plain2
Aber auch:
Crypt1 XOR Crypt2 XOR Plain1 = Plain2
87h XOR C0h XOR 47h = 00h
Das C0h entspricht entschlüsselt anscheinend 00h, weil es mit 201 mal öfters vorkommt.
Also der erste Block ist anscheinend mit seinen Nullen nicht der gesuchte Block, denn wir suchen ja
nach FFh Bytes.
Wenden wir und also den zweiten verbleibenden Block zu.
Auch hier ist der erste Unterschied im dritten der letzten vier Bytes auszumachen.
37h XOR 8F XOR 47h = FFh
Das sieht jetzt besser aus. Die letzen 4 Byte brauchen wird zum Berechnen des CW mit der Rainbow
Table nicht. Die ersten 160 Bytes (… 04 F1 23) reichen. Sie entsprechen 160 mal dem Byte FFh.
Seite 13
DVB TS Vollverschlüsselung geknackt
Aus Zeitgründen habe ich nicht eine vollständige Rainbow Table erzeugt mit 160 mal FFh, sondern
nur so viel, dass ich eines der noch unbekannten CW berechnen konnte. Mir gings hier nur ums
Prinzip, ob das auch in der Praxis so funktioniert.
Wir haben also bis jetzt gesehen welchen Plaintexte man für das Erzeugen seiner Rainbow Table
verwenden kann und welche Vor- und Nachteile die verschiedenen Plaintexte haben. Auch wissen
wir wie wir zu dem passenen Ciphertext kommen um mit der Rainbow Table das CW berechnen zu
können.
Doch wie erzeugen wir die Rainbow Table und wie genau berechnen wir mit ihr später das CW?
Zuerst sollte man sich [1] duchlesen um das Prinzip der Rainbow Tables zu verstehen.
Das CW hat zwar eine Länge von 8 Bytes und somit wären 264 verschiedene Schlüssel möglich, aber
die Anzahl der verschiedenen Schlüssel wird bei allen Receivern immer künstlich auf 248 begrenzt.
Vermutlich haben sich die die 216 in Reserve gehalten um im Falle eines Knacken des Systems (z.B.
über Rainbow Tables) es sofort durch nutzen der vollen 264 Schlüssel über ein Firmware update
wieder sicher zu machen. Dann bleibt hoffentlich noch genug Zeit sich einen Nachfolger für den CSAAlgo zu überlegen der eine höhere Schlüssellänge unterstützt (z.B. AES). Es müssen dann natürlich
neue Receiver produziert werden die beide Varianten (z.B. CSA und AES) unterstützen. Wenn die
Endkunden dann die neuen Receiver haben, könnten die schlagartig auf neue Verschlüsselung
umstellen, bevor auch die 264 Schlüssel sich mit Rainbow Tables in der Praxis knacken lassen.
Innerhalb der Rainbow Table kann man also derzeit noch mit 6 Bytes für den Schlüssel arbeiten.
Diesen Schlüssel kann man dann für Verschlüsselungen mit CSA wie folgt von 6 auf 8 Bytes erweitern:
Cw8[0]
Cw8[1]
Cw8[2]
Cw8[3]
Cw8[4]
Cw8[5]
Cw8[6]
Cw8[7]
=
=
=
=
=
=
=
=
Cw6[0];
Cw6[1];
Cw6[2];
Cw6[0] + Cw6[1] + Cw6[2];
Cw6[3];
Cw6[4];
Cw6[5];
Cw6[3] + Cw6[4] + Cw6[4];
Die Grösse der Rainbow Table kann man ja über die Kettenlänge selbt beeinflussen.
Je grösser die Rainbow Table ist, desto schneller kann später ein CW gefunden werden, aber desto
mehr Plattenplatz wird dann auch benötigt.
Ich habe mich für 10000h (216) als Kettenlänge entschieden. Die Rainbow Table muss somit nur noch
die verbleibenden 248-16 = 232 Paare aus Start- und Endwert enthalten und kann dennoch das CW
relativ schnell berechnen.
Der Startwert und der Endwert stellen das CW dar, benötigen also jeweils 6 Bytes innerhalb der
Rainbow Table.
Die Grösse der Rainbow Table berechnet sich wie folgt:
(6+6) * 232 = 48 GByte
Seite 14
DVB TS Vollverschlüsselung geknackt
Die Rahmenparameter sind gesteckt und man kann mit dem Erzeugen anfangen.
Man wählt ein 6 Byte CW als Startwert. Vom Ersten bis zum letzen Startwert wird immer um eins
hochgezählt. Wählt man 0 als Startwert dann ergibt sich folgender Bereich:
00 00 00 00 00 00 … 00 00 FF FF FF FF
Dieser Startwert ist aber sehr ungünstig. Jemand anders aus der Community könnte auch bei 0
Anfangen und die resultierenden 48 GByte wären absolut identisch. So eine Rainbow Table deckt
keinesfalls 100% ab, sondern beim CSA wie ich glaube etwa 66%. Wärend der Verkettung der jeweils
10000h Elemente muss nämlich ständig die Entropie von 264 (Crypt Block) auf 248 (CW Länge)
reduziert werden. Dadurch mergen unweigerlich jede Menge der Ketten und ergeben den gleichen
Endwert. Ziel ist es deshalb gleich mehrere verschiedene Rainbow Tables zu mit unterschiedlichen
Startwerten zu haben, damit man möglichst nahe an der 100%igen Abdeckung ist. Die ersten beiden
Bytes des Startwerts sollten absolut zufällig sein, die restlichen 4 Bytes sollten 0 haben. Z.B.:
C3 E9 00 00 00 00 … C3 E9 FF FF FF FF
Um den Endwert aus dem Startwert zu berechnen kann man in etwa wie folgt vorgehen:
for(RoundNr=0; RoundNr<0x10000; RoundNr++)
{
//Verschlüsseln
//input 8 Byte: Cw
//output 8 Byte: data
//inside the fctn: 184 or 160 Byte fixed plaintext
BlockCipherEncryptPlain(Cw, data);
//Reduzierung der Daten von 8 Bytes auf 6 Bytes
//in dem data[6] und data[7] nicht verwendet werden
//XOR-Verknüpfen der RoundNr mit den Daten
data[2] ^= ((RoundNr >> 24) & 0xFF);
data[3] ^= ((RoundNr >> 16) & 0xFF);
data[4] ^= ((RoundNr >> 8) & 0xFF);
data[5] ^= (RoundNr & 0xFF);
//6 Byte Daten in 8 Byte CW konvertieren
Cw[0] = data[0];
Cw[1] = data[1];
Cw[2] = data[2];
Cw[3] = data[0] + data[1] + data[2];
Cw[4] = data[3];
Cw[5] = data[4];
Cw[6] = data[5];
Cw[7] = data[3] + data[4] + data[5];
}
memcpy(Endwert, data, 6);//die ersten 6 Bytes als Endwert übernehmen
Seite 15
DVB TS Vollverschlüsselung geknackt
Hier als Beispiel ein paar Zwischenergebnisse während der Berechnung der Kette für den Plaintext
184 * 00h. Abgespeichert wird später nur der Start- und Endwert. Man kann damit die eigene
Implementation überprüfen (aber anschliessend den Startwert ändern!):
Cw6: 00 00 00 00 00 00
Crypt: BF 8A 91 00 77 6F
XOR RoundNr: 0h
Cw6: BF 8A 91 00 77 6F
Crypt: 1A 83 E3 00 58 84
XOR RoundNr: 1h
Cw6: 1A 83 E3 00 58 85
Crypt: 76 93 55 40 35 8B
XOR RoundNr: 2h
Cw6: 76 93 55 40 35 89
Crypt: FC 8D 87 4C CF 75
XOR RoundNr: 3h
Cw6: FC 8D 87 4C CF 76
…
Cw6: 86 48 D2 8E 21 BF
Crypt: DA C4 02 09 51 9E
XOR RoundNr: FFFCh
Cw6: DA C4 02 09 AE 62
Crypt: 54 05 79 9D 95 F0
XOR RoundNr: FFFDh
Cw6: 54 05 79 9D 6A 0D
Crypt: AA 28 CA FD B7 5D
XOR RoundNr: FFFEh
Cw6: AA 28 CA FD 48 A3
Crypt: 3A 39 2A E6 42 61
XOR RoundNr: FFFFh
Cw6: 3A 39 2A E6 BD 9E
<= Startwert
7D A5
B0 C6
2E AE
9D 62
C0 DB
0E A9
50 9E
D9 4B
<= Endwert
Der Anfang und das Ende meiner 48 GByte Rainbow Table für den Plaintext 184 * 00h. Man sieht den
6 Byte langen Startwert und dann den 6 Byte langen Endwert.
00
00
00
00
00
00
00
00
00
00
…
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
01
02
03
04
05
06
07
08
09
3A
E4
BE
29
A2
A6
55
67
B1
47
39
63
2F
E3
AA
EE
93
59
78
A8
2A
9C
FF
9D
AA
31
42
5C
C9
37
E6
23
98
3B
D0
57
66
D2
8F
2B
BD
DE
7F
AD
C6
49
48
79
49
13
9E
8C
10
99
C6
E0
DC
82
30
0B
00
00
00
00
00
00
00
00
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
F6
F7
F8
F9
FA
FB
FC
FD
7F
69
A3
4B
D4
6A
6D
3C
3E
B7
AA
91
24
06
B4
24
EA
A1
14
99
2F
C0
5E
CD
6E
4A
3F
AA
C6
6A
46
0B
FE
96
3C
C8
57
C1
A2
73
D7
D4
EB
02
A1
FA
87
09
Seite 16
DVB TS Vollverschlüsselung geknackt
00 00 FF FF FF FE 1B 15 4B 20 BE 61
00 00 FF FF FF FF 57 10 46 C9 5D 70
Nach dem Erstellen der Rainbow Table, die ja nach aufsteigenden Startwerten sortiert ist, muss man
sie jetzt nach aufsteigenden Endwerten umsortieren (ermöglicht später eine effiziente binäre Suche),
da beim Berechnen eines CW mit der Rainbow Table nach speziellen Endwerten gesucht wird. Hat
man sie dann gefunden wird der zugehörige Startwert zum Weiterrechnen ausgelesen:
00
00
00
00
00
00
00
00
00
00
…
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
11
86
6F
C5
99
17
50
E4
A1
CB
6F
27
17
69
53
53
B1
EA
90
E4
08
08
6A
2A
B3
49
62
92
32
99
DB
E3
22
71
A0
1A
86
74
B8
8D
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
02
04
04
05
05
05
06
09
09
0F
47
A6
A6
41
41
41
73
1F
1F
06
07
18
18
D4
D4
D4
BB
F2
F2
A9
00
00
00
00
00
00
00
00
00
00
FD
42
73
94
DF
36
1E
50
F0
10
E3
46
E6
E8
B4
9C
4D
F0
90
FD
71
50
2D
5C
C9
8D
FD
61
82
97
39
39
18
B5
CA
69
C8
D0
23
EA
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
F5
F6
F6
F7
FA
FA
FA
FB
FB
FF
71
7D
CB
26
69
BB
BB
0E
89
5B
22
46
2F
85
33
30
30
88
A3
D4
Man kann jetzt auch gut das vorher geschilderte mergen sehen, das zu gleichen Endwerten führt.
Wir haben jetzt unsere Rainbow Table, aber wie ermittelt man mit ihr und einem ciphertext das CW?
Klären wir das gleich an Hand unseres Beispiels mit der obigen abgebildeten Kette mit Startwert 0.
Wir wir haben ein verschlüsseltes Paket gefunden das dem Plaintext 184 * 00h entspricht. Also
nehem wir den ersten 8 Byte Block vom Anfang er Payload AA 28 CA FD B7 5D 50 9E um das CW mit
der Rainbow Table herauszufinden.
Wir kürzen AA 28 CA FD B7 5D 50 9E auf 6 Bytes und führen eine XOR Verknüpfung mit der letzten
RoundNr FFFFh durch. Die 6 Byte vergleichen wir mit allen Endwerten der Rainbow Table. Es gibt
keine übereinstimmung.
Wir kürzen AA 28 CA FD B7 5D 50 9E auf 6 Bytes und führen eine XOR Verknüpfung mit der
vorletzten RoundNr FFFEh durch. Das Cw6: AA 28 CA FD 48 A3 konvertieren wir auf Cw8 und
verschlüsseln wir wieder unseren Plaintext 184 * 00h. Es ergibt sich der Ciphertext 3A 39 2A E6 42 61
D9 4B. Dann noch XOR mit der RoundNr FFFFh. Die 6 Bytes 3A 39 2A E6 BD 9E vergleichen wir mit
allen Endwerten der Rainbow Table. Jetzt gibt es eine Übereinstimmung. Falls dieser Endwert
mehrmals in der Rainbow Table vorkommt, muss man das Folgende für jeden zugehörigen Startwert
wiederholen. Wir holen uns den zum Endwert passenden Startwert 00 00 00 00 00 00 aus der
Rainbow Table. Dann berechnen wir wieder wie wir es schon beim Erzeugen der Rainbow Table
gemacht haben eine Kette und zwar die mit unseren gefunden Startwert 00 00 00 00 00 00. Dabei
Seite 17
DVB TS Vollverschlüsselung geknackt
prüfen wir nach jeder Verschlüsselung ob das Ergebnis mit unseren Ciphertext AA 28 CA FD B7 5D 50
übereinstimmt. Falls ja, dann nehmen wir das Cw6 54 05 79 9D 6A 0D das diesen Ciphertext
ergeben hat, konvertieren es in ein Cw8 und fertig. Ansonsten wiederholen wird das Ganze bis wir
bei Runde 0 angekommen sind.
Cw6: 00 00 00 00 00 00
Crypt: BF 8A 91 00 77 6F
XOR RoundNr: 0h
Cw6: BF 8A 91 00 77 6F
Crypt: 1A 83 E3 00 58 84
XOR RoundNr: 1h
…
Crypt: 54 05 79 9D 95 F0
XOR RoundNr: FFFDh
Cw6: 54 05 79 9D 6A 0D
Crypt: AA 28 CA FD B7 5D
XOR RoundNr: FFFEh
Cw6: AA 28 CA FD 48 A3
Crypt: 3A 39 2A E6 42 61
XOR RoundNr: FFFFh
Cw6: 3A 39 2A E6 BD 9E
<= Startwert
7D A5
B0 C6
0E A9
50 9E
D9 4B
<= Endwert
Seite 18
DVB TS Vollverschlüsselung geknackt
Normaler ungetunnelter TS
Bisher ging’s ja nur um getunnelte TS, doch wie sieht’s bei herkömmlichen ungetunnelten TS mit den
Berechnen von CWs mit Rainbow Tables aus?
Da hier nur Video und Audio verschlüsselt wird, entfallen hier sehr viele bekannte Klartexte. Ich habe
mir deswegen mal die Video-PID von einem unverschlüsselten Sender im HEX-Editor angesehen. Das
Interessante war, dass ich mehre unterschiedlich grosse Blöcke von Nullen gesehen habe. Sie waren
immer am Ende von einem MPEG Paket. Aber nicht jedes MPEG Paket hat Nullen am Ende. Wenn der
letzte Rest eines MPEG Pakets nicht exakt in ein TS Paket mit 184 Byte Payload passt, dann wird im
letzten TS Paket auch ein AF untergebracht. Das AF ist so gross, dass das Ende von MPEG Paket exakt
mit dem Ende der Payload vom TS Paket übereinstimmt. Das folgende TS Paket hat dann das Payload
Unit Start Indicator (PUSI)-Bit gesetzt und enthält den Anfang des
nächsten MPEG Pakets.
Wie erkennt man aber, ob bei einer konkreten verschlüsselten Video-PID,
auch solch praktische Nullen mit verschlüsselt wurden?
Man vergleicht die Payload der Pakete die auch ein AF haben. Wenn zwei
Identische vorkommen, dann sind es höchstwahrscheinlich verschlüsselte
Nullen.
Um das zu Testen habe ich mir einen Bruchteil einer Rainbow Table
erzeugt, die auf den Plaintext von 8 Nullbytes aufgebaut ist.
Hat eine Payload nur 0-7 Bytes, dann werden sie auch bei einem als
verschlüsselt markierten Paktet immer als Klartext übertragen. Der CSAAlgo kann erst ab 8 Bytes verschlüsseln, bei weniger Bytes wird immer
transparent durchgereicht.
Eine Rainbow Table die auf 8 Nullbytes basiert, kann Payloads knacken die
zwischen 8 und 15 Bytes lang sind und bei denen die ersten 8 Bytes
verschlüsselte Nullen sind. Die restlichen bis zu 7 Bytes gehen nur durch
den Stream cipher und nicht durch den Block chipher. Deren Wert ist
somit irrelevant.
Ich habe mir ein paar Sender genommen, die mit Mediaguard 3,
Nagravision 3, Viaccess 3 und VideoGuard verschlüsselt sind. Es wird also
kein festes CW wie bei BISS verwendet, sondern ein etwa alle 10
Sekunden Wechselndes. Natürlich konnte ich mit dem Fragment meiner
Rainbow Table nur jeweils eins der CWs berechnen, also nur eine
Cryptoperiode entschlüsseln. Für ein paar Screenshots (siehe rechts) hat
aber gereicht.
Abbildung 3: 30W 11731H
PID 1651h "FX Portugal"
Abbildung 4: 30W 11731H
PID 1671h "Fox HD Spain &
Portugal"
Abbildung 5: 13E 10796V PID
AAh "Orange sport Polska"
Abbildung 6: 13E 12731H
PID A7h "Int101_1"
Abbildung 7: 13E 12731H
PID A8h "Int101_2"
Seite 19
DVB TS Vollverschlüsselung geknackt
Performance
Mit meiner 12% Over Clocked NVIDIA GeForce GTX 470 (GV-N470SO-13I) komme ich auf folgende
Performance:
Plaintext Länge
CWs pro Sekunde
Erzeugezeit
184 Bytes
160 Bytes
8 Bytes
30 Million
33 Million
71 Million
109 Tage
99 Tage
45 Tage
Durchschn. Zeit zum
Ermitteln eines CWs
170 sek.
Die CWs pro Sekunde sind gemessen, die Erzeugezeit hochgerechnet. Ich habe ja nur die eine
Rainbow Table mit den 184 Bytes komplett erzeugt und selbst da habe ich den Rechner nicht an
einem Stück durchlaufen lassen.
Das Erzeugen der Rundenschlüssel für den Blockcipher frisst viel Zeit, ist aber nur einmal pro CW
nötig. Das Verschlüsseln pro 8 Byte Block geht viel schneller und fällt weniger ins Gewicht. Daduch ist
die Geschwindigkeit in der obigen Tabelle nicht gleichmässig im Verhältnis zu den 8 Byte Blöcken.
Evtl. kann ein CUDA [2] Profi noch mehr aus der Karte rausholen.
Empfehlungen
Ganz klar ist die in der Praxis verwendete Schlüssellänge von nur 48 Bits zu gering, um gegen
Rainbow Tables standhalten zu können. Ein Firmwareupdate, das die Vollen vom CSA-Chip
unterstützen 64 Bits nutzt, ist notwendig um erst mal vor den Rainbow Table Angriffen geschützt zu
sein. Da dieser Schutz nicht ewig halten wird, muss sofort mit Entwicklung eines CSA Nachfolgers
begonnen werden. Dafür kann z.B. der schon fertige AES-Algo verwendet werden.
Literatur
[1] Karsten Nohl, Kunterbuntes Schlüsselraten, http://www.heise.de/security/artikel/VonWoerterbuechern-und-Regenboegen-270088.html
[2] http://www.nvidia.de/object/what_is_cuda_new_de.html
Seite 20