Mengganti flag eksekusi pada sistem Linux. Mengapa ini mungkin?

23

Saat membaca ini , saya menemukan exploit berikut:

% cp /usr/bin/id ~
% chmod -x ~/id
% ls -al ~/id
-rw-r--r-- 1 edd edd 22020 2012-08-01 15:06 /home/edd/id
% ~/id
zsh: permission denied: /home/edd/id
% /lib/ld-linux.so.2 ~/id
uid=1001(edd) gid=1001(edd) groups=1001(edd),1002(wheel)

Cuplikan ini menunjukkan bahwa kita secara sepele dapat menghindar dari izin eksekusi sistem berkas sebagai pengguna biasa yang tidak memiliki hak. Saya menjalankan ini pada Ubuntu 12.04.

Sementara loader Linux adalah objek bersama menurut file (1), itu juga memiliki titik masuk yang memungkinkannya untuk dieksekusi secara langsung. Ketika dijalankan dengan cara ini, loader Linux bertindak sebagai juru bahasa untuk binari ELF.

Pada mesin OpenBSD saya, bagaimanapun, exploit ini tidak efektif, karena Anda tidak dapat menjalankan loader sebagai suatu program. Halaman manual OpenBSD mengatakan: "ld.so sendiri merupakan objek bersama yang awalnya dimuat oleh kernel.".

Coba ini di Solaris 9, dan Anda akan mendapatkan segfault. Saya tidak yakin apa yang terjadi di tempat lain.

Karena itu pertanyaan saya adalah:

  • Mengapa pemuat Linux (ketika dieksekusi langsung) tidak memeriksa atribut filesystem sebelum menafsirkan biner ELF?
  • Mengapa menerapkan mekanisme yang dirancang untuk melarang eksekusi file, jika terlalu sepele? Apakah saya melewatkan sesuatu?
Edd Barrett
sumber
1
Tidak ada alasan bagus, tetapi jika Anda pernah berhasil menghapus sistem Anda libc(saya pernah melakukannya, memutakhirkan kotak Arch), Anda akan berterima kasih atas kekhasan kecil ini.
new123456
1
@ new123456 oh tuhan, saluran IRC setelah peningkatan itu menyakitkan untuk berada di.
Rob
Itu adalah loader , bukan linker.
Stop Harming Monica

Jawaban:

33

Tujuan dari executeizin ini bukan untuk mencegah eksekusi secara umum . Ini adalah (1) untuk memberi tahu progams file mana yang dimaksudkan untuk dieksekusi, dan (2) untuk mencegah eksekusi sebagai pengguna istimewa , ketika bit setuid (dll.) Ditentukan.

Retasan linker kurang eksploit dari yang terlihat. Anda dapat mengeksekusi file yang tidak dapat dieksekusi yang memiliki izin untuk Anda baca dengan lebih mudah:

$ cp unexecutable_file ~/runme
$ chmod +x ~/runme
$ ~/runme

Lihat diskusi ini di forum Arch Linux .

Singkatnya:

Menandai file yang harus dieksekusi

Saat Anda menulis skrip shell, Anda dapat menandainya sebagai executable chmod +x. Ini mengisyaratkan ke shell Anda bahwa Anda ingin dieksekusi (jika tidak semua shell tahu, itu hanya file teks biasa). Shell kemudian dapat menampilkannya di tab-selesai ketika Anda mengetik ./Tab.

Demikian pula: something.ddirektori (misalnya init.d) berisi skrip startup atau control shell yang biasanya dijalankan secara otomatis oleh daemon. Anda mungkin ingin meletakkan komentar atau file README di direktori sebagai file teks biasa. Atau Anda mungkin ingin menonaktifkan sementara salah satu skrip. Anda dapat melakukannya dengan menghapus bit eksekusi untuk file tertentu. Ini memberitahu daemon untuk melewatinya.

Mencegah eksekusi istimewa

The setuidberarti sedikit bahwa ketika Anda menjalankan file tersebut, ia dieksekusi sebagai tertentu pengguna (misalnya root).

Posting forum menjelaskannya dengan baik:

Anda ingin executable menjadi setuid untuk beberapa pengguna, tetapi Anda hanya ingin orang-orang dari grup tertentu dapat menjalankannya sebagai setuid. Mereka masih dapat menjalankannya dengan menyalin, tetapi flag setuid hilang, sehingga mereka akan mengeksekusinya sendiri, bukan pengguna yang memiliki file asli.

Siput mekanik
sumber
2
Terima kasih - Saya mengabaikan fakta bahwa pengguna dapat menyalin file apa pun yang dapat dia baca dan karenanya memilih izin yang sewenang-wenang.
Edd Barrett
bagaimana dengan file dengan mengeksekusi izin tetapi tanpa izin baca?
Lie Ryan
@ LieRyan Bagaimana dengan mereka?
Pasang kembali Monica
@ BrendanLong: Anda jelas tidak bisa menyalinnya, jadi Anda tidak bisa mengubah izinnya. (Tapi mengapa Anda ingin, saya tidak bisa mengatakan - satu-satunya hal yang dapat Anda lakukan dengan salinan itu adalah menjatuhkan izin eksekusi)
MSalters
9

Jika Anda memiliki akses baca ke file, Anda selalu dapat membuat salinannya.

Jika Anda dapat membuat salinan pribadi, Anda selalu dapat menandai bahwa salinan tersebut dapat dieksekusi.

Ini tidak menjelaskan bahaviour dari ld-linux tetapi mengindikasikan bahwa itu mungkin bukan celah keamanan yang sangat berguna.

Jika Anda ingin keamanan yang lebih ketat, pertimbangkan SELinux

RedGrittyBrick
sumber
Ini sangat benar.
Edd Barrett
Itu hanya pertanyaan konseptual. Saya kira Anda dapat mengatur nonexec pada sistem file juga.
Edd Barrett
2

Melihat pertanyaannya sedikit berbeda: seperti yang dikatakan Mechanical Snail, izin eksekusi pada file tidak dimaksudkan untuk mencegah eksekusi. Namun, opsi filesystem "noexec" tidak mencegah eksekusi, dan tidak begitu mudah dielakkan (tidak didukung oleh semua filesystem, tetapi tentunya oleh yang paling populer di linux). Jika administrator ingin mencegah pengguna menjalankan program sendiri, mereka dapat menentukan opsi noexec di direktori home dan tmp, dan yang lainnya di mana pengguna dapat membuat file.

$ mount -o noexec /dev/sdd1 /test
$ cd /test
$ cp /usr/bin/id .
$ ./id
-bash: ./id: Permission denied

Rupanya dulu mungkin untuk menghindari opsi noexec menggunakan trik loader yang disebutkan dalam pertanyaan, tetapi itu diperbaiki di kernel beberapa versi kembali.

Dari http://linux.die.net/man/8/mount :

noexec

Jangan izinkan eksekusi langsung binari apa pun pada sistem file yang dipasang. (Sampai saat ini masih dimungkinkan untuk menjalankan binari menggunakan perintah seperti /lib/ld*.so / mnt / binary. Trik ini gagal sejak Linux 2.4.25 / 2.6.0.)

Randy Orrison
sumber