Kursus MIT "Keamanan Sistem Komputer". Kuliah 4: “Berbagi Hak Istimewa,” Bagian 2

Institut Teknologi Massachusetts. Kursus Kuliah # 6.858. "Keamanan sistem komputer." Nikolai Zeldovich, James Mickens. Tahun 2014


Keamanan Sistem Komputer adalah kursus tentang pengembangan dan implementasi sistem komputer yang aman. Ceramah mencakup model ancaman, serangan yang membahayakan keamanan, dan teknik keamanan berdasarkan pada karya ilmiah baru-baru ini. Topik meliputi keamanan sistem operasi (OS), fitur, manajemen aliran informasi, keamanan bahasa, protokol jaringan, keamanan perangkat keras, dan keamanan aplikasi web.

Kuliah 1: “Pendahuluan: model ancaman” Bagian 1 / Bagian 2 / Bagian 3
Kuliah 2: "Kontrol serangan hacker" Bagian 1 / Bagian 2 / Bagian 3
Kuliah 3: “Buffer Overflows: Exploits and Protection” Bagian 1 / Bagian 2 / Bagian 3
Kuliah 4: “Pemisahan Hak Istimewa” Bagian 1 / Bagian 2 / Bagian 3

Jadi apa lagi yang kita miliki dalam daftar ini? Proses Memori adalah sesuatu yang terjadi bersamaan dengan prosesnya. Jadi, jika Anda tidak dalam proses ini, maka Anda tidak dapat mengakses memorinya. Memori virtual dengan sempurna meningkatkan isolasi ini bagi kami. Selain itu, mekanisme debug memungkinkan Anda untuk "pop" ke dalam memori proses lain, jika Anda memiliki ID pengguna yang sama

Selanjutnya kita memiliki jaringan. Jaringan di Unix tidak cukup sesuai dengan model yang dijelaskan di atas, sebagian karena fakta bahwa sistem operasi Unix pertama kali dikembangkan, dan kemudian sebuah jaringan muncul, yang segera menjadi populer. Ini memiliki seperangkat aturan yang sedikit berbeda. Oleh karena itu, operasi yang benar-benar perlu kita perhatikan adalah menghubungkan seseorang ke jaringan jika Anda mengelola jaringan, atau mendengarkan beberapa port jika Anda bertindak sebagai server. Anda mungkin perlu membaca atau menulis data pada koneksi ini, atau mengirim dan menerima paket mentah .



Dengan demikian, jaringan di Unix sebagian besar tidak terkait dengan userid . Aturannya adalah siapa pun dapat selalu terhubung ke mesin apa pun atau alamat IP apa pun atau membuka koneksi. Jika Anda ingin mendengarkan port, maka dalam hal ini ada satu perbedaan, yaitu sebagian besar pengguna dilarang mendengarkan port dengan angka di bawah "nilai ajaib" 1024. Pada prinsipnya, Anda dapat mendengarkan port tersebut, tetapi dalam hal ini Anda harus Jadilah pengguna khusus yang disebut "pengguna super" dengan uid = 0 .

Secara umum, di Unix ada konsep administrator, atau superuser, yang diwakili oleh pengidentifikasi uid = 0, yang dapat melewati hampir semua pemeriksaan ini, jadi jika Anda bekerja dengan hak root, Anda dapat membaca dan menulis file, mengubah hak akses ke sana. Sistem operasi akan memungkinkan Anda untuk melakukan ini karena menurutnya Anda harus memiliki semua hak istimewa. Dan Anda benar-benar membutuhkan hak istimewa untuk mendengarkan pada port dengan angka <1024. Apa pendapat Anda tentang pembatasan aneh seperti itu?

Pemirsa: ini mengidentifikasi nomor port tertentu untuk koneksi tertentu, misalnya, untuk http pada port 80.

Profesor: ya, secara default protokol HTTP menggunakan port 80. Di sisi lain, layanan lain dapat menggunakan port dengan angka lebih tinggi dari 1024, mengapa pembatasan ini diperlukan? Apa gunanya di sini?

