ProHoster > وبلاگ > اداره > معکوس کردن و هک کردن درایو HDD خارجی خود رمزگذاری شده Aigo. قسمت 2: برداشتن زباله از Cypress PSoC
معکوس کردن و هک کردن درایو HDD خارجی خود رمزگذاری شده Aigo. قسمت 2: برداشتن زباله از Cypress PSoC
این قسمت دوم و پایانی مقاله در مورد هک درایوهای خود رمزنگاری خارجی است. به شما یادآوری می کنم که اخیراً یکی از همکاران یک هارد دیسک Patriot (Aigo) SK8671 برای من آورده است و من تصمیم گرفتم آن را معکوس کنم و اکنون آنچه را که از آن به دست آمده را به اشتراک می گذارم. قبل از خواندن ادامه مطلب حتما بخوانید قسمت اول مقالات
4. ما شروع به برداشتن زباله از درایو فلش داخلی PSoC می کنیم
بنابراین، همه چیز نشان می دهد (همانطور که در [بخش اول]() مشخص کردیم) که کد پین در اعماق فلش PSoC ذخیره می شود. بنابراین، ما باید این عمق فلاش را بخوانیم. جلوی کارهای ضروری:
کنترل "ارتباط" با میکروکنترلر را در دست بگیرید.
راهی برای بررسی اینکه آیا این "ارتباطات" از خواندن از بیرون محافظت می شود پیدا کنید.
راهی برای دور زدن حفاظت پیدا کنید.
دو مکان وجود دارد که منطقی است به دنبال یک کد پین معتبر بگردید:
فلش مموری داخلی؛
SRAM، جایی که کد پین را می توان برای مقایسه آن با پین کد وارد شده توسط کاربر ذخیره کرد.
با نگاهی به آینده، متذکر می شوم که پس از معکوس کردن قابلیت های غیرمستند پروتکل ISSP، هنوز هم توانستم فلش درایو داخلی PSoC را - با دور زدن سیستم امنیتی آن با استفاده از یک حمله سخت افزاری به نام "ردیابی بوت سرد" - یک کمپرس کنم. این به من اجازه داد که مستقیماً کد پین واقعی را حذف کنم.
$ ./psoc.py
syncing: KO OK
[...]
PIN: 1 2 3 4 5 6 7 8 9
"ارتباط" با یک میکروکنترلر می تواند به معنای متفاوت باشد: از "فروشنده به فروشنده" تا تعامل با استفاده از یک پروتکل سریال (به عنوان مثال، ICSP برای PIC Microchip).
Cypress پروتکل اختصاصی خود را برای این کار دارد که ISSP (پروتکل برنامه نویسی سریال درون سیستمی) نامیده می شود که تا حدی در مشخصات فنی. پتنت US7185162 اطلاعاتی هم می دهد همچنین یک معادل OpenSource به نام HSSP وجود دارد (کمی بعد از آن استفاده خواهیم کرد). ISSP به شرح زیر عمل می کند:
راه اندازی مجدد PSoC؛
خروجی شماره جادویی به پین داده سریال این PSoC. برای ورود به حالت برنامه نویسی خارجی؛
دستورات را ارسال کنید، که رشته های بیتی بلندی هستند که "بردار" نامیده می شوند.
مستندات ISSP این بردارها را فقط برای تعداد کمی از دستورات تعریف می کند:
Initialize-1
Initialize-2
Initialize-3 (گزینه های 3 ولت و 5 ولت)
ID-SETUP
READ-ID-WORD
SET-BLOCK-NUM: 10011111010dddddddd111، جایی که dddddddd=block #
پاک کردن انبوه
PROGRAM-BLOCK
تأیید تنظیم
READ-BYTE: 10110aaaaaaZDDDDDDDDDZ1، جایی که DDDDDDDD = داده خارج می شود، aaaaaa = آدرس (6 بیت)
WRITE-BYTE: 10010aaaaaaddddddd111، جایی که dddddddd = داده در آن، aaaaaa = آدرس (6 بیت)
امن
CHECKSUM-SETUP
READ-CHECKSUM: 10111111001ZDDDDDDDDDZ110111111000ZDDDDDDDDZ1، جایی که DDDDDDDDDDDDDDDDDD = داده خارج شده: جمع کنترلی دستگاه
طول همه بردارها یکسان است: 22 بیت. اسناد HSSP دارای اطلاعات اضافی در مورد ISSP است: "بردار ISSP چیزی بیش از یک دنباله بیت نیست که مجموعه ای از دستورالعمل ها را نشان می دهد."
5.2. ابهام زدایی بردارها
بیایید بفهمیم اینجا چه خبر است. در ابتدا، من فرض میکردم که همین بردارها نسخههای خام دستورالعملهای M8C هستند، اما پس از بررسی این فرضیه، متوجه شدم که کدهای عملیاتی با هم مطابقت ندارند.
سپس وکتور بالا را در گوگل جستجو کردم و به آن برخوردم اینجا است مطالعهای که در آن نویسنده، اگرچه وارد جزئیات نمیشود، نکات مفیدی را ارائه میکند: «هر دستورالعمل با سه بیت شروع میشود که با یکی از چهار یادگاری مطابقت دارد (خواندن از RAM، نوشتن در RAM، خواندن ثبت نام، ثبت ثبت نام). سپس 8 بیت آدرس، به دنبال آن 8 بیت داده (خواندن یا نوشتن) و در نهایت سه بیت توقف وجود دارد.
سپس من توانستم اطلاعات بسیار مفیدی را از بخش Supervisory ROM (SROM) جمع آوری کنم. راهنمای فنی. SROM یک رام سخت کدگذاری شده در PSoC است که توابع کاربردی (به روشی مشابه Syscall) را برای کد برنامه در حال اجرا در فضای کاربر فراهم می کند:
00h:SWBootReset
ساعت 01: ReadBlock
ساعت 02: WriteBlock
03h: EraseBlock
06h: TableRead
07h: CheckSum
08h: Calibrate0
09h: Calibrate1
با مقایسه نام های برداری با توابع SROM، می توانیم عملیات مختلف پشتیبانی شده توسط این پروتکل را به پارامترهای SROM مورد انتظار نگاشت کنیم. به لطف این، ما می توانیم سه بیت اول بردارهای ISSP را رمزگشایی کنیم:
100 => "wrem"
101 => "rdmem"
110 => "wrreg"
111 => "rdreg"
با این حال، درک کامل فرآیندهای روی تراشه تنها از طریق ارتباط مستقیم با PSoC بدست می آید.
5.3. ارتباط با PSoC
از آنجایی که دیرک پتراتسکی قبلاً این کار را کرده است منتقل شده است کد HSSP Cypress در آردوینو، من از Arduino Uno برای اتصال به کانکتور ISSP برد کیبورد استفاده کردم.
لطفا توجه داشته باشید که در طول تحقیق من، کد دیرک را کمی تغییر دادم. می توانید اصلاحات من را در GitHub پیدا کنید: اینجا و اسکریپت پایتون مربوطه برای برقراری ارتباط با آردوینو، در مخزن من cypress_psoc_tools.
بنابراین، با استفاده از آردوینو، ابتدا فقط از بردارهای "رسمی" برای "ارتباطات" استفاده کردم. با دستور VERIFY سعی کردم رام داخلی رو بخونم. همانطور که انتظار می رفت، من نتوانستم این کار را انجام دهم. احتمالاً به این دلیل است که بیت های حفاظت خواندن در داخل فلش درایو فعال می شوند.
سپس چند بردار ساده خودم را برای نوشتن و خواندن حافظه/رجیسترها ایجاد کردم. لطفاً توجه داشته باشید که ما می توانیم کل SROM را بخوانیم حتی اگر درایو فلش محافظت شده باشد!
5.4. شناسایی رجیسترهای روی تراشه
پس از نگاه کردن به بردارهای "جداسازی شده"، متوجه شدم که دستگاه از رجیسترهای غیرمستند (0xF8-0xFA) برای تعیین کدهای عملیاتی M8C استفاده می کند، که مستقیماً اجرا می شوند و حفاظت را دور می زنند. این به من اجازه داد تا اپکدهای مختلفی مانند "ADD"، "MOV A، X"، "PUSH" یا "JMP" را اجرا کنم. با تشکر از آنها (با بررسی عوارض جانبی آنها بر روی رجیسترها) من توانستم تشخیص دهم که کدام یک از رجیسترهای غیرمستند واقعاً رجیسترهای معمولی هستند (A، X، SP و PC).
در نتیجه، کد "disassembled" تولید شده توسط ابزار HSSP_disas.rb به این شکل است (برای وضوح نظرات را اضافه کردم):
در این مرحله می توانم با PSoC ارتباط برقرار کنم، اما هنوز اطلاعات قابل اعتمادی در مورد بیت های امنیتی فلش درایو ندارم. من از این واقعیت که Cypress هیچ وسیله ای را برای بررسی فعال بودن حفاظت در اختیار کاربر دستگاه قرار نمی دهد بسیار متعجب شدم. بیشتر در گوگل جستجو کردم تا در نهایت بفهمم که کد HSSP ارائه شده توسط Cypress پس از انتشار اصلاحات خود توسط دیرک به روز شده است. و همینطور! این بردار جدید ظاهر شده است:
با استفاده از این بردار (به read_security_data در psoc.py مراجعه کنید)، همه بیتهای امنیتی در SRAM را با ابعاد 0x80 دریافت میکنیم، جایی که در هر بلوک محافظت شده دو بیت وجود دارد.
نتیجه ناامید کننده است: همه چیز در حالت "غیرفعال کردن خواندن و نوشتن خارجی" محافظت می شود. بنابراین، نه تنها نمیتوانیم چیزی از درایو فلش بخوانیم، بلکه نمیتوانیم چیزی بنویسیم (مثلاً برای نصب یک دامپر رام در آنجا). و تنها راه غیرفعال کردن حفاظت پاک کردن کامل تراشه است. 🙁
6. اولین حمله (شکست خورده): ROMX
با این حال، میتوانیم ترفند زیر را امتحان کنیم: از آنجایی که ما توانایی اجرای کدهای عملیاتی دلخواه را داریم، چرا ROMX را که برای خواندن حافظه فلش استفاده میشود، اجرا نکنیم؟ این رویکرد شانس موفقیت خوبی دارد. زیرا تابع ReadBlock که داده ها را از SROM می خواند (که توسط بردارها استفاده می شود) بررسی می کند که آیا از ISSP فراخوانی شده است یا خیر. با این حال، کد رمز ROMX ممکن است چنین بررسی را نداشته باشد. بنابراین کد پایتون (پس از اضافه کردن چند کلاس کمکی به کد آردوینو) در اینجا آمده است:
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 به یک بافر موقت هدایت می شود.
این اساساً تابع SROM را 0x07 مینامد، همانطور که در مستندات ارائه شده است.
این تابع بررسی مجموع تایید. این یک جمع 16 بیتی تعداد بلوک های مشخص شده توسط کاربر در یک بانک فلش را محاسبه می کند که از صفر شروع می شود. پارامتر BLOCKID برای ارسال تعداد بلوک هایی که هنگام محاسبه چک جمع استفاده می شود استفاده می شود. مقدار "1" فقط جمع چک را برای بلوک صفر محاسبه می کند. در حالیکه "0" باعث می شود که جمع کل 256 بلوک فلش بانک محاسبه شود. جمع چک 16 بیتی از طریق KEY1 و KEY2 برگردانده می شود. پارامتر KEY1 8 بیت مرتبه پایین از چک جمع را ذخیره می کند و پارامتر KEY2 8 بیت مرتبه بالا را ذخیره می کند. برای دستگاه هایی با چندین بانک فلش، تابع چک جمع برای هر یک به طور جداگانه فراخوانی می شود. شماره بانکی که با آن کار خواهد کرد توسط رجیستر FLS_PR1 (با تنظیم بیت مربوط به فلش بانک مورد نظر در آن) تنظیم می شود.
توجه داشته باشید که این یک جمعبندی ساده است: بایتها به سادگی یکی پس از دیگری اضافه میشوند. بدون CRC عجیب و غریب. علاوه بر این، با دانستن اینکه هسته M8C دارای مجموعه بسیار کوچکی از رجیسترها است، فرض کردم که هنگام محاسبه چکسوم، مقادیر میانی در همان متغیرها ثبت میشوند که در نهایت به خروجی میروند: KEY1 (0xF8) / KEY2 ( 0xF9).
بنابراین در تئوری حمله من به این صورت است:
ما از طریق ISSP متصل می شویم.
محاسبه جمع کنترل را با استفاده از بردار CHECKSUM-SETUP شروع می کنیم.
ما پردازنده را پس از یک زمان مشخص T راه اندازی مجدد می کنیم.
RAM را می خوانیم تا جمع چک فعلی C را بدست آوریم.
مراحل 3 و 4 را تکرار کنید و هر بار مقدار T را کمی افزایش دهید.
ما اطلاعات را از یک درایو فلش با کم کردن جمع چک قبلی C از فعلی بازیابی می کنیم.
با این حال، یک مشکل وجود دارد: بردار Initialize-1 که باید پس از راه اندازی مجدد ارسال کنیم، KEY1 و KEY2 را بازنویسی می کند:
این کد با فراخوانی Calibrate1 (عملکرد SROM 9) چک جمع ارزشمند ما را بازنویسی می کند... شاید فقط بتوانیم شماره جادویی (از ابتدای کد بالا) را برای وارد شدن به حالت برنامه نویسی بفرستیم و سپس SRAM را بخوانیم؟ و بله، کار می کند! کد آردوینو که این حمله را پیاده سازی می کند بسیار ساده است:
برای مدت زمان مشخصی صبر کنید؛ با در نظر گرفتن مشکلات زیر:
زمان زیادی را هدر دادم تا اینکه فهمیدم چه نتیجه ای دارد تاخیر میکرو ثانیه فقط با تاخیرهای بیش از 16383 میکروثانیه به درستی کار می کند.
و سپس دوباره همان زمان را از بین بردم تا اینکه متوجه شدم delayMicroseconds، اگر 0 به عنوان ورودی به آن ارسال شود، کاملاً اشتباه کار می کند!
PSoC را مجدداً در حالت برنامه نویسی راه اندازی کنید (ما فقط شماره جادویی را بدون ارسال بردارهای اولیه ارسال می کنیم).
کد نهایی در پایتون:
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))
به طور خلاصه، آنچه این کد انجام می دهد:
PSoC را مجددا راه اندازی می کند (و یک عدد جادویی برای آن ارسال می کند).
بردارهای اولیه سازی کامل را ارسال می کند.
تابع Arduino Cmnd_STK_START_CSUM (0x85) را فراخوانی میکند، که در آن تأخیر در میکروثانیه به عنوان پارامتر ارسال میشود.
جمع کنترلی (0xF8 و 0xF9) و ثبات غیرمستند 0xF1 را می خواند.
این کد 10 بار در 1 میکروثانیه اجرا می شود. 0xF1 در اینجا گنجانده شده است زیرا تنها ثباتی بود که هنگام محاسبه چکسوم تغییر کرد. شاید این یک نوع متغیر موقتی باشد که توسط واحد منطق حسابی استفاده می شود. به هک زشتی که برای تنظیم مجدد آردوینو با استفاده از پیکوکام استفاده میکنم، توجه کنید، زمانی که آردوینو از نشان دادن علائم حیات خودداری میکند (نمیدانم چرا).
7.2. خواندن نتیجه
نتیجه اسکریپت پایتون به این شکل است (برای خوانایی ساده شده):
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
همانطور که گفته شد، ما یک مشکل داریم: از آنجایی که ما با یک چک جمع واقعی کار می کنیم، یک بایت تهی مقدار خوانده شده را تغییر نمی دهد. با این حال، از آنجایی که کل روش محاسبه (8192 بایت) 0,1478 ثانیه طول می کشد (با تغییرات جزئی در هر بار اجرا)، که معادل تقریباً 18,04 میکرو ثانیه در هر بایت است، می توانیم از این زمان برای بررسی مقدار checksum در زمان های مناسب استفاده کنیم. برای اولین اجرا، همه چیز به راحتی خوانده می شود، زیرا مدت زمان روش محاسباتی همیشه تقریباً یکسان است. با این حال، پایان این تخلیه دقت کمتری دارد زیرا "انحرافات زمان بندی جزئی" در هر اجرا جمع می شوند و قابل توجه می شوند:
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. پیدا کردن آدرس ذخیره کد پین
اکنون که میتوانیم چکسوم را در زمانهایی که نیاز داریم بخوانیم، میتوانیم به راحتی بررسی کنیم که چگونه و کجا تغییر میکند زمانی که:
کد پین را اشتباه وارد کنید؛
کد پین را تغییر دهید
ابتدا، برای یافتن آدرس ذخیره سازی تقریبی، پس از راه اندازی مجدد، یک جمع بندی چک را با افزایش 10 میلی ثانیه انجام دادم. سپس پین را اشتباه وارد کردم و همین کار را کردم.
نتیجه چندان خوشایند نبود، زیرا تغییرات زیادی وجود داشت. اما در نهایت توانستم تعیین کنم که چکسوم چیزی بین 120000 میکروثانیه تا 140000 میکروثانیه تاخیر تغییر کرده است. اما "پین کد" ای که من در آنجا نشان دادم کاملاً نادرست بود - به دلیل یک مصنوع از رویه delayMicroseconds که وقتی 0 به آن ارسال می شود کارهای عجیبی انجام می دهد.
سپس، پس از گذراندن تقریباً 3 ساعت، به یاد آوردم که فراخوانی سیستم SROM CheckSum یک آرگومان به عنوان ورودی دریافت می کند که تعداد بلوک ها را برای checksum مشخص می کند! که ما به راحتی میتوانیم آدرس ذخیرهسازی کد پین و شمارنده «تلاشهای نادرست» را با دقت حداکثر 64 بایت بومیسازی کنیم.
اجراهای اولیه من نتیجه زیر را به همراه داشت:
سپس پین کد را از "123456" به "1234567" تغییر دادم و دریافت کردم:
بنابراین به نظر می رسد پین کد و شمارنده تلاش های نادرست در بلوک شماره 126 ذخیره شده است.
7.5. برداشت کمپرسی از بلوک شماره 126
بلوک شماره 126 باید در جایی در حدود 125x64x18 = 144000μs، از شروع محاسبه جمع کنترلی، در دامپ کامل من قرار گیرد، و کاملاً قابل قبول به نظر می رسد. سپس، پس از الک دستی تعداد زیادی تخلیه نامعتبر (به دلیل تجمع "انحرافات زمان بندی جزئی")، در نهایت این بایت ها را دریافت کردم (با تاخیر 145527 میکرو ثانیه):
کاملا واضح است که پین کد به صورت رمزگذاری نشده ذخیره می شود! این مقادیر البته در کدهای ASCII نوشته نشده اند، اما همانطور که مشخص است، خوانش های گرفته شده از صفحه کلید خازنی را منعکس می کنند.
در نهایت، چند آزمایش دیگر را برای یافتن محل ذخیره شمارشگر تلاش بد انجام دادم. نتیجه این است:
0xFF - به معنای "15 تلاش" است و با هر تلاش ناموفق کاهش می یابد.
7.6. بازیابی کد پین
این کد زشت من است که موارد بالا را کنار هم قرار می دهد:
لطفاً توجه داشته باشید که مقادیر تاخیری که من استفاده کردم احتمالاً مربوط به یک PSoC خاص است - همان چیزی که من استفاده کردم.
8. بعدی چیه؟
بنابراین، بیایید در سمت PSoC، در زمینه درایو Aigo خود خلاصه کنیم:
ما می توانیم SRAM را بخوانیم حتی اگر محافظت شده خوانده شود.
ما میتوانیم با استفاده از حمله ردیابی بوت سرد و خواندن مستقیم کد پین، از محافظت ضد ضربه زدن دور بزنیم.
با این حال، حمله ما به دلیل مشکلات همگام سازی دارای نقص هایی است. می تواند به شرح زیر بهبود یابد:
یک ابزار برای رمزگشایی صحیح داده های خروجی که در نتیجه حمله "ردیابی بوت سرد" به دست می آید بنویسید.
از ابزار FPGA برای ایجاد تاخیرهای زمانی دقیق تر استفاده کنید (یا از تایمرهای سخت افزاری آردوینو استفاده کنید).
حمله دیگری را امتحان کنید: یک کد پین عمداً نادرست را وارد کنید، RAM را مجدد راه اندازی کنید و آن را خالی کنید، به این امید که کد پین صحیح برای مقایسه در RAM ذخیره شود. با این حال، انجام این کار در آردوینو چندان آسان نیست، زیرا سطح سیگنال آردوینو 5 ولت است، در حالی که بردی که ما بررسی می کنیم با سیگنال های 3,3 ولت کار می کند.
یکی از چیزهای جالبی که می توان امتحان کرد، بازی با سطح ولتاژ برای دور زدن حفاظت خواندن است. اگر این روش کار می کرد، ما می توانستیم به جای تکیه بر خواندن یک جمع بندی با تاخیرهای زمان بندی نادقیق، داده های کاملا دقیق را از درایو فلش دریافت کنیم.
از آنجایی که SROM احتمالا بیتهای محافظ را از طریق فراخوانی سیستم ReadBlock میخواند، میتوانیم همان کاری را انجام دهیم که شرح داده شده در وبلاگ دیمیتری ندوسپاسوف - اجرای مجدد حمله کریس گرلینسکی که در کنفرانس اعلام شد "REcon Brussels 2017".
یکی دیگر از کارهای جالبی که میتوان انجام داد این است که کیس را از تراشه جدا کنیم: حذف SRAM، شناسایی تماسها و آسیبپذیریهای غیرمستند سیستم.
9. نتیجه گیری
بنابراین، حفاظت از این درایو چیزهای زیادی را باقی میگذارد، زیرا از یک میکروکنترلر معمولی (نه «سختشده») برای ذخیره کد پین استفاده میکند... بهعلاوه، من (هنوز) به نحوه انجام کارها با دادهها نگاه نکردهام. رمزگذاری در این دستگاه!
چه چیزی را می توانید برای Aigo توصیه کنید؟ پس از تجزیه و تحلیل چند مدل از درایوهای HDD رمزگذاری شده، در سال 2015 ساختم ارائه در SyScan، که در آن او مشکلات امنیتی چندین درایو HDD خارجی را بررسی کرد و توصیه هایی را در مورد آنچه که می توان در آنها بهبود داد، ارائه کرد. 🙂
من دو آخر هفته و چندین شب را صرف این تحقیق کردم. در کل حدود 40 ساعت. شمارش از همان ابتدا (زمانی که دیسک را باز کردم) تا انتها (دامپ کد پین). همان 40 ساعت شامل زمانی است که برای نوشتن این مقاله صرف کردم. سفر بسیار هیجان انگیزی بود.