Tekninen artikkeli

HotXLS XLS XOR -obfuskaatio: avaimen johtaminen ja XorRor

HotXLS kirjoittaa Excel 5.0/95 -työkirjoja (BIFF5) XOR-obfuskaatiolla, ja Excel 16 avaa ne vain, kun kolme yksityiskohtaa vastaa [MS-OFFCRYPTO]a täsmälleen: FILEPASS-avain on oltava CreateXorKey_Method1(password), 16-tavuinen XOR-taulukko on rakennettava XorRorilla (kierto oikealle yhden bitin verran) ja jokaisen tavun on käytettävä arvoa XorArrayIndex = (streamin siirtymä + tietueen pituus) mod 16. HotXLS sai indeksin kohdalleen versiossa v2.384.47 ja avaimen ja kierron versiossa v2.384.54. Sitä ennen jokainen sen tuottama salasanasuojattu BIFF5-tiedosto avautui HotXLS:ssä hyvin ja epäonnistui Excelissä

Tuossa viimeisessä lauseessa on koko tarina pienoiskoossa. Lukija ja kirjoittaja, joilla on sama väärä ajatus, sopivat toisiinsa täydellisesti, joten kierrostestit pysyvät vihreinä, kun ainoa merkittävä kuluttaja sanoo ei. Excel 16 sanoi kahdesti ei, kahdella eri viestillä, ja kumpikin viesti osoitti skeeman eri kerrosta. Tämä artikkeli kulkee kerrosten läpi siinä järjestyksessä, jossa Excel ne tarkistaa, tavutason yksityiskohtineen, joista on hyötyä olitpa sitten kutsumassa HotXLS:ää tai kirjoittamassa omaa BIFF-lukijaasi

Mitä BIFF XOR -obfuskaatio oikeasti tallentaa?

BIFF XOR -obfuskaatio tallentaa tiedostoon vain kaksi 16-bittistä sanaa, ja kaikki muu lasketaan uudelleen salasanasta. FILEPASS-tietue ($002F) istuu heti työkirjan globals-BOF:n perässä, ja BIFF5-tiedostossa sen runko on täsmälleen 4 tavua: XOR-avain, jota seuraa salasanan verifier. Suolaa ei ole, algoritmitunnistetta ei ole, eikä RC4- ja AES-skeemien kaltaista salattua verifier-lohkoa ole

Näistä kahdesta sanasta lukija rakentaa kolme asiaa uudelleen:

  • verifierin, salasanatavujen 16-bittisen hashin, joka on XORattu arvolla $CE4B. Sen vertaaminen tallennettuun sanaan on salasantarkistus, ja ainoa sellainen
  • XOR-avaimen, 16-bittisen arvon funktiosta CreateXorKey_Method1 kohdassa [MS-OFFCRYPTO] §2.3.7.2, jota kaksi vakiotaulukkoa ohjaa (InitialCode, 15 sanaa, ja XorMatrix, 105 sanaa)
  • XOR-taulukon, 16 tavua, jotka muodostuvat salasanatavuista täydennettynä kiinteällä 16-tavuisella padilla, kukin XORattuna matalaan avaintavuun (parilliset paikat) tai korkeaan avaintavuun (parittomat paikat), ja sitten kierrettynä oikealle yhden bitin verran

Tietueiden otsikot pysyvät selvätekstinä, samoin muutama kokonainen tietue, jonka skeema vapauttaa, niiden joukossa BOF, FILEPASS ja INTERFACEHDR. Jokainen muu tietuerunko muunnetaan tavu kerrallaan: kierrä vasemmalle 5 bittiä, sitten XOR yhdellä 16-tavaisen taulukon alkiolla. Salauksen purku, jonka [MS-OFFCRYPTO] §2.3.7.3 esittää nimellä DecryptData_Method1, on peilikuva: ensin XOR, sitten kierto oikealle 5

HotXLS:ssä sinun ei tarvitse koskettaa mitään näistä suoraan. Aseta salasana, valitse muoto, ja SaveAs emittoi FILEPASSin ja muuntaa streamin:

