dd คือ = / dev / urandom ของ = / dev / mem ปลอดภัยหรือไม่


10

มันทำอะไรกันแน่ ฉันไม่เข้าใจว่าคุณสามารถเข้าถึงหน่วยความจำพื้นฐานด้วยวิธีนี้ได้อย่างไร ... ดูเหมือนว่าจะแปลก ปลอดภัยไหม

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

"ปลอดภัย" ที่คุณพูดนี้คืออะไร ปลอดภัยด้วยความเคารพต่ออะไร
waltinator

คุณต้องการทำอะไรกับคำสั่งนี้?
jochen

คำตอบ:


23

อย่าลองทำที่บ้าน! มันอาจทำให้ระบบของคุณเสียหายและถ้าคุณโชคไม่ดีจริง ๆ มันอาจทำให้อุปกรณ์ต่อพ่วงเสียหายหรือทำให้คอมพิวเตอร์ของคุณไม่สามารถบูตได้

ที่จริงแล้วในแพลตฟอร์มส่วนใหญ่มันล้มเหลวโดยมีข้อผิดพลาด แต่ขึ้นอยู่กับสถาปัตยกรรมฮาร์ดแวร์ ไม่มีการรับประกันแน่นอนว่าสิ่งนี้จะไม่เป็นอันตรายเว้นแต่คุณจะเรียกใช้คำสั่งในฐานะผู้ใช้ที่ไม่มีสิทธิพิเศษ ด้วยผู้ใช้ที่ไม่มีสิทธิพิเศษคำสั่งจะไม่เป็นอันตรายอย่างสมบูรณ์เพราะคุณไม่สามารถเปิด/dev/memได้

เมื่อคุณเรียกใช้คำสั่งในฐานะรูทคุณควรจะรู้ว่าคุณกำลังทำอะไรอยู่ เคอร์เนลบางครั้งจะป้องกันไม่ให้คุณทำสิ่งที่อันตราย แต่ไม่เสมอไป /dev/memเป็นหนึ่งในสิ่งที่อาจเป็นอันตรายที่คุณควรรู้ว่าคุณกำลังทำอะไรอยู่

ฉันจะอธิบายวิธีการเขียนไปใช้/dev/memงานบน Linux หลักการทั่วไปจะเหมือนกันใน Unices อื่น ๆ แต่สิ่งต่าง ๆ เช่นตัวเลือกเคอร์เนลแตกต่างอย่างสิ้นเชิง

จะเกิดอะไรขึ้นเมื่อกระบวนการอ่านหรือเขียนไปยังไฟล์อุปกรณ์ขึ้นอยู่กับเคอร์เนล การเข้าถึงไฟล์อุปกรณ์จะเรียกใช้รหัสบางอย่างในไดรเวอร์ที่จัดการไฟล์อุปกรณ์นี้ ยกตัวอย่างเช่นการเขียนเพื่อ/dev/memเรียกฟังก์ชั่นในwrite_mem drivers/char/mem.cฟังก์ชั่นนี้ใช้เวลา 4 ข้อโต้แย้ง: โครงสร้างข้อมูลที่แสดงถึงไฟล์ที่เปิดตัวชี้ไปยังข้อมูลที่จะเขียนจำนวนไบต์ที่จะเขียนและตำแหน่งปัจจุบันในไฟล์

โปรดทราบว่าคุณจะได้รับเมื่อผู้โทรได้รับอนุญาตให้เปิดไฟล์ตั้งแต่แรก ไฟล์อุปกรณ์เชื่อฟังการอนุญาตไฟล์ตามปกติ สิทธิ์ปกติของการ/dev/memเป็นcrw-r-----เจ้าของroot:kmemดังนั้นหากคุณพยายามเปิดโดยไม่ต้องรูทคุณจะได้รับ“ สิทธิ์ถูกปฏิเสธ” (EACCESS) แต่ถ้าคุณรูท (หรือถ้ารูทเปลี่ยนสิทธิ์ของไฟล์นี้) การเปิดจะผ่านไปแล้วคุณสามารถลองเขียนได้

