= / Dev / mem = / dev / urandom ise dd güvenli midir?


10

Bu tam olarak ne yapıyor? Baz belleğe bununla nasıl ulaşabileceğinizi anlamıyorum ... biraz garip görünüyor. Güvenli mi?

dd if=/dev/urandom of=/dev/mem

Konuştuğun "güvenli" nedir? Ne için güvenli?
waltinator

Bu komutla neyi başarmak istiyorsunuz?
jochen

Yanıtlar:


23

Bunu evde denemeyin! Sisteminizi kilitleyebilir ve gerçekten şanssızsanız, bir çevre birimine zarar verebilir veya bilgisayarınızı önyüklenemez hale getirebilir.

Aslında, çoğu platformda, sadece bir hata ile başarısız olur, ancak bu donanım mimarisine bağlıdır. Komutu ayrıcalıksız bir kullanıcı olarak çalıştırmadığınız sürece bunun kesinlikle zararsız olduğuna dair bir garanti yoktur. Ayrıcalıksız bir kullanıcıyla, açamadığınız için komut tamamen zararsızdır /dev/mem.

Kök olarak bir komut çalıştırdığınızda, ne yaptığınızı bilmeniz gerekir. Çekirdek bazen tehlikeli bir şey yapmanızı engeller, ancak her zaman değil. /dev/memgerçekten ne yaptığınızı bilmeniz gereken potansiyel olarak tehlikeli şeylerden biridir.

Bir yazının /dev/memLinux'ta nasıl çalıştığını inceleyeceğim. Genel ilke diğer Unices için aynıdır, ancak çekirdek seçenekleri gibi şeyler tamamen farklıdır.

Bir işlem bir aygıt dosyasını okuduğunda veya bir dosyaya yazdığında çekirdeğe kadar olur. Bir aygıt dosyasına erişim, sürücüde bu aygıt dosyasını işleyen bazı kodlar çalıştırır. Örneğin, yazma /dev/memfonksiyonu istemektedir write_memiçindedrivers/char/mem.c . Bu işlev 4 argüman alır: açık dosyayı temsil eden bir veri yapısı, yazılacak verilere bir işaretçi, yazılacak bayt sayısı ve dosyadaki geçerli konum.

Yalnızca arayanın dosyayı ilk etapta açma izni varsa bu kadar ileri gidebileceğinizi unutmayın. Aygıt dosyaları dosya izinlerine normal olarak uyar. Normal izinleri /dev/memvardır crw-r-----aittir root:kmemsen olmak root olmadan yazma için açmaya çalışırsanız, bu nedenle, sadece alırsınız (EACCESS) “izin reddedildi”. Ancak root iseniz (veya root bu dosyanın izinlerini değiştirdiyse), açılış gerçekleşir ve daha sonra bir yazma girişiminde bulunabilirsiniz.