uses
  SysUtils, lxHandle;

procedure SaveLegacyProtectedBook(const FileName: string);
var
  Wb: IXLSWorkbook;
begin
  Wb := TXLSWorkbook.Create;
  Wb.Sheets.Add.Name := 'Ledger';
  Wb.Sheets[1].Range['A1', 'A1'].Value := 'Account';
  Wb.Sheets[1].Range['B1', 'B1'].Value := 1250.75;

  // BIFF5 tukee vain XOR-obfuskaatiota; xletAuto valitsisi senkin
  Wb.EncryptionType := xletXor;
  // Pidä ASCII:na ja enintään 15 merkkiä (katso alta)
  Wb.EncryptionPassword := 'secret';

  if Wb.SaveAs(FileName, xlExcel5) <> 1 then
    raise Exception.Create('BIFF5 save failed');
end;

Miksi Excel sanoo salasanan väärin, vaikka verifier täsmää?

Excel hylkää salasanan, koska se ei luota tallennettuun avaimeen: Excel johtaa avaimen kirjoitetusta salasanasta funktiolla CreateXorKey_Method1 ja vertaa sitä FILEPASSin avainsanaan, joten tiedosto, jonka avain on jotain muuta, kaatuu salasantarkistukseen, vaikka verifier olisi oikein. Spesifikaatio kuvaa avaimen salasanan tuotokseksi, ei vapaaksi parametriksi, ja Excel 16 valvoo tuota tulkintaa

HotXLS:n kirjoittaja täytti avainsanan kahdella satunnaisella tavulla ennen versiota v2.384.54. Se näyttää paperilla harmittomalta, sillä verifier on dokumentoitu salasantarkistus ja taulukko rakennetaan sillä avaimella, jonka tiedosto julistaa. HotXLS itse luki kyseiset tiedostot ongelmitta, sillä sen lukija otti avaimen FILEPASSista annettuna. Excel 16, sille annettuna sama tiedosto ja oikea salasana, vastasi, ettei salasana ollut oikein. Versiosta v2.384.54 alkaen avain johtuu, joten FILEPASS salasanalle secret sisältää aina avaimen $014D ja verifierin $DAA7, arvot, jotka ristiintarkistettiin spesifikaation riippumattomalla toteutuksella

HotXLS-kaavio BIFF5 XOR FILEPASS -tietueesta, jonka Excel 16 tarkistaa avatessaan: selvätekstinen nelitavuinen runko sisältää XOR-avaimen ja salasanan verifierin, Excel johtaa avaimen kirjoitetusta salasanasta funktiolla CreateXorKey_Method1 ja hylkää satunnaisen avaimen salasanavirheellä, vaikka verifier täsmäisi; HotXLS tallentaa johdetun avaimen 014D salasanalle secret
FILEPASSin runko on vain kaksi sanaa, mutta Excel johtaa avaimen uudelleen salasanastasi ja vertaa; satunnaisesti täytetty avain kaatuu tarkistukseen, vaikka verifier olisi oikein, minkä vuoksi HotXLS on johtanut sen versiosta v2.384.54 alkaen

Itse johtaminen on lyhyt, kun kaksi taulukkoa ovat paikoillaan. Kulje salasana takaperin, katso jokaisen tavun bittiä 6 seitsemän kertaa siirtäen sitä vasemmalle ja XORaa mukaan yksi XorMatrix-alkio aina, kun bitti on asetettu. Seuraava on periaatepiirros, joka toistaa spesifikaation algoritmin ja vastaa HotXLS:n toteutusta; se ei ole HotXLS:n API:

// Periaatepiirros kohdan [MS-OFFCRYPTO] 2.3.7.2 funktiosta CreateXorKey_Method1
// ja funktiosta CreateXorArray_Method1 (vain havainnollistus, ei HotXLS:n API)
type
  TXorArray = array [0..15] of Byte;