Pemirsa: karena Anda tidak ingin ada orang yang secara tidak sengaja mendengarkan HTTP Anda.

Profesor: ya. Saya pikir alasannya adalah Anda dulu memiliki banyak pengguna di mesin yang sama. Mereka masuk dengan login mereka, meluncurkan aplikasi mereka, jadi Anda ingin memastikan bahwa beberapa pengguna acak, setelah masuk ke komputer, tidak akan bisa mendapatkan server web yang menjalankannya. Karena pengguna yang terhubung dari luar tidak tahu siapa yang bekerja di port ini, dan mereka hanya terhubung ke port 80. Jika saya ingin memasuki mesin ini dan memulai server web saya sendiri, maka saya hanya mentransfer semua lalu lintas server web ke mobil ini. Ini mungkin bukan rencana yang sangat baik, tetapi itu adalah cara subsistem jaringan Unix mencegah pengguna acak dari mengontrol layanan yang dikenal berjalan pada nomor port rendah ini. Itulah alasan pembatasan semacam itu.



Selain itu, dari sudut pandang membaca dan menulis data koneksi, jika Anda memiliki file deskriptor untuk soket tertentu, maka Unix akan memungkinkan Anda untuk membaca dan menulis data apa pun dalam koneksi TCP atau uTP ini . Dalam mengirim paket mentah , Unix berperilaku seperti paranoid, sehingga tidak akan membiarkan Anda mengirim paket sewenang-wenang melalui jaringan. Ini harus berada dalam konteks koneksi khusus, kecuali Anda memiliki root - hak dan Anda dapat melakukan apa pun yang Anda inginkan.

Jadi, satu pertanyaan menarik yang bisa Anda tanyakan adalah dari mana semua userid ini berasal?

Kita berbicara tentang proses memiliki userid atau groupid . Ketika Anda meluncurkan PS di komputer Anda, Anda pasti akan melihat serangkaian proses dengan nilai uid yang berbeda. Dari mana mereka berasal?

Kami membutuhkan mekanisme untuk memuat semua nilai userid ini. Unix memiliki beberapa panggilan sistem yang dirancang untuk ini. Oleh karena itu, untuk mem-bootstrap nilai pengenal ini, ada fungsi yang disebut setuid (uid) , sehingga Anda dapat menetapkan nomor uid dari beberapa proses saat ini ke nilai ini. Ini sebenarnya operasi berbahaya, seperti semua yang lain dalam tradisi Unix , karena Anda hanya dapat melakukan ini jika uid Anda = 0 . Bagaimanapun, seharusnya begitu.

Jadi, jika Anda adalah pengguna dengan hak root dan memiliki uid = 0 , maka Anda dapat memanggil setuid (uid) dan mengalihkan pengguna ke proses apa pun. Ada beberapa panggilan sistem serupa lainnya untuk menginisialisasi gid terkait proses: ini adalah setgid dan setgroups . Oleh karena itu, panggilan sistem ini memungkinkan Anda untuk mengonfigurasi hak istimewa proses.



Fakta bahwa proses Anda mendapatkan hak akses yang benar ketika Anda masuk ke mesin Unix tidak terjadi karena Anda memiliki ID yang sama dengan proses, karena sistem belum tahu siapa Anda. Sebaliknya, di Unix, ada semacam prosedur masuk ketika protokol SSH secure shell memulai proses untuk siapa saja yang terhubung ke komputer dan mencoba untuk mengotentikasi pengguna.

Jadi, pada awalnya proses login ini dimulai dengan uid = 0 untuk pengguna dengan hak root, dan kemudian, ketika ia menerima nama pengguna dan kata sandi tertentu, ia memeriksanya di database akunnya sendiri. Sebagai aturan, pada Unix, data ini disimpan dalam dua file: / etc / password (karena alasan historis, kata sandi tidak lagi disimpan dalam file ini), dan dalam file / etc / shadow , di mana kata sandi disimpan. Namun, ada tabel di file / etc / password yang menampilkan setiap nama pengguna dalam sistem sebagai nilai integer.

