Dd nếu = / dev / urandom của = / dev / mem có an toàn không?


10

Chính xác thì nó làm gì? Tôi không hiểu làm thế nào bạn có thể truy cập bộ nhớ cơ bản với điều này ... có vẻ hơi lạ. Nó có an toàn không?

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

"An toàn" mà bạn nói là gì? An toàn đối với những gì?
ví von

Bạn muốn đạt được gì với lệnh này?
jochen

Câu trả lời:


23

Đừng thử điều này ở nhà! Nó có thể làm sập hệ thống của bạn và nếu bạn thực sự không may thì nó có thể làm hỏng thiết bị ngoại vi hoặc khiến máy tính của bạn không thể khởi động được.

Trên thực tế, trên hầu hết các nền tảng, nó chỉ bị lỗi, nhưng điều đó phụ thuộc vào kiến ​​trúc phần cứng. Chắc chắn là không có gì đảm bảo rằng điều này là vô hại trừ khi bạn chạy lệnh với tư cách là người dùng không có quyền. Với người dùng không có đặc quyền, lệnh hoàn toàn vô hại vì bạn không thể mở /dev/mem.

Khi bạn chạy một lệnh với quyền root, bạn phải biết bạn đang làm gì. Hạt nhân đôi khi sẽ ngăn bạn làm điều gì đó nguy hiểm, nhưng không phải lúc nào cũng vậy. /dev/memlà một trong những điều nguy hiểm tiềm tàng nơi bạn thực sự cần phải biết những gì bạn đang làm.

Tôi sẽ tìm hiểu cách viết để /dev/memhoạt động trên Linux. Nguyên tắc chung sẽ giống nhau trên các Unice khác, nhưng những thứ như tùy chọn kernel hoàn toàn khác nhau.

Điều gì xảy ra khi một quá trình đọc hoặc ghi vào tệp thiết bị tùy thuộc vào kernel. Quyền truy cập vào tệp thiết bị chạy một số mã trong trình điều khiển xử lý tệp thiết bị này. Ví dụ, viết để /dev/memgọi hàm write_memtrongdrivers/char/mem.c . Hàm này có 4 đối số: cấu trúc dữ liệu đại diện cho tệp đang mở, con trỏ tới dữ liệu cần ghi, số byte cần ghi và vị trí hiện tại trong tệp.

Lưu ý rằng bạn chỉ đạt được điều đó nếu người gọi có quyền mở tệp ở vị trí đầu tiên. Tập tin thiết bị tuân theo quyền tập tin bình thường. Các quyền thông thường /dev/memđược crw-r-----sở hữu bởi root:kmem, vì vậy nếu bạn cố mở nó để viết mà không cần root, bạn sẽ chỉ nhận được quyền của từ chối từ chối (EACCESS). Nhưng nếu bạn là root (hoặc nếu root đã thay đổi quyền của tệp này), thì việc mở sẽ diễn ra và sau đó bạn có thể thử ghi.

Mã trong write_memhàm tạo ra một số kiểm tra độ tỉnh táo, nhưng các kiểm tra này không đủ để bảo vệ chống lại mọi thứ xấu. Điều đầu tiên nó làm là chuyển đổi vị trí tệp hiện tại *pposthành một địa chỉ vật lý. Nếu điều đó không thành công (trong thực tế, vì bạn đang ở trên một nền tảng có địa chỉ vật lý 32 bit nhưng độ lệch tệp 64 bit và độ lệch tệp lớn hơn 2 ^ 32), thì lỗi ghi với EFBIG (tệp quá lớn). Kiểm tra tiếp theo là liệu phạm vi địa chỉ vật lý cần ghi có hợp lệ trên kiến ​​trúc bộ xử lý cụ thể này hay không và có kết quả không thành công trong EFAULT (địa chỉ xấu).

Tiếp theo, trên Sparc và m68k, bất kỳ phần nào của bài viết trong trang vật lý đầu tiên đều âm thầm bỏ qua.