function DemoCreateXorKey(const Password: AnsiString): Word;
const
  InitialCode: array [0..14] of Word = ($E1F0, $1D0F, $CC9C, $84C0, $110C,
    $0E10, $F1CE, $313E, $1872, $E139, $D40F, $84F9, $280C, $A96A, $4EC3);
  XorMatrix: array [0..104] of Word = (
    $AEFC, $4DD9, $9BB2, $2745, $4E8A, $9D14, $2A09,
    $7B61, $F6C2, $FDA5, $EB6B, $C6F7, $9DCF, $2BBF,
    $4563, $8AC6, $05AD, $0B5A, $16B4, $2D68, $5AD0,
    $0375, $06EA, $0DD4, $1BA8, $3750, $6EA0, $DD40,
    $D849, $A0B3, $5147, $A28E, $553D, $AA7A, $44D5,
    $6F45, $DE8A, $AD35, $4A4B, $9496, $390D, $721A,
    $EB23, $C667, $9CEF, $29FF, $53FE, $A7FC, $5FD9,
    $47D3, $8FA6, $0F6D, $1EDA, $3DB4, $7B68, $F6D0,
    $B861, $60E3, $C1C6, $93AD, $377B, $6EF6, $DDEC,
    $45A0, $8B40, $06A1, $0D42, $1A84, $3508, $6A10,
    $AA51, $4483, $8906, $022D, $045A, $08B4, $1168,
    $76B4, $ED68, $CAF1, $85C3, $1BA7, $374E, $6E9C,
    $3730, $6E60, $DCC0, $A9A1, $4363, $86C6, $1DAD,
    $3331, $6662, $CCC4, $89A9, $0373, $06E6, $0DCC,
    $1021, $2042, $4084, $8108, $1231, $2462, $48C4);
var
  Len, I, Bit, Element: Integer;
  Ch: Byte;
begin
  Result := 0;
  Len := Length(Password);
  if Len > 15 then
    Len := 15;                       // avain näkee vain 15 tavua
  if Len = 0 then
    Exit;
  Result := InitialCode[Len - 1];
  Element := $68;                    // viimeinen XorMatrix-alkio
  for I := Len downto 1 do
  begin
    Ch := Ord(Password[I]);
    for Bit := 1 to 7 do
    begin
      if (Ch and $40) <> 0 then
        Result := Result xor XorMatrix[Element];
      Ch := Byte(Ch shl 1);
      Dec(Element);
    end;
  end;
end;

function XorRor(B, KeyByte: Byte): Byte;
begin
  B := B xor KeyByte;
  Result := Byte((B shr 1) or (B shl 7));   // kierto oikealle yhden bitin verran
end;

procedure DemoCreateXorArray(const Password: AnsiString; out Arr: TXorArray);
const
  PadArray: TXorArray = ($BB, $FF, $FF, $BA, $FF, $FF, $B9, $80,
    $00, $BE, $0F, $00, $BF, $0F, $00, $00);
var
  Key: Word;
  Len, I: Integer;
begin
  Key := DemoCreateXorKey(Password);
  Len := Length(Password);
  if Len > 16 then
    Len := 16;
  for I := 0 to Len - 1 do
    Arr[I] := Ord(Password[I + 1]);
  for I := Len to 15 do
    Arr[I] := PadArray[I - Len];
  for I := 0 to 15 do
    if Odd(I) then
      Arr[I] := XorRor(Arr[I], Byte(Key shr 8))
    else
      Arr[I] := XorRor(Arr[I], Byte(Key and $FF));
end;

Salasanalle secret tämä tuottaa taulukon 1F 32 17 B9 14 BA 7B 7F 59 DD 59 7F 7A C0 A6 DF, kätevä testidata, jos testaat omaa lukijaasi