รหัสในwrite_memฟังก์ชันทำให้การตรวจสอบมีสติ แต่การตรวจสอบเหล่านี้ไม่เพียงพอที่จะป้องกันทุกสิ่งที่ไม่ดี สิ่งแรกที่ทำคือแปลงตำแหน่งไฟล์ปัจจุบัน*pposเป็นที่อยู่จริง หากล้มเหลว (ในทางปฏิบัติเนื่องจากคุณอยู่บนแพลตฟอร์มที่มีที่อยู่ทางกายภาพ 32- บิต แต่ออฟเซ็ตไฟล์ 64- บิตและออฟเซ็ตไฟล์ใหญ่กว่า 2 ^ 32) การเขียนล้มเหลวด้วย EFBIG (ไฟล์ใหญ่เกินไป) การตรวจสอบครั้งต่อไปคือช่วงของที่อยู่ทางกายภาพในการเขียนที่ถูกต้องในสถาปัตยกรรมตัวประมวลผลนี้หรือไม่และมีความล้มเหลวส่งผลให้ EFAULT (ที่อยู่ไม่ถูกต้อง)

ถัดไปใน Sparc และ m68k ส่วนใดส่วนหนึ่งของการเขียนในหน้าฟิสิคัลแรกนั้นจะถูกข้ามอย่างเงียบ ๆ

ตอนนี้เรามาถึงลูปหลักซึ่งวนซ้ำข้อมูลในบล็อกที่สามารถใส่ได้ในหน้าMMUเดียว /dev/memเข้าถึงหน่วยความจำกายภาพไม่ใช่หน่วยความจำเสมือน แต่ตัวประมวลผลคำแนะนำในการโหลดและเก็บข้อมูลในหน่วยความจำใช้ที่อยู่เสมือนดังนั้นรหัสจะต้องจัดเรียงเพื่อแมปหน่วยความจำกายภาพในที่อยู่เสมือนบางแห่ง บน Linux ขึ้นอยู่กับสถาปัตยกรรมตัวประมวลผลและการกำหนดค่าเคอร์เนลการแมปนี้มีอยู่อย่างอนุญาตหรือต้องทำทันที นั่นเป็นหน้าที่ของxlate_dev_mem_ptr(และunxlate_dev_mem_ptrยกเลิกสิ่งที่xlate_dev_mem_ptrทำ) จากนั้นฟังก์ชั่นcopy_from_userจะอ่านจากบัฟเฟอร์ที่ส่งผ่านไปยังwriteการเรียกของระบบและเพิ่งเขียนไปยังที่อยู่เสมือนที่หน่วยความจำกายภาพถูกแมปในปัจจุบัน รหัสส่งคำแนะนำในการจัดเก็บหน่วยความจำปกติและสิ่งนี้หมายถึงอะไรขึ้นอยู่กับฮาร์ดแวร์

ก่อนที่ฉันจะพูดถึงว่าการเขียนไปยังที่อยู่ทางกายภาพนั้นฉันจะพูดถึงการตรวจสอบที่เกิดขึ้นก่อนการเขียนนี้ ภายในลูปฟังก์ชันpage_is_allowedปิดกั้นการเข้าถึงที่อยู่บางอย่างหากCONFIG_STRICT_DEVMEMเปิดใช้งานตัวเลือกการกำหนดค่าเคอร์เนล(ซึ่งเป็นกรณีโดยค่าเริ่มต้น): เฉพาะที่อยู่ที่อนุญาตโดยdevmem_is_allowedสามารถเข้าถึงได้ผ่าน/dev/memสำหรับคนอื่น ๆ การเขียนล้มเหลวด้วย EPERM คำอธิบายของตัวเลือกนี้ระบุ:

หากเปิดใช้งานตัวเลือกนี้และ IO_STRICT_DEVMEM = n ไฟล์ / dev / mem จะอนุญาตให้ผู้ใช้เข้าถึงพื้นที่ PCI และรหัส BIOS และเขตข้อมูลเท่านั้น นี่เพียงพอสำหรับ dosemu และ X และผู้ใช้ทั่วไปของ / dev / mem

นี่คือคำอธิบาย x86- ศูนย์กลางมาก ในความเป็นจริงโดยทั่วไปแล้วCONFIG_STRICT_DEVMEMบล็อกการเข้าถึงที่อยู่หน่วยความจำกายภาพที่แมปกับ RAM แต่อนุญาตการเข้าถึงที่อยู่ที่ไม่ได้แมปกับ RAM รายละเอียดของช่วงที่อยู่ทางกายภาพที่ได้รับอนุญาตขึ้นอยู่กับสถาปัตยกรรมของโปรเซสเซอร์ แต่ทั้งหมดไม่รวม RAM ที่ข้อมูลของเคอร์เนลและกระบวนการผู้ใช้ที่ดินจะถูกเก็บไว้ ตัวเลือกเพิ่มเติมCONFIG_IO_STRICT_DEVMEM(ปิดใช้งานในขณะที่ Ubuntu 18.04) บล็อกการเข้าถึงที่อยู่ทางกายภาพที่อ้างสิทธิ์โดยไดรเวอร์