Dengan demikian, nama pengguna Anda dipetakan ke integer tertentu di file / etc / password ini , dan kemudian proses login memeriksa apakah kata sandi Anda benar sesuai dengan file ini. Jika ia menemukan integer uid Anda , maka ia mengatur fungsi setuid ke nilai uid itu dan memulai shell dengan perintah exec (/ bin / sh) . Sekarang Anda dapat berinteraksi dengan shell, tetapi ia bekerja di bawah uid Anda, sehingga Anda tidak akan dapat menyebabkan kerusakan yang tidak disengaja pada mesin ini.



Pemirsa: apakah mungkin untuk memulai proses baru dengan uid = 0 jika uid Anda tidak benar-benar 0?

Profesor: jika Anda memiliki hak akses root, Anda dapat membatasi diri untuk uid lain, menurunkan otoritas Anda, tetapi dalam hal apa pun, Anda dapat membuat proses dengan hanya uid yang sama seperti milik Anda. Tetapi hal itu terjadi karena berbagai alasan Anda ingin meningkatkan hak istimewa Anda. Misalkan Anda perlu menginstal paket, yang Anda perlukan hak akses root .

Ada dua cara untuk mengatur hak istimewa di Unix . Satu yang telah kami sebutkan adalah deskriptor file. Jadi jika Anda benar-benar ingin meningkatkan hak istimewa Anda, maka Anda dapat berbicara dengan seseorang yang bekerja di bawah hak root dan memintanya untuk membuka file ini untuk Anda. Atau Anda perlu menginstal beberapa antarmuka baru, maka asisten ini membuka file untuk Anda dan mengembalikan deskriptor file kepada Anda menggunakan transfer fd . Ini adalah salah satu cara untuk meningkatkan hak istimewa Anda, tetapi itu tidak nyaman karena dalam beberapa kasus ada proses yang berjalan dengan sejumlah besar hak istimewa. Untuk ini, Unix memiliki mekanisme bermasalah yang cerdas namun sekaligus disebut "setuid binaries" . Mekanisme ini adalah executable reguler pada sistem file Unix , kecuali ketika Anda menjalankan exec pada setuid binary, misalnya, / bin / su pada sebagian besar mesin, atau sudo , saat startup.

Sistem Unix yang khas memiliki banyak binari setuid . Perbedaannya adalah bahwa ketika Anda menjalankan salah satu dari binari ini, itu benar-benar mengalihkan userid dari proses ke pemilik biner ini. Mekanisme ini terasa aneh ketika Anda pertama kali melihatnya. Sebagai aturan, cara untuk menggunakannya adalah bahwa "biner" ini kemungkinan besar memiliki pemilik dari 0, karena Anda benar-benar ingin mengembalikan banyak hak istimewa.



Anda ingin mengembalikan hak pengguna super sehingga Anda dapat menjalankan perintah su ini, dan kernel, ketika Anda menjalankan biner ini, akan mengalihkan proses uid ke 0, sehingga program ini sekarang akan melakukan beberapa hal istimewa.

Pemirsa: jika Anda memiliki uid = 0 dan Anda mengubah uid dari semua binari setuid ini ke sesuatu selain 0, dapatkah Anda mengembalikan hak istimewa Anda?

Profesor: tidak, banyak proses tidak akan dapat mengembalikan hak istimewa ketika menurunkan tingkat akses, sehingga Anda mungkin terjebak di tempat ini. Mekanisme ini tidak terikat dengan uid = 0 . Seperti halnya pengguna sistem Unix , Anda dapat membuat file biner apa pun, membangun program, mengompilasinya, dan mengatur bit setuid ini ke program itu sendiri. Itu milik Anda, pengguna, ID pengguna Anda. Dan itu berarti bahwa siapa pun yang menjalankan program Anda akan menjalankan kode ini dengan ID pengguna Anda. Apakah ada masalah dengan ini? Apa yang perlu dilakukan?