Bây giờ chúng ta đã đạt đến vòng lặp chính lặp lại dữ liệu trong các khối có thể vừa trong một trang MMU . /dev/memtruy cập bộ nhớ vật lý, không phải bộ nhớ ảo, nhưng bộ xử lý hướng dẫn tải và lưu trữ dữ liệu trong bộ nhớ sử dụng địa chỉ ảo, do đó mã cần sắp xếp để ánh xạ bộ nhớ vật lý tại một số địa chỉ ảo. Trên Linux, tùy thuộc vào kiến ​​trúc bộ xử lý và cấu hình kernel, ánh xạ này tồn tại vĩnh viễn hoặc phải được thực hiện nhanh chóng; đó là công việc của xlate_dev_mem_ptr(và unxlate_dev_mem_ptrhoàn tác bất cứ điều gì xlate_dev_mem_ptr). Sau đó, hàm copy_from_userđọc từ bộ đệm được truyền đếnwritegọi hệ thống và chỉ ghi vào địa chỉ ảo nơi bộ nhớ vật lý hiện đang được ánh xạ. Mã này phát ra các hướng dẫn lưu trữ bộ nhớ thông thường và điều này có nghĩa là tùy thuộc vào phần cứng.

Trước khi tôi thảo luận về việc ghi vào địa chỉ thực, tôi sẽ thảo luận về kiểm tra xảy ra trước khi viết. Bên trong vòng lặp, các page_is_allowedkhối chức năng truy cập vào một số địa chỉ nhất định nếu tùy chọn cấu hình kernel CONFIG_STRICT_DEVMEMđược bật (đó là trường hợp theo mặc định): chỉ có thể truy cập các địa chỉ được phép devmem_is_allowedthông qua /dev/mem, đối với các địa chỉ khác thì không thể ghi bằng EPERM (không được phép thao tác). Mô tả của tùy chọn này nêu:

Nếu tùy chọn này được bật và IO_STRICT_DEVMEM = n, tệp / dev / mem chỉ cho phép không gian người dùng truy cập vào không gian PCI và mã vùng và dữ liệu BIOS. Điều này là đủ cho dosemu và X và tất cả người dùng phổ biến của / dev / mem.

Đây là mô tả rất x86 trung tâm. Trên thực tế, nói chung hơn, CONFIG_STRICT_DEVMEMchặn truy cập vào các địa chỉ bộ nhớ vật lý ánh xạ tới RAM, nhưng cho phép truy cập vào các địa chỉ không ánh xạ tới RAM. Chi tiết về phạm vi địa chỉ vật lý nào được phép tùy thuộc vào kiến ​​trúc bộ xử lý, nhưng tất cả chúng đều loại trừ RAM nơi lưu trữ dữ liệu của hạt nhân và quy trình đất của người dùng. Tùy chọn bổ sung CONFIG_IO_STRICT_DEVMEM(bị vô hiệu hóa kể từ Ubuntu 18.04) chặn truy cập vào các địa chỉ vật lý được yêu cầu bởi trình điều khiển.

Bộ nhớ vật lý địa chỉ ánh xạ tới RAM . Vì vậy, có địa chỉ bộ nhớ vật lý không ánh xạ tới RAM? Đúng. Đó là cuộc thảo luận mà tôi đã hứa ở trên về ý nghĩa của việc viết vào một địa chỉ.

Một hướng dẫn lưu trữ bộ nhớ không nhất thiết phải ghi vào RAM. Bộ xử lý phân tách địa chỉ và quyết định thiết bị ngoại vi nào sẽ gửi cửa hàng tới. (Khi tôi nói bộ xử lý của bộ xử lý, tôi bao gồm các bộ điều khiển ngoại vi có thể không đến từ cùng một nhà sản xuất.) RAM chỉ là một trong những thiết bị ngoại vi đó. Làm thế nào công văn được thực hiện rất phụ thuộc vào kiến ​​trúc bộ xử lý, nhưng các nguyên tắc cơ bản ít nhiều giống nhau trên tất cả các kiến ​​trúc. Bộ xử lý về cơ bản phân tách các bit cao hơn của địa chỉ và tìm kiếm chúng trong một số bảng được điền dựa trên thông tin được mã hóa cứng, thông tin thu được bằng cách thăm dò một số xe buýt và thông tin được cấu hình bởi phần mềm. Rất nhiều bộ đệm và bộ đệm có thể được tham gia, nhưng tóm lại, sau khi phân tách này,xe buýt và sau đó đến các thiết bị ngoại vi để đối phó với nó. (Hoặc kết quả của việc tra cứu bảng có thể là không có thiết bị ngoại vi tại địa chỉ này, trong trường hợp đó, bộ xử lý sẽ chuyển sang trạng thái bẫy trong đó nó thực thi một số mã trong kernel thường dẫn đến SIGBUS cho quá trình gọi.)