อยู่หน่วยความจำทางกายภาพที่แมปไป RAM ดังนั้นมีที่อยู่หน่วยความจำกายภาพที่ไม่ได้แมปกับ RAM หรือไม่ ใช่. นั่นคือการสนทนาที่ฉันสัญญาไว้ข้างต้นเกี่ยวกับความหมายของการเขียนไปยังที่อยู่

คำสั่งที่เก็บหน่วยความจำไม่จำเป็นต้องเขียนลง RAM โปรเซสเซอร์จะสลายตัวที่อยู่และตัดสินใจว่าอุปกรณ์ต่อพ่วงใดที่จะส่งต่อร้านค้า (เมื่อฉันพูดว่า "ตัวประมวลผล" ฉันรวมตัวควบคุมอุปกรณ์ต่อพ่วงซึ่งอาจไม่ได้มาจากผู้ผลิตรายเดียวกัน) RAM เป็นเพียงหนึ่งในอุปกรณ์ต่อพ่วงเหล่านั้น วิธีการจัดส่งนั้นขึ้นอยู่กับสถาปัตยกรรมของโปรเซสเซอร์เป็นอย่างมาก แต่ปัจจัยพื้นฐานนั้นมีความเหมือนกันในทุกสถาปัตยกรรม หน่วยประมวลผลโดยทั่วไปจะสลายบิตที่สูงขึ้นของที่อยู่และค้นหามันในบางตารางที่มีประชากรอยู่บนพื้นฐานของข้อมูลที่ได้รับการเข้ารหัสข้อมูลที่ได้รับจากการตรวจสอบรถเมล์และข้อมูลที่กำหนดโดยซอฟต์แวร์ การแคชและการบัฟเฟอร์จำนวนมากอาจเกี่ยวข้อง แต่สรุปหลังจากการสลายตัวนี้รถบัสและจากนั้นขึ้นอยู่กับอุปกรณ์ต่อพ่วงเพื่อจัดการกับมัน (หรือผลลัพธ์ของการค้นหาตารางอาจเป็นเพราะไม่มีอุปกรณ์ต่อพ่วงที่ที่อยู่นี้ซึ่งในกรณีนี้โปรเซสเซอร์จะเข้าสู่สถานะของแทร็บซึ่งจะประมวลผลโค้ดบางส่วนในเคอร์เนลที่โดยปกติแล้วจะส่งผลให้SIGBUSสำหรับกระบวนการเรียก)

ร้านค้าไปยังที่อยู่ที่จับคู่กับ RAM จะไม่“ ทำ” สิ่งใดนอกจากเขียนทับค่าที่เก็บไว้ก่อนหน้านี้ที่อยู่นี้โดยสัญญาว่าการโหลดในภายหลังที่ที่อยู่เดียวกันจะให้ค่าที่เก็บไว้ล่าสุด แต่แม้ RAM จะมีที่อยู่ไม่กี่ที่ที่ไม่ทำงานเช่นนี้ แต่ก็มีรีจิสเตอร์บางตัวที่สามารถควบคุมสิ่งต่าง ๆ เช่นอัตราการรีเฟรชและแรงดันไฟฟ้า

โดยทั่วไปการอ่านหรือเขียนลงทะเบียนฮาร์ดแวร์จะทำสิ่งที่ฮาร์ดแวร์ถูกตั้งโปรแกรมให้ทำ การเข้าถึงฮาร์ดแวร์ส่วนใหญ่ทำงานด้วยวิธีนี้: ซอฟต์แวร์ (ปกติรหัสเคอร์เนล) เข้าถึงที่อยู่ทางกายภาพที่แน่นอนไปถึงรถบัสที่เชื่อมต่อโปรเซสเซอร์กับอุปกรณ์ต่อพ่วงและอุปกรณ์ต่อพ่วงทำหน้าที่ของมัน โปรเซสเซอร์บางตัว (โดยเฉพาะอย่างยิ่ง x86) มีคำสั่ง CPU แยกต่างหากซึ่งทำให้การอ่าน / เขียนไปยังอุปกรณ์ต่อพ่วงซึ่งแตกต่างจากหน่วยความจำโหลดและที่จัดเก็บ แต่แม้กระทั่งบน x86 อุปกรณ์ต่อพ่วงมากมายถึงโหลด / เก็บ