HotXLS-kaavio XOR-taulukon rakentamisesta BIFF5-obfuskaatiolle: kuusitoista tavua, jotka saavat alkunsa salasanasta ja kiinteästä padista, XORataan matalalla avaintavulla parillisissa paikoissa ja korkealla avaintavulla parittomissa paikoissa ja kierretään sitten oikealle yhden bitin verran funktiolla XorRor, jolloin syntyy testidata 1F 32 17 B9 salasanalle secret
Taulukon tavut tulevat salasanasta, padista ja kahdesta avaintavusta, yksi kierto lopussa; kierto vasemmalle 2 toimi vain, kun tavumuunnos ajoi vastakkaisessa järjestyksessä, ja Excel noudattaa spesifikaation järjestystä

Miksi oikea avain tuottaa silti vaurioituneen tiedoston?

Oikea avain tuottaa yhä vaurioituneen tiedoston, kun XOR-taulukko kierretään väärään suuntaan: [MS-OFFCRYPTO] määrittelee taulukkovaiheen funktioksi XorRor, kierto oikealle yhden bitin verran, ja vasemmalle kahdella kierretty taulukko purkaa jokaisen tietuerungon kohinaksi. Avaimen korjaus vei Excel 16:n salasanakehotteen ohi suoraan toiseen virheeseen, ilmoitukseen siitä, että tiedostossa on ongelma eikä sitä voi avata

Vanha HotXLS-koodi kierrätti jokaisen taulukon tavun vasemmalle 2 bittiä, muoto, joka kiertää useissa BIFF-toteutuksissa. Koska HotXLS käytti samaa kiertoa molemmin puolin, sen oma lukija ei koskaan huomannut mitään. Excel 16 ei enää osaa tallentaa Excel 5.0/95 -tiedostoja, eikä se tarjoa XOR:ia tallentaessaan BIFF8:aa, joten natiivia Excel-näytettä ei ollut, johon verrata. Todisteiden oli tultava toiseen suuntaan: kirjoita yksi selvätekstinen BIFF5-stream, koodaa se uudelleen kahdeksalla tavalla ja anna Excel 16:n avata kukin variantti. Kahdeksan varianttia ristitti kolme riippumatonta valintaa:

ValintaVaihtoehto AVaihtoehto B
Taulukon kiertoXorRor (kierto oikealle 1)Kierto vasemmalle 2
Taulukon indeksi(siirtymä + tietueen pituus) mod 16siirtymä mod 16
Tavumuunnoksen järjestysKierto vasemmalle 5, sitten XORXOR, sitten kierto vasemmalle 5

Excel 16 avasi täsmälleen kaksi kahdeksasta: XorRor kiertä-sitten-XORaa-järjestyksellä ja tietueen pituuden indeksillä, sekä yhden variantin, joka vain näyttää erilaiselta. Kierto-vasemmalle-2 XOR-ensin-järjestyksellä ja samalla indeksillä on sama funktio naamioituneena. Kierto distribuoituu XOR:n yli, joten rol5(p xor rol2(b)) on yhtä suuri kuin rol5(p) xor rol7(b), ja 8-bittisellä arvolla kierto vasemmalle 7 on kierto oikealle 1. Lyhyesti, rol5 ∘ rol2 = ror1, mistä syystä kierto-vasemmalle-2-taulukko näyttää eristettynä uskottavalta: se on oikein vain yhdessä vastakkaisen muunnosjärjestyksen kanssa. Spesifikaation järjestykseen paritettuna se turmelee jokaisen muunnetun tavun

Sama koe ratkaisi toisenkin kysymyksen. Variantit, jotka pudottivat tietueen pituuden indeksistä, kaatuivat kaikki, mikä vahvisti indeksisäännön, jonka HotXLS oli omaksunut jakso aiemmin pelkän spesifikaatiotekstin nojalla

Miten XorArrayIndex lasketaan jokaiselle tavulle?

Tavun XorArrayIndex on sen siirtymä työkirjan streamissa plus sen koko tietuedatan pituus, mod 16. Indeksi alkaa siis jokaista tietuetta kohden tietueesta riippuvasta arvosta ja kasvaa yhdellä tavua kohden sen sisällä. Spesifikaation pseudokoodi nimeää syötteet FileOffset ja Data.Length, mikä on helppo lukea väärin pelkäksi tietueen aloitussiirtymäksi, ja juuri tuo väärinlukema oli se, mitä HotXLS toimitti versioon v2.384.47 asti

