Prosesor X86 Rakitan Mikrokode di Belakang

Kami tidak mempercayai perangkat lunak untuk waktu yang lama, dan oleh karena itu kami melakukan audit, melakukan rekayasa balik, menjalankannya dalam mode langkah-demi-langkah, menjalankannya di kotak pasir. Bagaimana dengan prosesor tempat perangkat lunak kami berjalan? - Kami dengan buta dan sepenuh hati mempercayai sepotong kecil silikon ini. Namun, perangkat keras modern memiliki masalah yang sama dengan perangkat lunak: fungsi rahasia tidak berdokumen, bug, kerentanan, malware, trojan, rootkit, backdoors.



ISA (Instruction Set Architecture) x86 adalah salah satu "arsitektur set instruksi" yang paling lama berubah dalam sejarah. Dimulai dengan desain 8086 yang dikembangkan pada tahun 1976, ISA terus mengalami perubahan dan pembaruan; sambil mempertahankan kompatibilitas mundur dan dukungan untuk spesifikasi asli. Lebih dari 40 tahun tumbuh, arsitektur ISA telah tumbuh dan terus tumbuh dengan banyak mode dan set instruksi baru, yang masing-masing menambahkan lapisan baru ke desain sebelumnya, yang sudah kelebihan beban. Karena kebijakan kompatibilitas penuh, prosesor x86 modern bahkan berisi instruksi dan mode yang sudah sepenuhnya dilupakan. Sebagai hasilnya, kami memiliki arsitektur prosesor, yang merupakan labirin rumit dari teknologi baru dan antik. Lingkungan yang sangat kompleks - menyebabkan banyak masalah dengan keamanan siber prosesor. Oleh karena itu, prosesor x86 tidak dapat mengklaim sebagai akar tepercaya infrastruktur cyber kritis.


Apakah Anda masih mempercayai prosesor Anda?


Keamanan program dan sistem operasi - didasarkan pada keamanan perangkat keras yang digunakan. Sebagai aturan, pengembang perangkat lunak tidak memperhitungkan fakta bahwa perangkat keras tempat perangkat lunak mereka digunakan dapat tidak dipercaya, berbahaya. Ketika perangkat keras berperilaku keliru (baik sengaja atau tidak), mekanisme keamanan perangkat lunak menjadi sama sekali tidak berharga. Selama bertahun-tahun, berbagai model prosesor aman telah ditawarkan: Intel SGX, AMD Pacifica, dll. Meskipun demikian, keteraturan yang patut ditiru dengan informasi yang dipublikasikan tentang kegagalan kritis (dari yang baru-baru ini, misalnya Meltdown dan Specter) dan mendeteksi fungsi "debugging" yang tidak didokumentasikan - mengarah ke pemikiran bahwa keyakinan sepenuh hati kami pada prosesor tidak berdasar.


Prosesor x86 modern adalah jalinan yang sangat rumit dan rumit dari teknologi terbaru dan antik. 8086 memiliki 29 ribu transistor, Pentium 3 juta, Broadwell 3,2 miliar, Cannonlake lebih dari 10 miliar.



Dengan begitu banyak transistor, tidak mengherankan bahwa prosesor x86 modern penuh dengan instruksi tidak berdokumen dan kerentanan perangkat keras. Di antara yang tidak terdokumentasi, yang ditemukan hampir secara tidak sengaja, instruksi: ICEBP (0xF1), LOADALL (0x0F07), apicall (0x0FFFF0) [1], yang memungkinkan prosesor tidak terkunci untuk akses tidak sah ke area memori yang dilindungi.


Adapun banyak kerentanan perangkat keras prosesor (lihat dua gambar di bawah), mereka memungkinkan penyerang cyber untuk meningkatkan hak istimewa [3], mengekstrak kunci kriptografi [4], membuat instruksi assembler baru [2], mengubah fungsi instruksi assembler yang sudah ada [2] , pasang kait pada instruksi assembler [2], kendalikan "virtualisasi akselerasi perangkat keras" [7], campur tangan dalam "perhitungan kriptografi atom" [7], dan, akhirnya, manis, masuk ke "mode dewa": ive diri hardware yang sah Intel ME backdoor (yang memungkinkan Anda untuk menerima akses remote bahkan komputer dimatikan). [8] Dan semua ini - tanpa meninggalkan jejak digital.