คำสั่งdd if=/dev/urandom of=/dev/memเขียนข้อมูลแบบสุ่มไปยังอุปกรณ์ต่อพ่วงใด ๆ ที่ถูกแมปที่ที่อยู่ 0 (และที่อยู่ที่ตามมาตราบใดที่การเขียนสำเร็จ) ในทางปฏิบัติฉันคาดหวังว่าในสถาปัตยกรรมจำนวนมากที่อยู่จริง 0 ไม่ได้ต่อพ่วงใด ๆ กับมันหรือมี RAM ดังนั้นความพยายามในการเขียนครั้งแรกจึงล้มเหลว แต่ถ้ามีการต่อพ่วงอุปกรณ์ต่อพ่วงที่ที่อยู่ 0 หรือถ้าคุณเปลี่ยนคำสั่งเพื่อเขียนไปยังที่อยู่อื่นคุณจะเรียกสิ่งที่ไม่สามารถคาดเดาได้ในอุปกรณ์ต่อพ่วง ด้วยข้อมูลแบบสุ่มที่เพิ่มที่อยู่จึงไม่น่าทำสิ่งที่น่าสนใจ แต่โดยหลักการแล้วมันสามารถปิดคอมพิวเตอร์ได้ (อาจมีที่อยู่ที่ใช้ทำสิ่งนี้) เขียนทับการตั้งค่า BIOS บางอย่างที่ทำให้ไม่สามารถบูตได้ อุปกรณ์ต่อพ่วง buggy ในลักษณะที่เสียหายมัน

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

ขอบคุณ! นี่คือสิ่งที่ฉันกำลังมองหา! ฉันเพิ่งสับสนว่า / dev / mem อนุญาตให้หน่วยความจำเข้าถึงสิ่งต่าง ๆ เช่นอุปกรณ์ต่อพ่วงและสิ่งที่เกี่ยวข้องกับฮาร์ดแวร์!
Coder14

ไม่สามารถแมปอุปกรณ์ต่อพ่วงที่ที่อยู่จริง 0 บน x86 pc; การกำหนดค่านั้นจะไม่เริ่มระบบ
Joshua

นี่ไม่เป็นความจริงเลย
Yvain

1
แน่นอนคุณสามารถสร้างความเสียหายเคอร์เนล แต่ไม่ใช่ไบออส
Yvain

1
@Yvain อะไรไม่จริงเหรอ? และที่จริงคุณไม่สามารถทำลายเคอร์เนลได้หากCONFIG_STRICT_DEVMEMเปิดใช้งาน
Gilles 'หยุดความชั่วร้าย'

12

มีความปลอดภัยหากคุณตั้งค่าเคอร์เนลอย่างถูกต้อง (ปลอดภัยเพราะจะไม่ทำงาน)

ต่อหน่วยความจำหน้าคู่มือ(4) :

/ dev / mem เป็นไฟล์อุปกรณ์อักขระที่เป็นรูปภาพของหน่วยความจำหลักของคอมพิวเตอร์ มันอาจถูกนำมาใช้เพื่อตรวจสอบ (และแม้กระทั่งการแก้ไข) ระบบ

ดังนั้นในทางทฤษฎีdd if=/dev/urandom of=/dev/memควรเขียนทับพื้นที่แอดเดรสทั้งหมดของหน่วยความจำกายภาพที่คุณติดตั้งและเนื่องจากเคอร์เนลและโปรแกรมอื่น ๆ ที่เรียกใช้จากหน่วยความจำจึงควรทำให้ระบบขัดข้องอย่างมีประสิทธิภาพ ในทางปฏิบัติมีข้อ จำกัด จากหน้าคนเดียวกัน:

เนื่องจาก Linux 2.6.26 และขึ้นอยู่กับสถาปัตยกรรมตัวเลือกการกำหนดค่าเคอร์เนล CONFIG_STRICT_DEVMEM จำกัด พื้นที่ที่สามารถเข้าถึงได้ผ่านไฟล์นี้

ลองสิ่งนี้บนเครื่องเสมือน Ubuntu 18.04 มันจะส่งคืนข้อผิดพลาดdd: writing to '/dev/mem': Operation not permittedแม้จะมีsudoและแม้จะมีสิทธิ์ใช้งานสำหรับรูcrw-r-----ท จากUbuntu Wiki :

การป้องกัน / dev / mem

