Melacak executable tanpa izin baca

17

Saya menemukan beberapa perilaku mengejutkan di Ubuntu 14.04 ketika menggunakan stracepada executable, yang saya tidak punya izin baca. Saya ingin tahu apakah ini bug, atau jika beberapa standar mengamanatkan perilaku tidak jelas ini.

Pertama mari kita lihat apa yang terjadi ketika saya memulai executable biasa di latar belakang dan melampirkannya. Seperti yang diharapkan ini bekerja:

$ /bin/sleep 100 &
[2] 8078
$ strace -p 8078
Process 8078 attached
restart_syscall(<... resuming interrupted call ...>

Selanjutnya saya coba dengan executable, yang saya tidak punya izin baca pada:

---x--x--x 1 root root 26280 Sep  3 09:37 sleep*

Melampirkan ke proses yang berjalan ini tidak diizinkan:

$ ./sleep 100 &
[1] 8089
$ strace -p 8089
strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted

Ini juga yang saya harapkan. Pemberian izin eksekusi tanpa izin baca tidak akan banyak gunanya, jika saya bisa melampirkan debugger ke proses dan secara efektif telah membaca izin pada executable seperti itu.

Tetapi jika saya memulai executable di bawah proses yang sudah dilacak, saya diizinkan untuk melakukannya:

$ strace ./sleep 100
execve("./sleep", ["./sleep", "100"], [/* 69 vars */]) = 0
brk(0)                                  = 0x9b7a000

Ini tidak terduga bagi saya. Apakah ini bug keamanan, atau apakah itu fitur yang diamanatkan oleh standar?

kasperd
sumber
3
@ StéphaneChazelas: Intinya adalah dia dapat memotongnya, hanya dengan menggunakannya sebagai argumen untuk strace. Penyebab root tampaknya adalah bahwa pada execvepanggilan, izin baca dari file yang dieksekusi tidak diperiksa lagi jika proses sudah dilacak. Pertanyaannya adalah apakah itu bug keamanan atau fitur yang diamanatkan (jika yang terakhir, saya masih menganggapnya bug keamanan, hanya bug keamanan dari spesifikasinya).
celtschk
@celtschk, maaf, saya membaca pertanyaan terlalu cepat.
Stéphane Chazelas
1
The EPERMtampaknya datang dari get_dumpable()(digunakan juga untuk memeriksa apakah inti dumping diperbolehkan, sehingga "dumpable") dipanggil dari __ptrace_may_access()menelepon dari ptrace_attach()atas kernel/ptrace.c.
ninjalj
Ketika sebuah program sedang berjalan, apakah informasi yang cukup akan tersedia untuk debugger untuk menghasilkan executable yang dapat dijalankan yang berisi kodenya, atau akankah program loader membuang hal-hal seperti perbaikan relokasi yang akan diperlukan untuk membuat program benar-benar berfungsi?
supercat
@supercat Sejauh yang saya tahu, debugger memiliki akses ke satu langkah melalui semua kode mode pengguna yang dieksekusi, termasuk kode relokasi. Dengan tingkat akses seperti itu seharusnya tidak terlalu sulit untuk mereproduksi executable yang berfungsi.
kasperd

Jawaban:

7

Ini bukan jawaban, melainkan kumpulan tautan dan pemikiran kalau-kalau ada orang lain yang ingin belajar juga. Karena ini adalah hal yang cukup menarik.

Jawaban terkait pada Unix & Linux menyebutkan itu (atau dulu, tidak dapat menguji dengan kernel vanilla sekarang) mungkin untuk membuang hanya membaca binari dengan cara ini.

Grsecurity sedang mencoba untuk memperbaiki opsi konfigurasi ini dan tambalan itu sendiri (walaupun mungkin sudah berubah sejak itu)

Komit ini benar-benar membuatnya tampak bahwa, pengembang kernel hanya peduli tentang dumping binari suid.

Tapi sebenarnya dari baris ini saya kira kernel ingin mencegah dumping binari yang tidak terbaca mengenai status SUID. Dan baris ini menunjukkan bahwa biner yang tidak dapat dibuang tidak dapat dilacak.

Jadi pada pandangan pertama tampaknya Anda telah menemukan bug di kernel dengan implikasi keamanan. Tapi saya bukan pengembang kernel, jadi saya tidak bisa mengatakan dengan pasti. Saya akan bertanya di LKML.

Sunting: satu lagi temuan, berkaitan dengan debugger, disebutkan dalam komentar ke posting asli - dari quick stracing (lagi) menurut saya, bahwa gdb menggunakan binari yang dilacak dan /proc/<pid>/mem. Setelah biner yang berjalan tidak dapat dibaca, cat /proc/<pid>/memkembali EPERM. Jika biner dapat dibaca, ia kembali EIO. (Menguji ini di Ubuntu 14.10, yang menjalankan beberapa patch keamanan, jadi ini mungkin berbeda dari kernel vanilla. Sekali lagi saya tidak memiliki kernel vanilla yang berjalan di mana saja berguna :()

Rubah
sumber