Kolme yksityiskohtaa ratkaisevat, osuvatko indeksisi yksiin Excelin kanssa:

  • 4-tavuista tietueen otsikkoa ei koskaan muunneta, mutta se silti vie streamin paikkoja, joten tietueen ensimmäinen runkotavu istuu kohdassa otsikon siirtymä + 4
  • pituustermi on koko tietuedatan pituus, ei varsinaisesti muunnettujen tavujen määrä
  • BOUNDSHEET on osittain selvätekstiä: sen ensimmäiset 4 tavua, lbPlyPos, taulukon BOF:n streamin siirtymä, pysyvät luettavina, jotta jäsentäjä löytää taulukot. Kyseiset 4 tavua ohitetaan muunnoksessa mutta lasketaan silti sekä siirtymään että tietueen pituuteen
HotXLS-kaavio XorArrayIndex-säännöstä BIFF5 XOR -obfuskaatiossa: jokainen runkotavu käyttää streamin siirtymää plus koko tietuedatan pituutta modulo 16, selvätekstinen nelitavuinen otsikko ja BOUNDSHEETin lbPlyPos-etuliite lasketaan silti siirtymään, ja tietueen pituustermien ohittaminen oli vika, jonka HotXLS korjasi versiossa v2.384.47
Taulukon indeksi alkaa alusta kerran tietuetta kohden, eikä kerran streamia kohden: otsikko ja mahdollinen selvätekstinen etuliite vievät paikkoja, tietuedatan pituus syöttää modulon, ja vanhan HotXLS:n molemmat puolet sopivat väärästä kaavasta

Yhdistettynä tietuekohtainen muunnos on muutaman rivin mittainen. Taas kerran: tämä on säännön piirros, ei jotain, mitä sinun tarvitsee kutsua:

function Rol8(B: Byte; N: Integer): Byte;
begin
  Result := Byte((B shl N) or (B shr (8 - N)));
end;

// Obfuskoi yhden tietuerungon paikallaan. BodyPos on Body[0]:n streamin
// siirtymä, eli tietueen otsikon siirtymä + 4. PlainPrefix on 4
// BOUNDSHEETille, koko pituus BOF / FILEPASSille, 0 useimmille tietueille
procedure DemoObfuscateRecord(var Body: array of Byte; RecordLength: Word;
  PlainPrefix: Integer; BodyPos: LongWord; const Arr: TXorArray);
var
  I: Integer;
begin
  for I := PlainPrefix to RecordLength - 1 do
    Body[I] := Rol8(Body[I], 5) xor
      Arr[(BodyPos + LongWord(I) + RecordLength) mod 16];
end;

// Lukeminen on peilikuva: B := Body[I] xor Arr[...];
// sitten kierto oikealle 5, eli Rol8(B, 3)

Ennen versiota v2.384.47 HotXLS:n lukija laski indeksin pelkästä streamin sijainnista ja kirjoittaja käytti selvätekstistä tavusiirtymää. Molemmat ohittivat tietueen pituuden, joten taas kerran kaksi puolta sopivat keskenään ja kumman muun kanssa. Riippumaton dekooderi luki version v2.384.47 tuotoksen oikein ja vanhemman tuotoksen roskana, ja kahdeksan variantin Excel 16 -testi vahvisti myöhemmin säännön todellista kohdetta vastaan

Mitä tapahtuu vanhempien HotXLS-versioiden kirjoittamille XOR-tiedostoille?

