Hacking a cracking BNL souborů pro Albi tužku – 2. část

V předchozím díle jsme v BNL souboru identifikovali zašifrované MP3 soubory a nakonec i prolomili šifru. Ve vzduchu zůstaly viset dvě otázky ohledně univerzálnosti šifry v dalších BNL souborech. Na tyto otázky odpovím hned v úvodu. Dále pak společně prozkoumáme hlavičku BNL souboru a nakonec propojení OID kódů s MP3 soubory.

Když se mi podařilo získat klíč, pomocí kterého byl zašifrován první MP3 soubor, můj další myšlenkový postup byl tento – zkusil jsem, zda i v jiném MP3 souboru, ve stejném BNL, platí tatáž šifra. Odpověď zněla ANO. Pak jsem zkusil, zda tatáž šifra platí v jiném BNL souboru. Odpověď zněla NE. Systém byl stejný, ale klíč jiný. Ale offsety šifrovaných bajtů byly stejné ve všech BNL souborech.

Další průzkum hlavičky BNL souboru

Z výše uvedeného jsem usoudil, že klíč musí být obsažen někde v hlavičce nebo (což by bylo složitější), byl generován na základě nějaké vlastnosti souboru kryptograficky. Nejprve jsem zkusil ručně extrahovat podobnou metodou různé klíče z různých BNL souborů a hledat mezi nimi souvislosti. Pak jsem si napsal krátký nástroj, který hledal první MP3 soubor a z přítomnosti ID3 na začátku se snažil hádat první bajt klíče. Pak jsem k nástroji přidal zobrazování kousku hlavičky a pak se dostavil Heuréka moment – skoro všude se na třetím bajtu v klíči vyskytovalo jedno číslo z hlavičky:

zvýrazněné hodnoty 0xD9 v hlavičce BNL souboru
Zvýrazněné hodnoty 0xD9 v hlavičce BNL souboru

Protože očekávám, že v hlavičce budou 32bitové ukazatele někam dál do souboru a zároveň vím, že hodnota 0xD9 je část klíče, usoudil jsem, že do hlavičky jako takové nepatří. Opět jsem dumal nad xorováním, ale zkusil jsem jednu věc – xorovat mezi sebou první 32bitovou hodnotu a druhou – a vždy, tj. pro každý známý BNL soubor, vyšlo 0x200 – což mi přišlo jako docela hezké číslo, které by mohlo být délkou hlavičky. Zkusil jsem to na dalších 32bit číslech v hlavičce a bylo to jasné. Nejen, že hodnota 0xD9 je částí klíče, ale hodnota 0xD90006C8 je klíč k dešifrování ukazatelů v hlavičce.

Dešifrovaná hlavička BNL souboru
Dešifrovaná hlavička BNL souboru

Takhle tedy vypadá hlavička, když dešifruji jednotlivé ukazatele a hned se mi ukázalo číslo, které jsem už viděl – 0x1224E je ukazatel na tabulku MP3. Další ukazatele budu zkoumat později a teď budu dál bádat nad získáním klíče pro MP3 soubory.

Pořád je možnost, že se klíč skládá z čísel z hlavičky, které jsem nepoužil, nebo nějak vyjde z té hodnoty 0xD9 a vygeneruje další bajty klíče. Ještě jednou jsem prozkoumal více souborů, zda platí má teorie, že 4. bajt v souboru je roven 3. bajtu v klíči. Téměř to vycházelo, občas se to lišilo o maličko. Zaměřil jsem se tedy na rozdíl mezi soubory, kde to sedělo a kde ne. Zíral jsem do hlubin hlavičky, hlubiny hlavičky zíraly zpět a pak jsem si toho všiml:

offset 0x140 - 0x150
offset 0x140 – 0x150

Na offsetu 0x140 v hlavičce je 20 bajtů, na první pohled náhodných. Soubory, kde sedělo, že 4. bajt v souboru je 3. bajt v klíči, ty měly na offsetu 0x146 0x00, u souborů, kde to o kousek nesedělo, ty tam měly ten „kousek“. Tj. když přičtu 4. bajt souboru k hodnotě na 0x146, dostanu 3. bajt klíče. Připomenu si hodnotu klíče pro tento soubor a zkusím si pod něj napsat 16 hodnot tak, abych tu 0x00 a 0xD9 srovnal pod sebe:

78 CA D9 EA - B7 AD DB 0C - 05 9D 0C E3 - 07 9D 0C E3
9F F1 00 11 – DD D4 02 33 – 2C C4 33 0A - 2E C4 33 0A

