Apa sebenarnya yang dilakukan ini? Saya tidak mengerti bagaimana Anda dapat mengakses memori dasar dengan ini ... tampaknya agak aneh. Apakah ini aman?
dd if=/dev/urandom of=/dev/mem
Apa sebenarnya yang dilakukan ini? Saya tidak mengerti bagaimana Anda dapat mengakses memori dasar dengan ini ... tampaknya agak aneh. Apakah ini aman?
dd if=/dev/urandom of=/dev/mem
Jawaban:
Sebenarnya, pada sebagian besar platform, itu hanya gagal dengan kesalahan, tetapi itu tergantung pada arsitektur perangkat keras. Jelas tidak ada jaminan bahwa ini tidak berbahaya kecuali jika Anda menjalankan perintah sebagai pengguna yang tidak memiliki hak. Dengan pengguna yang tidak memiliki hak istimewa, perintah ini sama sekali tidak berbahaya karena Anda tidak dapat membuka /dev/mem
.
Saat Anda menjalankan perintah sebagai root, Anda seharusnya tahu apa yang Anda lakukan. Kernel kadang - kadang akan mencegah Anda dari melakukan sesuatu yang berbahaya, tetapi tidak selalu. /dev/mem
adalah salah satu hal yang berpotensi berbahaya di mana Anda benar-benar seharusnya tahu apa yang Anda lakukan.
Saya akan membahas bagaimana cara menulis /dev/mem
bekerja di Linux. Prinsip umum akan sama pada Unix lain, tetapi hal-hal seperti opsi kernel sama sekali berbeda.
Apa yang terjadi ketika suatu proses membaca atau menulis ke file perangkat hingga kernel. Akses ke file perangkat menjalankan beberapa kode dalam driver yang menangani file perangkat ini. Misalnya, menulis untuk /dev/mem
memanggil fungsi write_mem
dalamdrivers/char/mem.c
. Fungsi ini mengambil 4 argumen: struktur data yang mewakili file terbuka, pointer ke data yang akan ditulis, jumlah byte yang akan ditulis, dan posisi saat ini dalam file.
Perhatikan bahwa Anda hanya mendapatkan sejauh itu jika penelepon memiliki izin untuk membuka file di tempat pertama. File perangkat mematuhi izin file secara normal. Hak akses normal /dev/mem
yang crw-r-----
dimiliki oleh root:kmem
, jadi jika Anda mencoba untuk membukanya untuk menulis tanpa root, Anda hanya akan mendapatkan “ijin ditolak” (EACCESS). Tetapi jika Anda root (atau jika root telah mengubah izin file ini), pembukaan akan melalui dan kemudian Anda dapat mencoba menulis.
Kode dalam write_mem
fungsi membuat beberapa pemeriksaan kewarasan, tetapi pemeriksaan ini tidak cukup untuk melindungi terhadap segala sesuatu yang buruk. Hal pertama yang dilakukannya adalah mengonversi posisi file saat ini *ppos
ke alamat fisik. Jika itu gagal (dalam praktiknya, karena Anda berada di platform dengan alamat fisik 32-bit tetapi offset file 64-bit dan offset file lebih besar dari 2 ^ 32), penulisan gagal dengan EFBIG (file terlalu besar). Pemeriksaan berikutnya adalah apakah kisaran alamat fisik yang akan ditulis valid pada arsitektur prosesor khusus ini, dan ada hasil kegagalan pada EFAULT (alamat buruk).
Selanjutnya, pada Sparc dan m68k, bagian apa pun dari penulisan di halaman fisik pertama dilewati secara diam-diam.
Kami sekarang telah mencapai loop utama yang berulang pada data dalam blok yang dapat ditampung dalam satu halaman MMU .
/dev/mem
mengakses memori fisik, bukan memori virtual, tetapi instruksi prosesor untuk memuat dan menyimpan data dalam memori menggunakan alamat virtual, sehingga kode perlu mengatur untuk memetakan memori fisik di beberapa alamat virtual. Di Linux, tergantung pada arsitektur prosesor dan konfigurasi kernel, pemetaan ini ada secara permanen atau harus dibuat dengan cepat; itulah tugas xlate_dev_mem_ptr
(dan unxlate_dev_mem_ptr
membatalkan apa pun yang xlate_dev_mem_ptr
dilakukan). Kemudian fungsi copy_from_user
membaca dari buffer yang diteruskan kewrite
panggilan sistem dan hanya menulis ke alamat virtual di mana memori fisik saat ini dipetakan. Kode ini memancarkan instruksi penyimpanan memori normal, dan apa artinya ini tergantung pada perangkat keras.
Sebelum saya membahas bahwa penulisan ke alamat fisik tidak, saya akan membahas cek yang terjadi sebelum penulisan ini. Di dalam loop, fungsi ini page_is_allowed
memblokir akses ke alamat-alamat tertentu jika opsi konfigurasi kernel CONFIG_STRICT_DEVMEM
diaktifkan (yang merupakan kasus secara default): hanya alamat-alamat yang diizinkan oleh yang devmem_is_allowed
dapat dijangkau /dev/mem
, untuk yang lain penulisan gagal dengan EPERM (operasi tidak diizinkan). Deskripsi opsi ini menyatakan:
Jika opsi ini diaktifkan, dan IO_STRICT_DEVMEM = n, file / dev / mem hanya memungkinkan userspace mengakses ruang PCI dan kode BIOS dan wilayah data. Ini cukup untuk dosemu dan X dan semua pengguna umum / dev / mem.
Ini adalah deskripsi yang sangat x86-sentris. Bahkan, secara lebih umum, CONFIG_STRICT_DEVMEM
memblokir akses ke alamat memori fisik yang memetakan ke RAM, tetapi memungkinkan akses ke alamat yang tidak memetakan ke RAM. Rincian kisaran alamat fisik apa yang diizinkan tergantung pada arsitektur prosesor, tetapi semuanya tidak termasuk RAM tempat data kernel dan proses lahan pengguna disimpan. Opsi tambahan CONFIG_IO_STRICT_DEVMEM
(dinonaktifkan pada Ubuntu 18.04) memblokir akses ke alamat fisik yang diklaim oleh driver.
Memori fisik alamat yang memetakan ke RAM . Jadi ada alamat memori fisik yang tidak dipetakan ke RAM? Iya. Itulah diskusi yang saya janjikan di atas tentang apa artinya menulis ke alamat.
Instruksi penyimpanan memori tidak harus menulis ke RAM. Prosesor menguraikan alamat dan memutuskan perangkat mana yang akan dikirimi toko. (Ketika saya mengatakan "prosesor", saya mencakup pengontrol periferal yang mungkin tidak berasal dari pabrikan yang sama.) RAM hanya salah satu dari periferal tersebut. Bagaimana pengiriman dilakukan sangat tergantung pada arsitektur prosesor, tetapi secara fundamental kurang lebih sama pada semua arsitektur. Prosesor pada dasarnya menguraikan bit-bit alamat yang lebih tinggi dan mencarinya di beberapa tabel yang diisi berdasarkan informasi kode-keras, informasi yang diperoleh dengan menyelidik beberapa bus, dan informasi yang dikonfigurasikan oleh perangkat lunak. Banyak caching dan buffering mungkin terlibat, tetapi singkatnya, setelah dekomposisi ini,bus dan kemudian terserah perangkat untuk menghadapinya. (Atau hasil dari pencarian tabel mungkin karena tidak ada perangkat di alamat ini, dalam hal ini prosesor memasuki kondisi jebakan di mana ia mengeksekusi beberapa kode di kernel yang biasanya menghasilkan SIGBUS untuk proses panggilan.)
Toko ke alamat yang dipetakan ke RAM tidak "melakukan" apa pun selain menimpa nilai yang sebelumnya disimpan di alamat ini, dengan janji bahwa pemuatan berikutnya pada alamat yang sama akan mengembalikan nilai terakhir yang disimpan. Tetapi bahkan RAM memiliki beberapa alamat yang tidak berperilaku seperti ini: ia memiliki beberapa register yang dapat mengontrol hal-hal seperti refresh rate dan voltase.
Secara umum, membaca atau menulis ke register perangkat keras melakukan apa pun yang diprogram untuk dilakukan perangkat keras. Sebagian besar akses ke perangkat keras bekerja dengan cara ini: perangkat lunak (biasanya kode kernel) mengakses alamat fisik tertentu, ini mencapai bus yang menghubungkan prosesor ke perangkat, dan perangkat melakukan hal tersebut. Beberapa prosesor (khususnya x86) juga memiliki instruksi CPU terpisah yang menyebabkan pembacaan / penulisan ke periferal yang berbeda dari pemuatan dan penyimpanan memori, tetapi bahkan pada x86, banyak periferal yang dicapai melalui pemuatan / penyimpanan.
Perintah dd if=/dev/urandom of=/dev/mem
menulis data acak ke perangkat apa pun yang dipetakan pada alamat 0 (dan alamat berikutnya, selama penulisan berhasil). Dalam prakteknya, saya berharap bahwa pada banyak arsitektur, alamat fisik 0 tidak memiliki perangkat apa pun yang dipetakan, atau memiliki RAM, dan oleh karena itu upaya penulisan pertama gagal. Tetapi jika ada perangkat yang dipetakan di alamat 0, atau jika Anda mengubah perintah untuk menulis ke alamat yang berbeda, Anda akan memicu sesuatu yang tidak terduga di perangkat. Dengan data acak di alamat yang meningkat, tidak mungkin melakukan sesuatu yang menarik, tetapi pada prinsipnya itu bisa mematikan komputer (mungkin ada alamat yang melakukan ini sebenarnya), menimpa beberapa pengaturan BIOS yang membuatnya tidak mungkin untuk boot, atau bahkan menekan beberapa perangkat kereta dengan cara yang merusaknya.
alias Russian_roulette='dd if=/dev/urandom of=/dev/mem seek=$((4096*RANDOM+4096*32768*RANDOM))'
CONFIG_STRICT_DEVMEM
diaktifkan.
/ dev / mem adalah file perangkat karakter yang merupakan gambar dari memori utama komputer. Ini dapat digunakan, misalnya, untuk memeriksa (dan bahkan menambal) sistem.
Jadi secara teori, dd if=/dev/urandom of=/dev/mem
harus menimpa seluruh ruang alamat dari memori fisik yang telah Anda instal, dan karena kernel dan program lain berjalan dari memori, ini akan secara efektif membuat sistem crash. Dalam praktiknya, ada batasnya. Dari halaman manual yang sama:
Sejak Linux 2.6.26, dan tergantung pada arsitekturnya, opsi konfigurasi kernel CONFIG_STRICT_DEVMEM membatasi area yang dapat diakses melalui file ini.
Mencoba ini di mesin virtual Ubuntu 18.04, ia mengembalikan kesalahan dd: writing to '/dev/mem': Operation not permitted
bahkan dengan sudo
dan meskipun izin untuk root crw-r-----
. Dari Ubuntu Wiki :
/ dev / mem perlindungan
Beberapa aplikasi (Xorg) memerlukan akses langsung ke memori fisik dari ruang pengguna. Ada file / dev / mem khusus untuk menyediakan akses ini. Di masa lalu, dimungkinkan untuk melihat dan mengubah memori kernel dari file ini jika penyerang memiliki akses root. Opsi kernel CONFIG_STRICT_DEVMEM diperkenalkan untuk memblokir akses memori non-perangkat (awalnya bernama CONFIG_NONPROMISC_DEVMEM).
Jadi secara teknis, tidak itu tidak aman (karena itu akan merusak sistem) dan jika opsi kernel CONFIG_STRICT_DEVMEM
dinonaktifkan itu lubang keamanan, tetapi dari apa yang saya lihat sejauh ini perintah tidak akan berjalan jika opsi itu diaktifkan. Menurut duplikat lintas-situs , reboot akan memperbaiki masalah dengan itu, tetapi tentu saja data dalam RAM pada saat itu akan hilang dan tidak memerah ke disk (jika ada harus).
Ada metode yang disarankan pada duplikat yang ditautkan sebelumnya menggunakan busybox devmem
jadi jika Anda bertekad untuk main-main dengan RAM, mungkin ada cara.
CONFIG_STRICT_DEVMEM
, Anda dapat mengakses wilayah memori di mana perangkat dipetakan, yang merupakan inti dari memiliki /dev/mem
. Jika Anda menulis hal-hal acak ke peripheral, apa pun mungkin terjadi. Anda mendapatkan "operasi tidak diizinkan" jika Anda mencoba mengakses alamat yang tidak dipetakan, dan perintah dimulai pada alamat 0. Apakah alamat 0 memetakan sesuatu yang buruk tergantung pada arsitektur perangkat keras. Yang saya tahu itu mungkin tidak pernah dipetakan ke apa pun di PC, tetapi secara umum tidak aman.
head -c 1024 </dev/mem | od -tx1
), tapi saya tidak tahu apakah ini digunakan ketika prosesor tidak dalam mode nyata (mode 8088). Saya tidak berpikir mereka dapat digunakan dalam mode 64-bit: setelah semua, vektor interupsi 8088 hanya memiliki 32 bit untuk alamat. Dan omong-omong ini dapat diakses dengan CONFIG_STRICT_DEVMEM
set, jadi saya kira Linux tidak menggunakannya.