Cửa hàng tới một địa chỉ ánh xạ tới RAM không phải là bất kỳ thứ gì khác ngoài ghi đè lên giá trị được lưu trữ trước đó tại địa chỉ này, với lời hứa rằng tải sau đó tại cùng địa chỉ sẽ trả lại giá trị được lưu trữ cuối cùng. Nhưng ngay cả RAM cũng có một vài địa chỉ không hoạt động theo cách này: nó có một vài thanh ghi có thể kiểm soát những thứ như tốc độ làm mới và điện áp.

Nói chung, việc đọc hoặc ghi vào thanh ghi phần cứng sẽ làm bất cứ điều gì phần cứng được lập trình để làm. Hầu hết các truy cập vào phần cứng đều hoạt động theo cách này: phần mềm (thông thường là mã hạt nhân) truy cập vào một địa chỉ vật lý nhất định, điều này đến được bus kết nối bộ xử lý với thiết bị ngoại vi và thiết bị ngoại vi thực hiện công việc của nó. Một số bộ xử lý (cụ thể là x86) cũng có các hướng dẫn CPU riêng biệt gây ra đọc / ghi vào các thiết bị ngoại vi khác với tải và lưu trữ bộ nhớ, nhưng ngay cả trên x86, nhiều thiết bị ngoại vi được truyền qua tải / lưu trữ.

Lệnh dd if=/dev/urandom of=/dev/memghi dữ liệu ngẫu nhiên vào bất kỳ thiết bị ngoại vi nào được ánh xạ tại địa chỉ 0 (và các địa chỉ tiếp theo, miễn là ghi thành công). Trong thực tế, tôi hy vọng rằng trên nhiều kiến ​​trúc, địa chỉ vật lý 0 không có bất kỳ ngoại vi nào được ánh xạ tới nó, hoặc có RAM, và do đó lần thử ghi đầu tiên đã thất bại. Nhưng nếu có một thiết bị ngoại vi được ánh xạ ở địa chỉ 0 hoặc nếu bạn thay đổi lệnh để ghi thành một địa chỉ khác, bạn sẽ kích hoạt một cái gì đó không thể đoán trước trong thiết bị ngoại vi. Với dữ liệu ngẫu nhiên khi tăng địa chỉ, không có khả năng làm điều gì đó thú vị, nhưng về nguyên tắc, nó có thể tắt máy tính (có thể có một địa chỉ thực tế này), ghi đè lên một số cài đặt BIOS khiến nó không thể khởi động hoặc thậm chí không chạm được lỗi ngoại vi theo cách làm hỏng nó.

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

Cảm ơn bạn! Đây là những gì tôi đang tìm kiếm! Tôi chỉ bối rối liệu / dev / mem có cho phép bộ nhớ truy cập vào những thứ như thiết bị ngoại vi và những thứ liên quan đến phần cứng không!
Coder14

Một thiết bị ngoại vi không thể được ánh xạ tại địa chỉ vật lý 0 trên x86 pc; cấu hình đó sẽ không bao giờ khởi động.
Joshua

Điều này không đúng
Yvain 27/07/19

1
Tất nhiên bạn có thể làm hỏng kernel nhưng không phải bios
Yvain 27/07/19

1
@Yvain Điều gì không đúng? Và thực sự bạn không thể làm hỏng kernel nếu CONFIG_STRICT_DEVMEMđược bật.
Gilles 'SO- ngừng trở thành ác quỷ'

12

Nó an toàn, nếu bạn có kernel được cấu hình đúng (an toàn vì nó không hoạt động)

Trên mỗi trang hướng dẫn mem (4) :

/ dev / mem là một tệp thiết bị ký tự là hình ảnh của bộ nhớ chính của máy tính. Nó có thể được sử dụng, ví dụ, để kiểm tra (và thậm chí vá) hệ thống.

Vì vậy, về mặt lý thuyết, dd if=/dev/urandom of=/dev/memnên ghi đè lên toàn bộ không gian địa chỉ của bộ nhớ vật lý mà bạn đã cài đặt và vì kernel và các chương trình khác chạy từ bộ nhớ nên điều này sẽ làm sập hệ thống một cách hiệu quả. Trong thực tế, có giới hạn. Từ cùng một trang người đàn ông:

