Bagaimana vim mencuri file yang dimiliki root?

39

Saksikan yang berikut ini:

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

Entah bagaimana vim telah mengambil file yang dimiliki oleh root ini, dan mengubahnya menjadi file milik pengguna!

Ini hanya berfungsi jika pengguna memiliki direktori - tetapi rasanya masih tidak mungkin. Adakah yang bisa menjelaskan bagaimana ini dilakukan?

Glenjamin
sumber

Jawaban:

51

Anda,, glenadalah pemilik direktori (lihat .file dalam daftar Anda). Direktori hanyalah daftar file dan Anda memiliki izin untuk mengubah daftar ini (mis. Menambah file, menghapus file, mengubah kepemilikan untuk menjadikannya milik Anda lagi, dll.). Anda mungkin tidak dapat mengubah konten file secara langsung, tetapi Anda dapat membaca dan memutuskan tautan file tersebut secara keseluruhan dan kemudian menambahkan file baru. 1 Hanya menyaksikan sebelum dan sesudah, ini mungkin terlihat seperti file telah diubah.

Vim menggunakan file swap dan memindahkan file di bawah air, sehingga itu menjelaskan mengapa tampaknya menulis ke file yang sama seperti yang Anda lakukan di shell Anda, tetapi itu bukan hal yang sama. 2

Jadi, apa yang Vim lakukan, sampai pada ini:

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 Ini adalah perbedaan penting dalam penanganan izin file antara Windows dan Unices. Di Windows, seseorang biasanya tidak dapat menghapus file yang Anda tidak memiliki izin untuk menulis.

2 pembaruan: seperti yang tercantum dalam komentar, Vim tidak benar-benar melakukannya dengan cara ini untuk mengubah kepemilikan, karena nomor inode pada tempfile tidak berubah (comaring ls -lisebelum dan sesudah). Menggunakan stracekita dapat melihat apa yang vimterjadi. Bagian yang menarik ada di sini:

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

Ini menunjukkan bahwa itu hanya memutuskan tautan , tetapi tidak menutup deskriptor file temp. Agak hanya menimpa seluruh isinya ( more text bla\ndalam kasus saya). Saya kira ini menjelaskan mengapa nomor inode tidak berubah.

gertvdijk
sumber
3
FWIW Anda dapat memverifikasi ini terjadi dengan menjalankan ls -ilsebelum dan sesudah ... jika tempnomor inode berubah, Anda tahu itu file yang berbeda dengan nama yang sama.
berguna
3
Orang dapat menambahkan bahwa rm tidak benar-benar menghapus file, tetapi hanya menghapus tautan ke file, dan file tidak terhapus sebelum jumlah tautan berkurang menjadi 0. rm hanya menghapus entri ke file di direktori. Jika root memiliki tautan lain (tautan keras) ke file di direktori lain, pengguna tidak dapat menghapus file.
gerrit
1
@ Tidak berguna, saya mencoba, dan nomornya tidak berubah meskipun pemilik dan stempel waktu berubah!
amyassin
1
@amyassin Anda benar! Saya telah memperbarui jawaban saya dengan kutipan strace yang menjelaskannya.
gertvdijk
1
Sebagai tambahan untuk catatan Anda tentang izin Windows vs. Unix, jika Anda menginginkan perilaku mirip Windows di Unix, Anda dapat membuat direktori yang dimiliki oleh root (atau pengguna lain yang harus memiliki izin universal remove / rename / etc) dan mengatur sticky bit pada direktori. Maka pengguna hanya akan dapat menghapus file mereka sendiri.
Matthew Crumley
16

sebelum:

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

setelah:

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

Vim tidak menembus penghalang izin. Lihat saja informasi file yang tercantum dengan hati-hati maka Anda bisa mengetahui bahwa vim sebenarnya menghapus file asli (karena Anda memiliki izin untuk menghapus file tersebut meskipun Anda tidak dapat mengubah kontennya) kemudian membuat file baru milik Anda sendiri ( lihat pemilik tidak lagi 'root').

Dan saat Anda mengedit file asli dalam vim, itu memperingatkan bahwa Anda mengubah file read-only. Jadi ketika Anda mengetik perintah :wq!(memaksa operasi), yang dapat dilakukan hanya vim adalah menghapus file yang ada dan membuat file baru yang memiliki nama yang sama.

Semoga itu bisa membantu.

ymfoi
sumber
1

Gunakan -iopsi lsuntuk melihat nomor inode, yang merupakan pengidentifikasi unik (dalam sistem file) file atau objek lain.

Anda akan melihat bahwa file diganti dengan objek yang berbeda: nomor inode kemungkinan akan berubah.

Melihat nomor inode yang sama bukan bukti apa pun: nomor inode dapat didaur ulang. Jika kami menghapus tautan terakhir ke suatu file, dan kemudian membuat file baru, kami mungkin mendapatkannya dengan nomor inode yang sama. Tapi itu tidak bisa terjadi jika file lama dihapus setelah yang baru dibuat. Misalnya mv file file.tmp; touch file; rm file.tmp. Saya menduga vim benar-benar melakukan sesuatu yang analog dengan ini echo new_content > tmpfile; mv tmpfile file. The mvoperasi akan menerjemahkan ke renamesystem call, sehingga penugasan nomor inode tergantung pada bagaimana mengimplementasikan filesystem mengubah nama yang menghapus link tujuan.

Kaz
sumber