A hned vidím na konci, že stejná čísla v klíči vedou na stejná čísla v těchto bajtech (0x9D vede na 0xC4 atd). Odtud už netrvalo dlouho a bylo to: 16 bajtů od offsetu 0x144 je klíč, když se ke každému bajtu připočte ona hodnota ze 4. bajtu souboru.

 9F F1 00 11 – DD D4 02 33 – 2C C4 33 0A - 2E C4 33 0A
+D9 D9 D9 D9 - D9 D9 D9 D9 - D9 D9 D9 D9 - D9 D9 D9 D9
 -----------------------------------------------------
 78 CA D9 EA - B7 AD DB 0C - 05 9D 0C E3 - 07 9D 0C E3

Hurá, klíč tedy umím ze souboru získat. Jak ale získat ty jednotlivé ofsety bajtů, které se pak šifrují? Na to jsem nakonec nepřišel. Sice předpokládám, že na to existuje nějaká jednoduchá a elegantní metoda, ale ta se mi vzpírá. Řešením je to, že jsem různě dešifroval ty bloky na konci a nakonec jsem zjistil, že je to takto:

  • Blok, který se šifruje, má 0x200 (512) bajtů.
  • Klíč má 0x10 (16) bajtů.
  • Na každých 16 bajtech se použijí 4 bajty klíče.
  • Tedy každých 64 bajtů je jedno „protočení“ klíče.
  • A to se zopakuje 8x za sebou, ale na různých ofsetech bajtů.

Nakonec jsem si tedy takovouto tabulku sestrojil a napsal si dešifrovací skript, který si vytáhne z hlavičky dešifrovací klíč, seskládá 512 bajtovou dešifrovací tabulku a tou prožene zašifrované MP3. Ve výsledku MP3 soubor vypadá takto:

dešifrovaný MP3 soubor
Dešifrovaný MP3 soubor

Tím mám dešifrování MP3 souborů hotové a můžu se vrátit k ostatním údajům z hlavičky.

Hlavička ještě podrobněji