İşlevdeki kod write_membazı sağlık kontrolleri yapar, ancak bu kontroller kötü olan her şeye karşı koruma için yeterli değildir. Yaptığı ilk şey, geçerli dosya konumunu *pposfiziksel bir adrese dönüştürmektir. Bu başarısız olursa (pratikte, 32 bit fiziksel adresleri ancak 64 bit dosya ofsetleri olan ve dosya ofseti 2 ^ 32'den büyük bir platformda olduğunuz için, yazma işlemi EFBIG (dosya çok büyük) ile başarısız olur. Bir sonraki kontrol, yazılacak fiziksel adres aralığının bu özel işlemci mimarisinde geçerli olup olmadığı ve bir başarısızlığın EFAULT (hatalı adres) ile sonuçlanıp sonuçlanmadığıdır.

Daha sonra, Sparc ve m68k'de, ilk fiziksel sayfadaki yazmanın herhangi bir kısmı sessizce atlanır.

Artık bir MMU sayfasına sığabilecek bloklar halinde veriler üzerinde yinelenen ana döngüye ulaştık . sanal belleğe değil, fiziksel belleğe erişir, ancak verileri belleğe yüklemek ve depolamak için işlemci talimatları sanal adresler kullanır, bu nedenle kodun fiziksel belleği bazı sanal adreslerde eşlemek için ayarlanması gerekir. Linux'ta, işlemci mimarisine ve çekirdek yapılandırmasına bağlı olarak, bu eşleme ya kalıcı olarak bulunur ya da anında yapılmalıdır; bu işin (ve ne yaparsa yapsın). Daha sonra işlev , aktarılan arabellekten okur./dev/memxlate_dev_mem_ptrunxlate_dev_mem_ptrxlate_dev_mem_ptrcopy_from_userwritesistem çağrısı ve fiziksel belleğin şu anda eşlendiği sanal adrese yazar. Kod normal bellek deposu talimatlarını yayar ve bunun anlamı donanıma bağlıdır.

Fiziksel bir adrese yazmanın yapmadan bahsetmeden önce, bu yazmadan önce gerçekleşen bir kontrolü tartışacağım. Döngü içinde, page_is_allowedçekirdek yapılandırma seçeneği CONFIG_STRICT_DEVMEMetkinse işlev blokları belirli adreslere erişir (varsayılan olarak durum budur): yalnızca izin verilen adreslere devmem_is_allowedulaşılabilir /dev/mem, diğerleri için yazma işlemi EPERM ile başarısız olur (işleme izin verilmez). Bu seçeneğin açıklaması şunları belirtir:

Bu seçenek açıksa ve IO_STRICT_DEVMEM = n ise, / dev / mem dosyası yalnızca PCI alanına, BIOS koduna ve veri bölgelerine kullanıcı erişimine izin verir. Bu, dosemu ve X ve / dev / mem'in tüm yaygın kullanıcıları için yeterlidir.

Bu çok x86 merkezli bir açıklama. Aslında, daha genel olarak, CONFIG_STRICT_DEVMEMRAM ile eşlenen fiziksel bellek adreslerine erişimi engeller, ancak RAM ile eşleşmeyen adreslere erişime izin verir. Hangi fiziksel adres aralıklarına izin verildiğinin ayrıntıları işlemci mimarisine bağlıdır, ancak hepsi çekirdek ve kullanıcı arazi işlemlerinin verilerinin depolandığı RAM'i hariç tutar. Ek seçenek CONFIG_IO_STRICT_DEVMEM(Ubuntu 18.04'ten itibaren devre dışı bırakılmıştır), bir sürücü tarafından talep edilen fiziksel adreslere erişimi engeller.

RAM ile eşlenen fiziksel bellek adresleri . RAM ile eşleşmeyen fiziksel bellek adresleri var mı? Evet. Bu, bir adrese yazmanın ne anlama geldiğine dair söz verdiğim tartışma.

Bellek deposu talimatı RAM'a mutlaka yazmaz. İşlemci adresi ayrıştırır ve mağazanın hangi çevre birimine gönderileceğine karar verir. (“İşlemci” dediğimde, aynı üreticiden gelmeyebilecek çevresel denetleyicileri kapsıyorum.) RAM, bu çevre birimlerinden sadece biri. Dağıtımın nasıl yapıldığı işlemci mimarisine çok bağlıdır, ancak temeller tüm mimarilerde aşağı yukarı aynıdır. İşlemci temel olarak adresin yüksek bitlerini ayrıştırır ve bunları sabit kodlanmış bilgilere, bazı otobüsleri inceleyerek elde edilen bilgilere ve yazılım tarafından yapılandırılan bilgilere dayalı olarak doldurulmuş bazı tablolarda arar. Çok fazla önbellekleme ve tamponlama söz konusu olabilir, ancak kısaca, bu ayrışmadan sonra,otobüs ve sonra onunla başa çıkmak için çevre birime kalmış. (Veya tablo aramasının sonucu, bu adreste bir çevre birimi olmaması olabilir; bu durumda işlemci , çekirdekte normalde çağrı işlemi için SIGBUS ile sonuçlanan bir kod yürüttüğü bir tuzak durumuna girer .)

