Làm thế nào để vim ăn cắp tập tin sở hữu root?


39

Chứng kiến ​​những điều sau:

sh-3.2$ mkdir testcase
sh-3.2$ cd testcase
sh-3.2$ sudo touch temp
sh-3.2$ ls -al
total 0
drwxr-xr-x   3 glen  staff  102 19 Dec 12:38 .
drwxr-xr-x  12 glen  staff  408 19 Dec 12:38 ..
-rw-r--r--   1 root  staff    0 19 Dec 12:38 temp

sh-3.2$ echo nope > temp
sh: temp: Permission denied

sh-3.2$ vim temp
# inside vim
itheivery
# press [ESC]
:wq!
# vim exits

sh-3.2$ ls -al
total 8
drwxr-xr-x   3 glen  staff  102 19 Dec 12:38 .
drwxr-xr-x  12 glen  staff  408 19 Dec 12:38 ..
-rw-r--r--   1 glen  staff    7 19 Dec 12:38 temp

Bằng cách nào đó vim đã lấy tệp sở hữu gốc này và thay đổi nó thành tệp do người dùng sở hữu!

Điều này dường như chỉ hoạt động nếu người dùng sở hữu thư mục - nhưng vẫn cảm thấy như không thể. Bất cứ ai có thể giải thích làm thế nào điều này được thực hiện?

Câu trả lời:


51

Bạn, glenlà chủ sở hữu của thư mục (xem .tệp trong danh sách của bạn). Một thư mục chỉ là một danh sách các tệp và bạn có quyền thay đổi danh sách này (ví dụ: thêm tệp, xóa tệp, thay đổi quyền sở hữu để biến nó thành của bạn một lần nữa, v.v.). Bạn có thể không thể thay đổi trực tiếp nội dung của tệp, nhưng bạn có thể đọc và hủy liên kết (xóa) toàn bộ tệp và thêm tệp mới sau đó. 1 Chỉ chứng kiến ​​trước và sau, điều này có thể trông giống như tập tin đã bị thay đổi.

Vim sử dụng các tệp hoán đổi và di chuyển các tệp xung quanh dưới nước, vì vậy điều đó giải thích tại sao nó dường như ghi vào cùng một tệp như bạn làm trong vỏ của mình, nhưng đó không phải là điều tương tự. 2

Vì vậy, những gì Vim làm, đi xuống này:

cat temp > .temp.swp          # copy file by contents into a new glen-owned file
echo nope >> .temp.swp        # or other command to alter the new file
rm temp && mv .temp.swp temp  # move temporary swap file back

1 Đây là một sự khác biệt quan trọng trong việc xử lý quyền của tệp giữa Windows và Unices. Trong Windows, người ta thường không thể xóa các tệp mà bạn không có quyền ghi.

2 cập nhật: như đã lưu ý trong các bình luận, Vim không thực sự làm theo cách này để thay đổi quyền sở hữu, vì số inode trên temptệp không thay đổi ( ls -litrước và sau). Sử dụng stracechúng ta có thể thấy chính xác những gì vimkhông. Phần thú vị ở đây:

open("temp", O_WRONLY|O_CREAT|O_TRUNC, 0664) = -1 EACCES (Permission denied)
unlink("temp")                               = 0
open("temp", O_WRONLY|O_CREAT|O_TRUNC, 0664) = 4
write(4, "more text bla\n", 14)              = 14
close(4)                                     = 0
chmod("temp", 0664)                          = 0

Điều này cho thấy rằng nó chỉ bỏ liên kết , nhưng không đóng bộ mô tả tệp temp. Nó thay vì chỉ ghi đè lên toàn bộ nội dung của nó ( more text bla\ntrong trường hợp của tôi). Tôi đoán điều này giải thích tại sao số inode không thay đổi.


3
FWIW bạn có thể xác minh điều này đang xảy ra bằng cách chạy ls -iltrước và sau ... nếu tempsố inode thay đổi, bạn biết đó là một tệp khác có cùng tên.
Vô dụng

3
Người ta có thể thêm rằng rm không thực sự xóa tệp mà chỉ xóa một liên kết đến tệp và tệp không bị xóa trước khi số lượng liên kết giảm xuống còn 0. rm chỉ xóa mục nhập vào tệp trong thư mục. Nếu root có một liên kết khác (liên kết cứng) đến tệp trong thư mục khác, người dùng không thể xóa tệp.
gerrit

1
@ Vô dụng tôi đã thử, và con số không thay đổi mặc dù chủ sở hữu và dấu thời gian đã thay đổi!
amyassin

1
@amyassin Bạn nói đúng! Tôi đã cập nhật câu trả lời của mình với một đoạn trích giải thích nó.
gertvdijk

1
Bên cạnh lưu ý của bạn về các quyền của Windows so với Unix, nếu bạn muốn hành vi giống Windows trong Unix, bạn có thể tạo một thư mục thuộc sở hữu của root (hoặc một người dùng khác có quyền xóa / đổi tên / etc phổ biến) và đặt dính bit trên thư mục. Sau đó, người dùng sẽ chỉ có thể xóa các tập tin của riêng họ.
Matthew Crumley

16

trước:

-rw-r--r-- 1 root staff 0 19 Dec 12:38 temp

sau:

-rw-r--r-- 1 glen staff 7 19 Dec 12:38 temp

Các vim không vượt qua hàng rào cho phép. Chỉ cần xem thông tin tệp được liệt kê cẩn thận, sau đó bạn có thể biết rằng vim thực sự đã xóa tệp gốc (vì bạn có quyền xóa tệp mặc dù bạn không thể thay đổi nội dung của tệp đó) sau đó tạo một tệp mới của riêng bạn ( thấy chủ sở hữu không còn là 'root').

Và trong khi bạn đang chỉnh sửa tệp gốc trong vim, nó cảnh báo rằng bạn đang thay đổi tệp chỉ đọc. Vì vậy, khi bạn gõ lệnh :wq!(bắt buộc thao tác), điều vim chỉ có thể làm là xóa tệp hiện có và tạo một tệp mới có cùng tên.

Mong rằng sẽ giúp.


1

Sử dụng -itùy chọn lsđể xem số inode, là số nhận dạng duy nhất (trong hệ thống tệp) của tệp hoặc đối tượng khác.

Bạn sẽ thấy rằng tệp đã được thay thế bằng một đối tượng khác: số inode sẽ có thể thay đổi.

Nhìn thấy cùng một số inode không phải là bằng chứng của bất cứ điều gì: một số inode có thể được tái chế. Nếu chúng tôi xóa liên kết cuối cùng đến một tệp, sau đó tạo một tệp mới, chúng tôi có thể nhận được một liên kết có cùng số inode. Nhưng điều đó không thể xảy ra nếu tập tin cũ bị xóa sau khi tập tin mới được tạo. Ví dụ mv file file.tmp; touch file; rm file.tmp. Tôi nghi ngờ vim thực sự làm một cái gì đó tương tự như thế này echo new_content > tmpfile; mv tmpfile file. Các mvhoạt động sẽ dịch cho một renamecuộc gọi hệ thống, vì vậy việc chuyển nhượng số inode phụ thuộc vào cách các dụng cụ hệ thống tập tin đổi tên mà hủy liên kết một đích.

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.