Hadirin: yaitu, jika ada kesalahan dalam aplikasi Anda, bisakah seseorang melakukan sesuatu dengan itu, bertindak dengan hak istimewa Anda?

Profesor: benar, itu terjadi jika aplikasi saya "buggy", atau jika itu memungkinkan Anda untuk menjalankan semua yang Anda inginkan. Misalkan saya bisa menyalin shell sistem dan membuatnya setuid untuk saya, tetapi siapa pun dapat menjalankan shell ini di bawah akun saya. Ini mungkin bukan rencana tindakan terbaik. Tetapi mekanisme seperti itu tidak menimbulkan masalah, karena satu-satunya orang yang dapat mengatur bit setuid pada file biner adalah pemilik file ini. Anda, sebagai pemilik file, memiliki hak istimewa uid , sehingga Anda dapat mentransfer akun Anda ke orang lain, tetapi orang lain ini tidak akan dapat membuat biner setuid dengan userid Anda.

Bit setuid ini disimpan di sebelah bit izin ini, yaitu, di setiap inode ada juga bit setuid yang mengatakan apakah file yang dapat dieksekusi ini harus atau jika program beralih ke pemilik uid selama eksekusi.



Ternyata ini adalah mekanisme yang sangat rumit ketika digunakan dengan benar, dan karenanya, kernel mengimplementasikan program dengan benar. Sebenarnya, ini cukup mudah dilakukan, karena hanya satu pemeriksaan dilakukan: jika setuid ini ada, maka proses beralih ke uid . Ini sangat sederhana.

Tetapi menggunakannya dengan aman cukup sulit, karena, seperti yang baru saja ditunjukkan, jika program ini mengandung kesalahan atau melakukan sesuatu yang tidak terduga, maka Anda mendapatkan kemampuan untuk melakukan hal-hal yang sewenang-wenang di bawah uid = 0 atau di bawah uid lainnya. Di Unix, ketika Anda menjalankan program, Anda mewarisi banyak hal dari proses induk Anda.

Misalnya, Anda bisa melewatkan variabel lingkungan ke setuid binari. Faktanya adalah bahwa di Unix Anda dapat menentukan pustaka bersama yang digunakan untuk proses dengan menetapkan variabel lingkungan, dan binari setuid tidak peduli tentang pemfilteran variabel lingkungan ini.

Misalnya, Anda dapat menjalankan bin / su , tetapi menggunakan pustaka bersama untuk fungsi printf , sehingga printf Anda akan mulai ketika bin / su mencetak sesuatu, dan Anda dapat menjalankan shell alih-alih mencetakf.

Ada banyak seluk-beluk yang harus Anda pahami dengan benar tentang ketidakpercayaan program terhadap data yang dimasukkan pengguna. Karena Anda biasanya mempercayai input pengguna, setuid tidak pernah menjadi bagian teraman dari keseluruhan sistem Unix . Ada pertanyaan tentang ini?

Audiens: apakah setuid juga berlaku untuk grup atau hanya untuk pengguna?

Profesor: ada bit setgid yang simetris dengan bit setuid , yang bisa Anda atur juga. Jika file tersebut memiliki gid tertentu dan bit setgid ini diatur saat program dimulai, maka Anda akan mendapatkannya.

Setgid tidak digunakan secara khusus, tetapi dapat berguna dalam kasus di mana Anda ingin memberikan hak istimewa yang sangat spesifik. Sebagai contoh, bin / su mungkin membutuhkan banyak hak istimewa, tetapi mungkin ada beberapa program yang memerlukan sedikit hak istimewa tambahan, misalnya, untuk menulis sesuatu ke file log khusus. Oleh karena itu, Anda mungkin ingin memberinya grup tertentu dan membuat file log untuknya yang dapat ditulis oleh grup ini. Jadi, bahkan jika program ini "kereta", maka Anda tidak akan kehilangan apa pun kecuali grup ini. Ini berguna sebagai mekanisme yang karena alasan tertentu tidak digunakan terlalu sering, karena bagaimanapun, orang harus menggunakan hak root lebih banyak.