RAM ile eşlenen bir adrese yapılan bir mağaza, daha önce bu adreste depolanan değerin üzerine yazmak dışında hiçbir şey yapmaz ve aynı adresteki daha sonraki bir yükün son depolanan değeri geri vereceğine dair söz verir. Ancak RAM'in bile bu şekilde davranmayan birkaç adresi vardır: yenileme hızı ve voltaj gibi şeyleri kontrol edebilen birkaç kaydı vardır.

Genel olarak, bir donanım kaydına bir okuma veya yazma işlemi, donanımın programlandığı her şeyi yapar. Donanıma çoğu erişim bu şekilde çalışır: yazılım (normalde çekirdek kodu) belirli bir fiziksel adrese erişir, bu işlemciyi çevreye bağlayan veri yoluna ulaşır ve çevre birimi işini yapar. Bazı işlemciler (özellikle x86), bellek yükünden ve depodan farklı olan çevre birimlerine okuma / yazma işlemlerine neden olan ayrı CPU komutlarına sahiptir, ancak x86'da bile, birçok çevre birimine yükleme / depolama yoluyla ulaşılır.

Komut dd if=/dev/urandom of=/dev/mem, 0 adresinde eşlenen çevre birimine rastgele veriler yazar (ve yazma işlemleri başarılı olduğu sürece sonraki adresler). Uygulamada, pek çok mimaride, fiziksel adres 0'ın kendisiyle eşlenmiş herhangi bir çevre birimi bulunmamasını veya RAM'in bulunmamasını ve bu nedenle ilk yazma girişiminin başarısız olmasını bekliyorum. Ancak 0 adresinde eşlenen bir çevre birimi varsa veya farklı bir adrese yazma komutunu değiştirirseniz, çevre biriminde öngörülemeyen bir şeyi tetiklersiniz. Artan adreslerdeki rastgele verilerle, ilginç bir şey yapmak olası değildir, ancak prensipte bilgisayarı kapatabilir (muhtemelen bunu yapan bir adres olabilir), önyüklemeyi imkansız kılan bazı BIOS ayarlarının üzerine yazabilir veya hatta bazılarına vurabilir zarar veren bir şekilde buggy periferik.

alias Russian_roulette='dd if=/dev/urandom of=/dev/mem seek=$((4096*RANDOM+4096*32768*RANDOM))'

Teşekkür ederim! Aradığım şey buydu! / Dev / mem, çevre birimleri ve donanımla ilgili şeylere bellek erişimine izin verip vermediği konusunda kafam karıştı!
Coder14

Bir çevre birimi x86 bilgisayardaki fiziksel adres 0'da eşlenemez; bu yapılandırma hiçbir zaman önyükleme yapmaz.
Joshua

Bu doğru değil
Yvain

1
Tabii ki çekirdeğe zarar verebilirsiniz ama biyografiye zarar
veremezsiniz

1
@Yvain Doğru olmayan nedir ? Ve eğer CONFIG_STRICT_DEVMEMetkinse , çekirdeğe zarar veremezsiniz .
Gilles 'SO- kötü olmayı bırak

12

Çekirdeği doğru yapılandırdıysanız güvenlidir (çalışmadığı için güvenlidir)

Manuel sayfa belleği başına (4) :

/ dev / mem, bilgisayarın ana belleğinin görüntüsü olan bir karakter aygıtı dosyasıdır. Örneğin, sistemi incelemek (ve hatta düzeltmek) için kullanılabilir.

Yani teoride, dd if=/dev/urandom of=/dev/memyüklediğiniz fiziksel bellek tüm adres alanını üzerine olmalı ve çekirdek ve diğer programlar bellekten çalıştırmak beri bu olmalıdır etkili bir sistem çökmesine. Pratikte sınır var. Aynı kılavuz sayfasından:

Linux 2.6.26'dan beri ve mimariye bağlı olarak, CONFIG_STRICT_DEVMEM çekirdek yapılandırma seçeneği bu dosya üzerinden erişilebilen alanları sınırlar.