Kể từ Linux 2.6.26 và tùy thuộc vào kiến ​​trúc, tùy chọn cấu hình hạt nhân CONFIG_STRICT_DEVMEM giới hạn các khu vực có thể được truy cập thông qua tệp này.

Thử điều này trên máy ảo Ubuntu 18.04, nó trả về lỗi dd: writing to '/dev/mem': Operation not permittedngay cả khi có sudovà mặc dù có quyền cho root crw-r-----. Từ Ubuntu Wiki :

/ dev / mem bảo vệ

Một số ứng dụng (Xorg) cần truy cập trực tiếp vào bộ nhớ vật lý từ không gian người dùng. Các tập tin / dev / mem đặc biệt tồn tại để cung cấp quyền truy cập này. Trước đây, có thể xem và thay đổi bộ nhớ kernel từ tệp này nếu kẻ tấn công có quyền truy cập root. Tùy chọn kernel CONFIG_STRICT_DEVMEM được giới thiệu để chặn truy cập bộ nhớ không phải thiết bị (tên ban đầu là CONFIG_NONPROMISC_DEVMEM).

Về mặt kỹ thuật, không có gì là không an toàn (vì nó sẽ làm sập hệ thống) và nếu tùy chọn kernel CONFIG_STRICT_DEVMEMbị vô hiệu hóa thì đó là một lỗ hổng bảo mật, nhưng từ đó tôi thấy lệnh này sẽ không chạy nếu tùy chọn đó được bật. Theo trùng lặp chéo trang , khởi động lại sẽ khắc phục mọi sự cố với nó, nhưng tất nhiên dữ liệu trong RAM tại thời điểm đó sẽ bị mất và không bị xóa vào đĩa (nếu có).

Có một phương pháp được đề xuất trên bản sao được liên kết trước đó bằng cách sử dụng busybox devmemvì vậy nếu bạn quyết tâm làm hỏng RAM, có thể có một cách sau tất cả.


6
Đây là an toàn. Không, chắc chắn là không. Ngay cả với CONFIG_STRICT_DEVMEM, bạn có thể truy cập các vùng bộ nhớ nơi ánh xạ ngoại vi, đó là toàn bộ điểm có /dev/mem. Nếu bạn viết công cụ ngẫu nhiên cho các thiết bị ngoại vi, bất cứ điều gì có thể xảy ra. Bạn không được phép hoạt động trên mạng nếu bạn cố truy cập vào một địa chỉ không được ánh xạ và lệnh bắt đầu tại địa chỉ 0. Việc địa chỉ 0 có ánh xạ tới thứ gì đó xấu hay không phụ thuộc vào kiến ​​trúc phần cứng. Đối với tất cả tôi biết nó có thể không bao giờ ánh xạ tới bất cứ thứ gì trên PC, nhưng nói chung nó không an toàn.
Gilles 'SO- đừng trở nên xấu xa'

1
@Gilles Trên x86 (không chắc chắn về x86-64), 1 KiB RAM đầu tiên (địa chỉ 0x0 đến 0x3ff) giữ các vectơ ngắt; giá trị bốn byte của địa chỉ trên mỗi vector. Nếu bạn thành công trong việc ghi đè những thứ có rác ngẫu nhiên, tất cả các loại điều thú vị có thể sẽ xảy ra rất sớm. Nhiều khả năng, bạn sẽ kết thúc với một lỗi kép hoặc gấp ba và hệ thống sẽ gặp sự cố, nhưng không có gì đảm bảo ...
một CVn

@aCVn Chắc chắn có thứ gì đó được ánh xạ ( head -c 1024 </dev/mem | od -tx1), nhưng tôi không biết liệu chúng có được sử dụng khi bộ xử lý không ở chế độ thực (chế độ 8088). Tôi không nghĩ rằng chúng có thể được sử dụng ở chế độ 64 bit: sau tất cả, các vectơ ngắt 8088 chỉ có 32 bit cho địa chỉ. Và bằng cách này có thể truy cập được với CONFIG_STRICT_DEVMEMtập hợp, vì vậy tôi đoán Linux không sử dụng nó.
Gilles 'SO- ngừng trở thành ác quỷ'

@Gilles: Trang 0 trên x86 được dành riêng cho v86, bộ nạp khởi động, v.v; đó là bảng vector ngắt chế độ thực ở đó. Trong chế độ được bảo vệ, IVT ở một nơi khác (một thanh ghi máy cho biết ở đâu).
Joshua
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.