Hadirin: Apakah ada batasan siapa yang dapat mengubah akses?

Profesor: ya. Implementasi Unix yang berbeda memiliki pemeriksaan yang berbeda untuk ini. Aturan umum adalah bahwa hanya root yang dapat mengubah pemilik file, karena Anda tidak ingin membuat file yang akan menjadi milik orang lain, dan tentu saja Anda tidak ingin menyesuaikan file orang lain. Jadi, jika uid Anda bukan 0, maka Anda mandek. Anda tidak dapat mengubah kepemilikan file apa pun. Jika uid = 0 , Anda memiliki hak akses root dan Anda dapat mengubah pemiliknya menjadi siapa saja. Ada beberapa komplikasi jika Anda memiliki setuid biner dan Anda beralih dari satu uid ke yang lain, ini cukup rumit, tetapi pada dasarnya Anda pada dasarnya tidak dapat mengubah pemilik file jika Anda tidak memiliki hak akses root.

Secara umum, ini adalah sistem yang agak ketinggalan jaman. Anda mungkin dapat membayangkan banyak cara untuk menyederhanakan proses yang dijelaskan di atas, tetapi pada kenyataannya, sebagian besar sistem yang canggih terlihat seperti ini karena mereka berkembang seiring waktu. Tetapi Anda dapat dengan sempurna menggunakan mekanisme ini sebagai "kotak pasir".

Ini hanya semacam prinsip dasar Unix , yang muncul di hampir setiap sistem operasi mirip Unix: Mac OS X , Linux , FreeBSD , Solaris , jika orang lain menggunakannya, dan seterusnya. Tetapi masing-masing sistem ini memiliki mekanisme yang lebih canggih yang dapat Anda gunakan. Misalnya, di Linux ada set "sandbox" COMP , Mac OS X menggunakan "sandbox" Seatbelt . Minggu depan saya akan memberi Anda contoh kotak pasir yang tersedia di setiap sistem berbasis Unix .

Jadi, salah satu mekanisme terakhir, yang akan kami pertimbangkan sebelum masuk ke OKWS , menjelaskan bagaimana Anda harus berurusan dengan binari setuid dan menunjukkan bagaimana Anda dapat melindungi diri dari lubang keamanan yang ada. Masalahnya adalah bahwa Anda pasti akan memiliki beberapa binari setuid pada sistem Anda, seperti / bin / su , atau sudo , atau sesuatu yang lain, dan kemungkinan program Anda akan memiliki kesalahan. Karena itu, seseorang akan dapat menjalankan biner setuid dan prosesnya akan dapat memperoleh akses root , yang tidak ingin Anda izinkan.



Mekanisme Unix , yang sering digunakan untuk mencegah pelaksanaan proses yang berpotensi berbahaya menggunakan setuid binari, adalah dengan menggunakan namespace sistem file untuk mengubahnya menggunakan panggilan sistem chroot , operasi mengubah direktori root. OKWS , sebagai server web yang berspesialisasi dalam menciptakan layanan web yang cepat dan aman, menggunakan ini dengan cukup luas.



Jadi, di Unix, Anda dapat menjalankan chroot di direktori tertentu, jadi mungkin Anda juga dapat menjalankan chroot ("/ foo") .