Prosesor modern lebih banyak perangkat lunak daripada perangkat keras


Sebenarnya, prosesor modern bahkan tidak bisa disebut "perangkat keras" dalam arti penuh kata. Karena fungsi mereka yang paling kritis (termasuk ISA) disediakan oleh flashing mikrokode. Awalnya, mikrokode terutama bertanggung jawab untuk mengendalikan decoding dan eksekusi instruksi assembler kompleks: operasi floating-point, primitif MMX, line handler dengan awalan REP, dll. Namun, seiring waktu, semakin banyak tanggung jawab yang diberikan pada mikrokode untuk memproses operasi di dalam prosesor. Misalnya, ekstensi modern prosesor Intel, seperti AVX (Advanced Vector Extensions) dan VT-d (virtualisasi perangkat keras) diimplementasikan pada mikrokode.


Selain itu, saat ini mikrokode bertanggung jawab, antara lain, untuk menjaga keadaan prosesor, untuk mengelola cache, dan juga untuk mengelola penghematan daya. Untuk menghemat energi, mikrokode memiliki mekanisme interupsi yang memproses status daya: C-state (tingkat tidur hemat energi: dari state aktif ke sleep dalam) dan P-state (kombinasi tegangan dan frekuensi yang berbeda). Jadi, misalnya, mikrokode bertanggung jawab untuk mengatur ulang cache L2 saat memasuki negara C4, serta saat keluar.


Mengapa produsen prosesor menggunakan mikrokode?


Produsen prosesor x86 menggunakan mikrokode untuk mendekomposisi instruksi perakitan yang rumit (yang dapat mencapai 15 byte) menjadi rantai instruksi mikro sederhana, untuk menyederhanakan arsitektur perangkat keras dan memfasilitasi diagnostik. Faktanya, mikrokode adalah interpreter antara arsitektur CISC eksternal (terlihat oleh pengguna) dan arsitektur RISC internal (perangkat keras).


Jika kesalahan terdeteksi dalam arsitektur CISC (terutama di ISA), pabrikan menerbitkan pembaruan mikrokode yang dapat diunduh ke prosesor melalui BIOS / UEFI dari motherboard atau melalui sistem operasi (selama proses booting). Berkat sistem pembaruan yang didasarkan pada mikrokode, produsen prosesor memberi diri mereka fleksibilitas dan pengurangan biaya - sembari memperbaiki kesalahan pada peralatan mereka. Kesalahan sensasional dengan fdiv, yang sangat merobohkan prosesor Intel Pentium pada tahun 1994, membuat fakta bahwa kesalahan perangkat keras teknologi tinggi rentan seperti perangkat lunak membuatnya semakin jelas. Kejadian ini telah membuat produsen lebih tertarik pada arsitektur prosesor berbasis mikrokode. Oleh karena itu, Intel dan AMD mulai membangun prosesor mereka menggunakan teknologi mikrokode. Intel - dimulai dengan Pentium Pro (P6), dirilis pada 1995. AMD - dimulai dengan K7, dirilis pada tahun 1999.


Segalanya rahasia menjadi jelas


Terlepas dari kenyataan bahwa produsen prosesor berusaha menjaga arsitektur mikrokode dan mekanisme untuk memperbaruinya dalam kepercayaan yang paling ketat, musuh tidak tertidur. Potongan-potongan informasi yang terfragmentasi (terutama dari paten, seperti AMD RISC86 [5]) dan pembalikan bijaksana dari pembaruan BIOS resmi (seperti halnya dengan K8 [6]), secara bertahap menjelaskan rahasia mikrokode (lihat, misalnya, pada gambar di bawah ini β€œ Mekanisme pembaruan mikrokode prosesor AMD ”). Dan berkat evolusi konstan alat rekayasa terbalik (baik perangkat lunak dan perangkat keras) [2], teknik fuzzing yang menjanjikan [1] dan munculnya alat OpenSource seperti Microparse [9] dan Sandsifter [10] - penyerang cyber dapat mempelajari segala sesuatu tentang mikrokode yang diperlukan untuk harus menulis malware microcode di atasnya.