Při letmém pohledu v hlavičce vidím:

  • Velikost 0x200, což je asi délka hlavičky. Je vlastně i ukazatel na první objekt za hlavičkou.
  • Nějaké ukazatele do souboru – to, že jsou daná čísla ukazatele, se dá odhadnout z toho, že jsou kratší než délka souboru, a minimálně jedno z těch čísel už bylo jako absolutní offset do souboru „odhaleno“, pak už jen stačí vyzkoušet, co se na daných offsetech vyskytuje.
  • Magické číslo 0x42C4 – zatím nevím, co by to mohlo být.
  • Magické číslo 0x1DA (hodně moc podobné našemu číslu 0x1DD, počtu MP3 souborů.
  • Magické číslo 0x4 – nevím.
  • Magické číslo 0xA3E – nevím.
  • A dešifrovací klíč.
Celá hlavička BNL souboru
Celá hlavička BNL souboru

Interpretace ukazatelů

Zajímavé je, že všechny ukazatele jsou relativně vysoké, vyberu z nich ten nejnižší a podívám se na něj (nebo spíš před něj). Je to ukazatel na ofsetu 0xC – 0x10D14.

Tabulka 32bitových ofsetů

Vidím, že se tam nachází nějaká tabulka zjevných 32bitových ofsetů. Zkusím usoudit (protože jsem neviděl nižší ukazatel), že mezi 0x200 a 0x10D14 se nachází dlouhá tabulka ofsetů, kolik jich je? ( 0x10D14 – 0x200 ) / 4 = 0x42C5. Což je o jedničku odlišné od 16bitové hodnoty na offsetu 0x1A hlavičky. A protože při čtení německé dokumentace se vyskytla podobná struktura, usuzuji, že je to řídké pole (tj. pole velké, které má ale většinu hodnot prázdnou, zde tedy 0xFFFFFFFF), které má jako index nějaké číslo mezi 0 a 0x42C4. A teď se podívám, na co vede. Zkusím třeba ten poslední ukazatel 0x11D22.

Tabulka offsetů

Vypadá to, že jsou to 16bitové hodnoty – vždy počitadlo (0x1) a pak potřebný počet hodnot ( 0x1D7). Význam teď nelze říct. Budu tomu zatím říkat TABULKA OFSETŮ.

Rozborem dalších hlavičkových ukazatelů a dat, na které ukazují, se zdá, že data jsou jen dvojího typu:

Typ 1

Pole 16bitových hodnot uvozené 16bitovou délkou pole. Vícenásobný výskyt.

Typ 2

Složitější datová struktura – začíná polem 32bitových ukazatelů na další prvky. Hned za pole ukazuje první z ukazatelů, tak se dá vypočítat jeho velikost. V případě této knihy je to 6 položek, v porovnání s ostatními knihami to vypadá, že se jedná o počet dvoustránek.

Typ 2 - složitější datové struktura
Typ 2 – složitější datová struktura

Tato struktura (červeně podtržená) se skládá z pěti 16bitových údajů

  • 0x0000 – neznámé
  • 0x0016 – počet následujících ukazatelů na prvky
  • 0x0005 – neznámé
  • 0x0000 – neznámé
  • 0x0064 – neznámé

Každý ukazatel pak ukazuje na jeden z prvků, který se skládá z 2 slov

  • 0x4269
  • 0x4269

a následuje opět počet a prvek 0x2AFA.

Když zkusím použít výše uvedené konstanty jako indexy do tabulky ofsetů, vše se mi propojí:

0x0064 chci použít jako offset, vypočítám si tedy 0x200 + 0x0064 * 4 = 0x0390. Na offsetu 0x390 v souboru se nachází ukazatel na 0x10D4E. Tam se nachází jednoprvkové pole s prvkem 1. Zkusím si tedy přehrát MP3 zvuk z indexu 1 a ozve se mi „Zahraj si jednoduchý kvíz“. Tím pádem je jasné, že Typ 2 je tabulka kvízů. Hodnota 6 je počet tabulek a rovná se počtu dvoustran právě proto, že většinou bývá na jedné dvoustraně jeden kvíz.

Když zkusím, co znamená hodnota 0x4269, podobným postupem se dostanu na MP3 s pořadovým číslem 380, což je „Najdi Honzíka“, tj. první otázka kvízu. A prvek 0x2AFA v tabulce offsetů vede na zvuk 42, což je „Honzík“. Tímto je tedy interpretace kvízové tabulky jasnější. Předpoklad je, že prvek s hodnotou 0x0005 je asi počet otázek kvízu.

Když jsem si zpětně prošel tabulky typu 1, zjistil jsem, že jsou ve skutečnosti dvojího typu – jedny ukazují do tabulky offsetů (a přes ně na zvuky), druhé přímo na zvuky.

Vazba k OID kódům na papíře

Jak víme z prvního dílu našeho seriálu, tužka načítá OID kód, který má 16bitů (8 teček, každá kóduje 2 bity). Velmi mrzuté zjištění bylo, že ačkoli pomocí scanneru lze vytisklé tečky celkem jednoduše přečíst a výsledné číslo spočítat, nedokázal jsem přijít na to, proč se daná čísla nikde v souboru BNL nevyskytují. Až při podrobnějším zkoumání německého pitvání podobného systému jsem dostal odpověď: Tužka přečte OID kód z papíru, ale to je tzv. raw kód a zatím nikdo nepřišel na to, jak ho převést na vnitřní kód, který načítá tužka. Někdo ovšem z komerčního nástroje (nevím přesně jakého, předpokládám něco podobného, jako je OID Producer, kde se daná tabulka také vyskytuje) vykopal převodní tabulku. A ta osvětlila zbytek.

Když si z papíru nascanuji objekt „Honzík“, načtu raw kód 0x1A32. Ten pomocí tabulky převedu na vnitřní kód 0x2AFA, a ten už jsem viděl. Je to index do tabulky ofsetů. Takže teď vím, k čemu přesně tabulka ofsetů slouží. Je to převod mezi načteným objektem z papíru (nebo některé z OID tabulek, třeba ve kvízu) a výsledným zvukem.

Tím se mi také vysvětluje předposlední neznámý údaj z hlavičky – 0xA3E je interní kód knihy. Na „zapínacím“ tlačítku je vytištěn jeho raw kód 0x931C. Takto tužka „načte“ novou knihu do paměti.

Mám už hotovo?

V tuto chvíli mi přijde, že téměř chápu celý BNL soubor. Pokračuji tak, že si napíšu pomocný skript, který mi označí všechny pochopené bajty, abych si to ověřil. Očekával jsem, že uvidím, že jsem přečetl všechny bajty, ale ve skutečnosti jsem zjistil, že pro každý OID vede ukazatel na paměť, kterou nepřečtu úplně celou. Chvíli jsem si s tím lámal hlavu, pak jsem se podíval, co jsou ty nepřečtené hodnoty.

Např. pro OID 0x2AFA (papír Honzík) to vede sem:

Čtyři pole pro jeden OID, každé pro jeden ‚mód‘ knihy

Původně jsem načetl jen jedno pole s hodnotou 0x2A, což je zvuk 42 (Honzík), ale ten je tam ještě jednou a pak je tam zvuk 43 (Honzík otevřel očka…) a 44 (Už je ráno, Honzík vstává…). Po průzkumu souboru jsem zjistil, že toto platí pro každý OID. Každý má za sebou 4 pole, vždy o jednom (nebo 0) zvucích. Tužka přepíná „mód“ podle toho, na kterou z přehrávacích ikon (názvy předmětů a postav, dialogy, zvuky, …) dole dítě klepne. Po načtení knihy hraje z prvního pole, po zmáčknutí ikony knížky z druhého pole, ikona žárovky z třetího atd.

A to vysvětluje poslední neznámou hodnotu z hlavičky – ona 4 znamená, do kolika módů přehrávání se může tužka přepnout. Většina knih má módy 4, některé 2, některé mnoho (třeba Roboti brebentí).

Většina polí, které vedou z hlavičky, jsou pole, které obsahují systémové zvuky, zvuky přepínání módů, zvuky reakcí na kvízové odpovědi a zvuky vyhodnocení kvízu. Některé knihy mají ukazatele na neznámé OID nebo zvukové tabulky a zatím nevím, jakým způsobem je interpretovat.

Všechny mé dosavadní poznatky naleznete v dokumentaci BNL souboru.

Závěr analýzy

Tímto relativně přímočarým postupem se mi podařilo rozebrat prakticky celý BNL soubor. Není zde ukázán postup zjištění všech informací o BNL souborů, ale aspoň hrubá představa o jeho vlastnostech a metodách, jak jsem na to přišel.

Šifrování jako takové bylo relativně naivní a špatně provedené, i šifrování hlavičky bylo jen naznačeno, až se člověk diví, proč vůbec něco tak jednoduchého implementovali. Stačilo použít jakoukoli blokovou šifru, která by třeba brala v potaz zarovnaný offset bloku a už tímto by byla analýza ztížená natolik, že by odradila i tvrdohlavějšího protivníka. Nejsem si jist, zda by se dal (vzhledem k hardware tužky) vymyslet systém, který by znemožnil náhradu BNL souboru za vlastní, ale jsem přesvědčen, že výběrem několika bajtů ze středů MP3 souborů by se dal rychle spočítat hash, který by se dal ověřit buď symetricky, nebo v nejprdlejším případě asymetricky, čímž by se znemožnila generace vlastních souborů. K tomu by bylo nutno upravit firmware tužky, což je již vyšší dívčí a zcela mimo rozsah tohoto seriálu.

V příštím, a zároveň posledním, dílu už přijde to, na co všichni netrpělivě čekáte. Dám vám k dispozici můj software, pomocí kterého následně vytvoříme vlastní knížku včetně BNL souboru.

5 názorů na “Hacking a cracking BNL souborů pro Albi tužku – 2. část”

  1. V dokumentaci souboru bnl má být:

    Tedy první bajt vstupního klíče bude uložen na offsetech: 0x00, 0x41, 0x81, 0xC2…
    Druhý bajt pak na offsetech 0x07, 0x47, 0x86, 0xC5…

    nebo ještě lépe:

    Tedy první bajt vstupního klíče bude uložen na offsetech: 0x00, 0x41, 0x81, 0xC2, 0x100, 0x141, 0x181, 0x1C2.
    Druhý bajt pak na offsetech 0x07, 0x47, 0x86, 0xC5, 0x105, 0x146, 0x186, 0x1C5.

  2. Díky moc za tento blog! Mám jednu prosbu, rád bych změnil ty otravné zvuky v tužce. Hlavně tedy ten zapínací, pak upozorňující na nečinnost a pak vypínací. Máte prosím nápad, jak a kde to co nejjednodušeji vyměnit? Moc díky!

    1. Muselo by se upravit firmware tužky – v něm jsou uloženy všechny výchozí zvuky. Ale protože je tužek více, dále netuším, zda je ve firmware někde kontrola integrity a u flashování je vždy nenulová možnost „bricknutí“, laicky rozbití tužky, radši bych do toho nezabrušoval, abych nemusel vybrušovat. Prostě vo tom vím tužku.
      V tom firmware je to ve druhé a třetí části – v dokumentaci firmware na githubu je vidět, kde jaké zvuky jsou – stačilo by identifikovat, který přesně je který (což nevím) a zaměnit MP3 za neotravné.

      Zkuste napsat do Albi, zda vám nějak budou umět vyhovět?

Diskuze

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Přejít nahoru