Ada 2 penjelasan untuk apa chroot tidak. Yang pertama hanya intuitif, artinya setelah menjalankan chroot , direktori root atau direktori yang terletak di belakang slash pada dasarnya setara dengan apa yang digunakan sebelum Anda memanggil chroot . Sepertinya membatasi namespace di bawah / foo Anda . Karena itu, jika Anda memiliki file yang dulu bernama / foo / x , maka setelah memanggil chroot, Anda bisa mendapatkan file ini hanya dengan membuka / x . Jadi batasi namespace Anda hanya untuk subdirektori. Inilah versi intuitifnya.



Tentu saja, dalam keamanan, itu bukan versi intuitif yang penting, tetapi apa sebenarnya yang dilakukan kernel dengan panggilan sistem ini? Dan itu pada dasarnya melakukan dua hal. Pertama, ia mengubah nilai slash ini, jadi kapan pun Anda mengakses atau ketika Anda memulai nama direktori dengan slash, kernel menyertakan file apa pun yang Anda sediakan dengan operasi chroot . Dalam contoh kita, ini adalah file / foo sebelum Anda memanggil chroot , yaitu, kita mendapatkan / = / foo .



Hal berikutnya yang akan coba dilakukan kernel adalah melindungi Anda agar tidak dapat "melarikan diri" dari / jika Anda melakukannya /../ . Karena pada Unix, saya dapat meminta Anda untuk memberi saya, misalnya, /../etc/password . Jadi jika saya menambahkan baris ini seperti ini: /foo/../etc/password , itu tidak akan baik, karena saya bisa keluar / foo dan melanjutkan untuk mendapatkan / etc / password .

Hal kedua yang dilakukan kernel dengan pemanggilan sistem Unix adalah ketika Anda memanggil chroot untuk proses khusus ini, ia mengubah cara /../ dievaluasi dalam direktori ini. Oleh karena itu, ia memodifikasi /../ sehingga / foo menunjuk ke dirinya sendiri. Dengan demikian, ini tidak memungkinkan Anda untuk "melarikan diri", dan perubahan ini hanya berlaku untuk proses ini dan tidak mempengaruhi sisanya. Gagasan apa yang Anda miliki tentang cara "melarikan diri" dari lingkungan chroot menggunakan cara penerapannya?

Menariknya, kernel hanya memonitor satu direktori chroot , jadi Anda mungkin dapat melakukan operasi chroot = (/ foo) , tetapi Anda akan terjebak di tempat ini. Jadi Anda ingin mendapatkan / etc / password , tetapi bagaimana cara melakukannya? Anda dapat membuka direktori root sekarang dengan mengetik open (* / *) . Ini akan memberi Anda deskriptor file yang menggambarkan apa / foo . Kemudian Anda dapat memanggil chroot lagi dan menjalankan chroot (`/ bar) .



, : root /foo , /foo/bar /../ /foo / bar/..



, /foo . fchdir (fd) (*/*) , chdir (..) .





/foo , /../ . /foo , root , .

, , . . Unix root- chroot , chroot . , Unix uid = 0 , chroot . . , , chroot , userid . , Unix , , root , .

, , , . chroot — . .

: , inod , ?

: ! , , , : « inode 23», - hroot . , Unix inode inode , , , root-.

, , , OKWS . , OKWS .

, -, , - , . , , httpd , , Apache .

userid www /etc/password . , , SSL , PHP , . , , , MySQL , . MySQL . MySQL , , , .



, , , MySQL , , .

, , , , . , , , Apache , SSL , , , PHP . , , , .

52:30

:

Kursus MIT "Keamanan Sistem Komputer". 4: « », 2


.

, . ? ? , 30% entry-level , : VPS (KVM) E5-2650 v4 (6 Cores) 10GB DDR4 240GB SSD 1Gbps $20 ? ( RAID1 RAID10, 24 40GB DDR4).

Dell R730xd 2 ? 2 Intel Dodeca-Core Xeon E5-2650v4 128GB DDR4 6x480GB SSD 1Gbps 100 $249 ! . kelas menggunakan server Dell R730xd E5-2650 v4 seharga 9.000 euro untuk satu sen?

Source: https://habr.com/ru/post/id418197/


All Articles