Jadi, misalnya, dalam [2] sebagai "Halo dunia!" (langkah pertama untuk trojanizing the microcode) "micro hook" (program microcode yang memotong instruksi assembler) dikembangkan, yang menghitung berapa kali prosesor mengakses perintah div. Microhook ini adalah injeksi ke handler dari instruksi assembler div.



Ibid [2] menyajikan microhook yang lebih maju - yang duduk dengan tenang dalam instruksi assembler dari div ebx, tidak memberikan kehadiran, dan diaktifkan hanya ketika kondisi tertentu terpenuhi saat mengakses ebx div: register ebx berisi nilai B, dan register eax berisi nilai A. Saat diaktifkan, microhook ini meningkatkan nilai register eip (penunjuk instruksi saat ini) satu per satu. Akibatnya, pelaksanaan program (yang memiliki keberanian untuk merujuk pada instruksi div ebx) berlanjut dengan offset: bukan dari byte pertama dari perintah yang mengikuti div ebx, tetapi dari byte kedua. Jika nilai-nilai lain ditentukan dalam register eax dan ebx, maka div ebx berfungsi seperti biasa. Apa nilai praktis dalam hal ini? Sebagai contoh, untuk secara diam-diam mengaktifkan rangkaian instruksi assembler tersembunyi saat menggunakan teknik kebingungan dengan β€œinstruksi yang tumpang tindih” [11].



Dua contoh ini menunjukkan bagaimana instruksi assembler yang sah dapat digunakan untuk menyembunyikan kode Trojan sewenang-wenang di dalamnya.


Pada saat yang sama, seorang penyerang cyber dapat mengaktifkan muatan jahatnya - termasuk jarak jauh. Misalnya, ketika kondisi yang diperlukan untuk aktivasi terpenuhi pada halaman web yang dikendalikan oleh penyerang. Hal ini dimungkinkan berkat kompiler Just-in-Time (JIT) dan Ahead-of-Time (AOT) yang dibangun dalam browser web modern. Kompiler ini memungkinkan Anda untuk memancarkan aliran instruksi assembler yang telah ditentukan sebelumnya untuk kode mesin - bahkan jika Anda menulis program secara eksklusif dalam JavaScript tingkat tinggi (lihat daftar terakhir, tepat di atas).


Daftar pustaka
  1. Christopher Domas . Melanggar ISA x86 // DEFCON 25.07.2017.
  2. Philipp Koppe . Teknik Reverse x86 Mikrokode Prosesor // Proses dari Simposium Keamanan USENIX ke-26. 2017. hlm. 1163-1180.
  3. Matthew Hicks . SPECS: Mekanisme Runtime Ringan untuk Melindungi Perangkat Lunak dari Bug Prosesor Keamanan-kritis // Proses Konferensi Internasional ke-28 tentang Dukungan Arsitektur untuk Bahasa Pemrograman dan Sistem Operasi (ASPLOS). 2015. hal. 517-529.
  4. Adi Shamir . Serangan Bug // Prosiding konferensi Tahunan ke-28 tentang Kriptografi: Kemajuan dalam Kriptologi. 2008. hal. 221–240.
  5. John Favor . Set Instruksi RISC86 // Paten AS 6336178. 2002.
  6. Opteron Exposed: Rekayasa Balik Pembaruan Mikrokode AMD K8 . 2004
  7. Saming Chen . Analisis Keamanan Mikrokode Prosesor x86 .2014.
  8. Simpanse Catalin . Malware Menggunakan Fitur Intel CPU yang Tidak Jelas untuk Mencuri Data dan Menghindari Firewall . 2017
  9. Daming Chen . Microparse: Microcode parser untuk prosesor AMD, Intel, dan VIA // GitHub. 2014
  10. Sandsifter: Fuzzer prosesor x86 // GitHib. 2017
  11. Karev V.M. Cara menulis program assembler dengan instruksi yang tumpang tindih (teknik lain untuk mengaburkan kode byte) // Habrahabr. 2018. URL: (Tanggal akses: 25 Oktober 2018).

Source: https://habr.com/ru/post/id427757/


All Articles