แอปพลิเคชั่นบางตัว (Xorg) จำเป็นต้องเข้าถึงหน่วยความจำกายภาพโดยตรงจากพื้นที่ผู้ใช้ มีไฟล์ / dev / mem พิเศษอยู่เพื่อให้การเข้าถึงนี้ ในอดีตเป็นไปได้ที่จะดูและเปลี่ยนหน่วยความจำเคอร์เนลจากไฟล์นี้หากผู้โจมตีมีการเข้าถึงรูท ตัวเลือกเคอร์เนล CONFIG_STRICT_DEVMEM ถูกนำมาใช้เพื่อบล็อกการเข้าถึงหน่วยความจำที่ไม่ใช่อุปกรณ์ (แต่เดิมชื่อ CONFIG_NONPROMISC_DEVMEM)

ดังนั้นในทางเทคนิคแล้วมันไม่ปลอดภัย (เพราะมันจะทำให้ระบบล่ม) และหากตัวเลือกเคอร์เนลCONFIG_STRICT_DEVMEMถูกปิดใช้งานนั่นคือช่องโหว่ความปลอดภัย แต่จากสิ่งที่ฉันเห็นจนถึงตอนนี้คำสั่งจะไม่ทำงานหากเปิดใช้งานตัวเลือกนั้น ตามการข้ามไซต์ซ้ำการรีบูตจะแก้ไขปัญหาใด ๆ กับมัน แต่แน่นอนว่าข้อมูลใน RAM ในเวลานั้นจะหายไปและไม่ถูกฟลัชลงดิสก์ (ถ้ามี)

มีวิธีที่แนะนำในการทำสำเนาลิงก์ที่ใช้ก่อนหน้านี้busybox devmemดังนั้นหากคุณตั้งใจจะยุ่งกับ RAM อาจมีวิธีหลังจากทั้งหมด


6
“ ปลอดภัย” ไม่แน่นอนที่สุดไม่ใช่ ถึงแม้จะมีคุณสามารถเข้าถึงพื้นที่หน่วยความจำที่ต่อพ่วงถูกแมปซึ่งเป็นจุดรวมของการมีCONFIG_STRICT_DEVMEM /dev/memหากคุณเขียนข้อมูลแบบสุ่มไปยังอุปกรณ์ต่อพ่วงอาจมีอะไรเกิดขึ้น คุณได้รับ“ การดำเนินการที่ไม่ได้รับอนุญาต” หากคุณพยายามเข้าถึงที่อยู่ที่ไม่ได้ถูกแมปและคำสั่งจะเริ่มต้นที่ที่อยู่ 0 ไม่ว่าที่อยู่ 0 จะแมปสิ่งที่ไม่ดีขึ้นอยู่กับสถาปัตยกรรมฮาร์ดแวร์ ฉันรู้ว่ามันอาจไม่เคยแมปกับสิ่งใดบนพีซี แต่โดยทั่วไปจะไม่ปลอดภัย
Gilles 'หยุดความชั่วร้าย'

1
@Gilles บน x86 (ไม่แน่ใจเกี่ยวกับ x86-64) RAM 1 KiB แรก (ที่อยู่ 0x0 ถึง 0x3ff) ถือเวกเตอร์ขัดจังหวะ ค่าที่อยู่สี่ไบต์ต่อเวกเตอร์ หากคุณประสบความสำเร็จในการเขียนทับผู้ที่มีขยะสุ่มสิ่งที่น่าสนใจทุกประเภทน่าจะเกิดขึ้นเร็ว ๆ นี้ เป็นไปได้มากที่สุดที่คุณจะพบกับข้อผิดพลาดสองหรือสามครั้งและระบบจะหยุดทำงาน แต่ไม่มีการรับประกัน ...
27719

@aCVn มีบางสิ่งที่แมป ( head -c 1024 </dev/mem | od -tx1) แต่ฉันไม่รู้ว่าสิ่งเหล่านี้ถูกใช้เมื่อตัวประมวลผลไม่ได้อยู่ในโหมดจริง (โหมด 8088) ฉันไม่คิดว่าจะสามารถใช้งานได้ในโหมด 64 บิต: หลังจากทั้งหมดเวกเตอร์ขัดจังหวะ 8088 มี 32 บิตสำหรับที่อยู่เท่านั้น และโดยวิธีการนี้สามารถเข้าถึงได้ด้วยCONFIG_STRICT_DEVMEMชุดดังนั้นฉันคิดว่า Linux ไม่ได้ใช้มัน
Gilles 'หยุดความชั่วร้าย'

@Gilles: 0 หน้าใน x86 สงวนไว้สำหรับ v86, bootloader, etc; นั่นคือตารางเวกเตอร์ขัดจังหวะโหมดจริงที่นั่น ในโหมดที่ได้รับการป้องกัน IVT นั้นอยู่ที่อื่น
Joshua
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.