Bunu sanal makine Ubuntu 18.04'te deneyerek, kök izinlerine rağmen ve dd: writing to '/dev/mem': Operation not permittedhatta sudoizinlere rağmen bir hata döndürür crw-r-----. Gönderen Ubuntu Wiki :

/ dev / mem koruması

Bazı uygulamaların (Xorg) fiziksel bellekten kullanıcı alanından doğrudan erişmesi gerekir. Bu erişimi sağlamak için / dev / mem özel dosyası var. Geçmişte, bir saldırganın root erişimine sahip olması durumunda bu dosyadaki çekirdek belleğini görüntülemek ve değiştirmek mümkün olmuştur. Aygıt dışı bellek erişimini engellemek için CONFIG_STRICT_DEVMEM çekirdek seçeneği tanıtıldı (başlangıçta CONFIG_NONPROMISC_DEVMEM olarak adlandırıldı).

Bu yüzden teknik olarak hayır, güvenli değildir (sistemi çökeceğinden beri) ve çekirdek seçeneği CONFIG_STRICT_DEVMEMdevre dışı bırakılırsa bu bir güvenlik açığıdır, ancak şu ana kadar gördüğüm kadarıyla bu seçenek etkinleştirilirse komut çalışmaz. Göre siteler arası ikişer , yeniden başlatma onunla herhangi bir sorun çözecektir, ancak o zaman RAM içinde elbette veriler kaybolur ve (herhangi biri olsaydı) diske temizlenip değil olacaktı.

Daha önce bağlanan kopyada önerilen bir yöntem var, busybox devmembu yüzden RAM ile uğraşmaya karar verirseniz, sonuçta bir yol olabilir.


6
“Güvenlidir” Hayır, kesinlikle değil. Bununla birlikte CONFIG_STRICT_DEVMEM, bir çevre biriminin eşleştirildiği bellek bölgelerine erişebilirsiniz, bu da sahip olmanın tüm noktasıdır /dev/mem. Çevre birimlerine rastgele şeyler yazarsanız, herhangi bir şey olabilir. Eşlenmemiş bir adrese erişmeye çalışırsanız ve komut 0 adresinden başlarsa “işleme izin verilmiyor” iletisi alırsınız. 0 adresinin kötü bir şeyle eşleşip eşleşmeyeceği donanım mimarisine bağlıdır. Bildiğim kadarıyla hiçbir zaman bir PC'deki hiçbir şeyle eşleşmeyebilir, ancak genel olarak güvenli değildir.
Gilles 'SO- kötü olmayı bırak

1
@Gilles x86'da (x86-64'ten emin değilim), ilk 1 KiB RAM (0x0 - 0x3ff adresleri) kesinti vektörlerini tutar; vektör başına dört bayt değerinde adres. Rastgele çöp olanların üzerine yazmayı başarırsanız, her türlü ilginç şeyin çok yakında gerçekleşmesi muhtemeldir. Büyük olasılıkla, çift veya üçlü bir arıza ile karşılaşacaksınız ve sistem çökecek, ancak garanti yok ...
CVn

@aCVn Kesinlikle mapped ( head -c 1024 </dev/mem | od -tx1) vardır, ancak işlemci gerçek modda (8088 modu) olmadığında bunların kullanılıp kullanılmadığını bilmiyorum. 64-bit modunda kullanılabileceklerini sanmıyorum: sonuçta 8088 kesinti vektörlerinin adres için sadece 32 bitleri var. Ve bu arada CONFIG_STRICT_DEVMEMset ile erişilebilir , bu yüzden sanırım Linux bunu kullanmıyor.
Gilles 'SO- kötü olmayı bırak

@Gilles: x86'daki 0 ​​sayfa v86, önyükleyici vb. İçin ayrılmıştır; Buradaki gerçek mod kesinti vektör tablosu. Korumalı modda, IVT başka bir yerdedir (bir makine sicili nerede olduğunu söyler).
Joshua
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.