HotXLS jatkaa omien v2.384.54:ää aiempien XOR-tiedostojensa lukemista tarkistamalla FILEPASS-avaimen: kun tallennettu avain on yhtä suuri kuin salasanasta johdettu avain, lukija rakentaa spesifikaation XorRor-taulukon, ja kun se poikkeaa, lukija käsittelee tiedostoa vanhempana HotXLS-tiedostona ja rakentaa kierto-vasemmalle-2-taulukon uudelleen. Excelin kirjoittamat tiedostot kantavat aina johdettua avainta, joten ne kulkevat aina spesifikaation polkua

Testi on heuristiikka, jolla on tarkka epäonnistumisaste. Vanha tiedosto, jonka satunnainen avain sattui olemaan yhtä suuri kuin johdettu avain, luettaisiin väärällä taulukolla, ja sen todennäköisyys on yksi 65 536:sta. Varapolku kattaa vain taulukon kierron; indeksisääntöä ei vaihdeta, joten sen pelastamat tiedostot ovat v2.384.47:n ja v2.384.53:n välissä kirjoitetut. Jos sinulla on yhä BIFF5 XOR -tiedostoja kyseiseltä aikaväliltä, avaa ne nykyisellä HotXLS:llä ja tallenna ne uudelleen, jotta saat tiedoston, jonka Excel hyväksyy

Kaksi salasanayksityiskohtaa koskee jokaista tiedostoa, vanhaa tai uutta:

  • Pituus. CreateXorKey_Method1 lukee vain ensimmäiset 15 salasanatavua, mikä on spesifikaation raja. HotXLS soveltaa kyseistä kattoa avaimeen ja pitää verifierin ja taulukon niissä tavanomaisissa koko pituuden ja 16 tavun säännöissä, yhdenmukaisesti molemmin puolin. Excel itse kieltäytyy yli 15 merkkiä pitkistä salasanoista tälle muodolle, joten käsittele lukua 15 todellisena maksimina
  • Merkistö. HotXLS muuntaa salasanan tavuiksi järjestelmän ANSI-koodisivun kautta. Spesifikaatio kuvaa kunkin UTF-16-merkin matalan tavun ottamista, mikä täsmää ASCII:lle. Ilman Excel-näytteitä, jotka on suojattu ei-ASCII-salasanalla, ei ole totuusarvoa lopuille, joten pidä kiinni ASCII-salasanoista XOR-tiedostoissa

Lukupuolella TXLSWorkbook.OnPassword antaa sinun kysyä salasanaa, kun Open kohtaa FILEPASS-tietueen. Tapahtuma on TXLSPasswordEvent, jossa on var PassWord: WideString ja var Retry: Boolean; aseta Retry arvoon True yrittääksesi uudelleen, enintään kolme yritystä:

procedure TImportForm.WorkbookPassword(Sender: TObject;
  var PassWord: WideString; var Retry: Boolean);
var
  S: string;
begin
  S := '';
  Retry := InputQuery('Protected workbook', 'Password:', S);
  PassWord := S;
end;

procedure TImportForm.ImportLegacyFile(const FileName: string);
var
  Wb: IXLSWorkbook;
  Rc: Integer;
begin
  Wb := TXLSWorkbook.Create;
  Wb.OnPassword := WorkbookPassword;
  Rc := Wb.Open(FileName);
  // -1003: salasana vaaditaan mutta ei annettu; -1005: väärä salasana
  if Rc <> 1 then
    raise Exception.CreateFmt('Cannot open %s (code %d)', [FileName, Rc]);
  ShowMessage(VarToStr(Wb.Sheets[1].Range['A1', 'A1'].Value));
end;

Jos tunnet salasanan jo valmiiksi, Open(FileName, APassWord) ohittaa tapahtuman kokonaan

Onko XOR-obfuskaatio riittävän turvallinen mihinkään?

BIFF XOR -obfuskaatio ei ole salausta eikä suojaa mitään motivoitunutta lukijaa vastaan. Salasantarkistus on 16-bittinen verifier, avain on 16 bittiä, ja 16-tavuinen taulukko toistuu koko streamin yli, joten ennakoitavat BIFF-tietueiden sisällöt paljastavat taulukon tavut ilman mitään salasanaa. HotXLS kirjoittaa XOR:in vain siksi, että Excel 5.0/95 -tiedostoilla ei ole muuta vaihtoehtoa, ja syy tuottaa tällaisia tiedostoja tänään on legacy-kuluttaja, joka ei osaa lukea mitään uudempaa

Klassinen moottori valitsee skeeman TXLSWorkbook.EncryptionTypen kautta, ja yhdistelmä tallennusmuodon kanssa tarkistetaan tiukasti:

  • xletAuto (oletus) kirjoittaa RC4 CryptoAPI:n muodolle xlExcel97 ja XOR:n muodolle xlExcel5, vastaavasti kuin Excel itse kirjoitti kullekin muodolle
  • xletXor kelpaa vain BIFF5:lle; muodolla xlExcel97 tallennus nostaa poikkeuksen hiljaisen paluun sijaan
  • xletRC4 ja xletRC4CryptoAPI ovat vain BIFF8:aa, ja niiden pyytäminen BIFF5-tallennuksessa nostaa myös poikkeuksen

RC4 on myös vanhentunut, ja sen yhteentoimivuuden yksityiskohdat on käsitelty artikkelissa miksi Excel hylkää salatun työkirjan oikealla salasanalla. Jos vastaanottaja osaa lukea XLSX:ää, käytä sen sijaan XLSX-moottoria: TXLSXWorkbook.SaveAsEncryptedAgile kirjoittaa Agile Encryptionin (SHA-512-salasanahash 100 000 iteraation spin countilla ja AES-256-CBC), muodon, jonka Excel 2010 ja uudemmat kirjoittavat oletuksena, kun taas SaveAsEncrypted kirjoittaa vanhemman AES-128 Standard Encryptionin. Kahden väliset kompromissit ovat artikkelissa XLSX-tiedostojen salaus AES:llä Delphissä, ja lukupuoli on käsitelty artikkelissa Agile-salattujen Excel-tiedostojen lukeminen HotXLS:llä

Pikaopas: BIFF XOR -obfuskaatio, jonka Excel 16 hyväksyy

  • FILEPASS ($002F) seuraa globals-BOF:ia; BIFF5:ssä sen runko on 4 tavua: avain, sitten verifier
  • Avain = CreateXorKey_Method1(password) kohdan [MS-OFFCRYPTO] §2.3.7.2 mukaan, ei koskaan satunnainen; salasanalle secret se on $014D
  • Taulukko = salasanatavut + pad, XOR matala avaintavu parillisissa paikoissa ja korkea avaintavu parittomissa paikoissa, sitten XorRor (kierto oikealle 1)
  • Salaa tavu: kierto vasemmalle 5, sitten XOR; pura: XOR, sitten kierto oikealle 5 (§2.3.7.3)
  • XorArrayIndex = (tavun streamin siirtymä + tietuedatan pituus) mod 16; otsikot ja selvätekstiset etuliitteet lasketaan siirtymään
  • BOUNDSHEET pitää ensimmäiset 4 tavuaan selvätekstinä; BOF, FILEPASS ja INTERFACEHDR pysyvät kokonaan selvätekstinä
  • Salasanat: ASCII, enintään 15 merkkiä
  • HotXLS: indeksi korjattu versiossa v2.384.47, avain ja XorRor korjattu versiossa v2.384.54, vanhemmat HotXLS:n XOR-tiedostot havaitaan avainristiriidasta
  • Tositoimensuojaan käytä vähintään BIFF8 RC4 CryptoAPI:a tai XLSX Agile Encryptionia

HotXLS hoitaa BIFF5- ja BIFF8-salasanasuojaukset, XLSX:n Standard- ja Agile Encryptionin sekä lukupuolen salasanacallbackin yhdestä Delphi- ja C++Builder-kirjastosta, ja yllä olevat yhteentoimivuuden yksityiskohdat on hoidettu puolestasi. Tutustu HotXLS Delphi -laskentataulukkokomponenttiin saadaksesi versiot, alustat ja kokeilulatauksen