Bagaimana sinyal * nix membiarkan Anda membaca memori proses lain

Ada hal * nix yang sangat tua dan mengakar yang disebut "sinyal" . Ide di balik primitif ini sangat sederhana: untuk mengimplementasikan analog perangkat lunak interupsi. Proses yang berbeda dapat mengirim sinyal satu sama lain dan untuk dirinya sendiri, mengetahui proses id (pid) penerima. Proses penerimaan bebas untuk menetapkan fungsi penangan sinyal yang akan dipanggil secara otomatis ketika diterima, atau mengabaikannya menggunakan topeng khusus, atau mempercayai perilaku default. Sejauh ini bagus.



Perilaku Bawaan dalam Menerima Sinyal ... Apa arti kata-kata yang meyakinkan ini? Tidak seperti yang Anda harapkan, tentu. Wiki mengatakan bahwa 28 penangan sinyal default (ada yang lain!) Adalah sebagai berikut: 2 diabaikan, 4 menyebabkan proses berhenti, 1 untuk melanjutkan, 11 untuk mengakhiri, 10 untuk mengakhiri dengan dump memori. Nah, itu menarik! Jadi, situasinya adalah sebagai berikut: bahkan jika program Anda tidak menyebutkan sinyal dengan cara apa pun dalam kode sumber, sebenarnya program itu menggunakannya, dan dengan cara yang sangat dramatis.



Mulai sekarang, kita harus menggali lebih dalam. Siapa yang dapat mengirim sinyal dan kepada siapa? Wiki mengatakan, "Sebuah proses (atau pengguna dari shell) dengan UID efektif selain 0 (superuser UID) hanya dapat mengirim sinyal ke proses dengan UID yang sama." Jadi, jika Anda menjalankan 100 program, maka salah satu dari mereka dapat dengan mudah mematikan semua 100 program ini menggunakan API sistem, bahkan jika semua program (kecuali pembunuh) tidak menyebutkan sinyal dengan cara apa pun dalam kode sumbernya. Jika Anda bekerja di bawah akun root, maka tidak masalah siapa yang memulai proses tertentu, Anda masih dapat dengan mudah mengakhirinya. Hal ini, tentu saja, mungkin untuk menemukan pid dari proses tertentu dan menjalankan "pembunuhan kontrak" nya, tetapi bahkan lebih mudah untuk membunuh semua orang yang hanya dapat berupa pid-s kekerasan.



“Tunggu, tunggu, jangan kendarai kudanya. Anda menyebutkan bahwa sinyal dapat diproses dan diabaikan! " - Saya mendengar suara pembaca saya. Apa yang akan dikatakan Vicki? "Untuk penanganan alternatif dari semua sinyal kecuali SIGKILL dan SIGSTOP, sebuah proses dapat menetapkan penangannya sendiri atau mengabaikan kemunculannya dengan memodifikasi topeng sinyalnya." Kami melihat tindakan default saat menerima sinyal ini dan melihat: "Proses penghentian", "Proses penghentian". Kedua tindakan ini ternyata dapat kami lakukan setiap kali mengirimkan sinyal SIGKILL dan SIGSTOP kepada korban pada prinsipnya memungkinkan. "Satu-satunya pengecualian adalah proses dengan pid 1 (init), yang memiliki hak untuk mengabaikan atau memproses sinyal apa pun, termasuk KILL dan STOP."Kami bahkan mungkin tidak dapat menghentikan salah satu proses sistem yang paling penting sebagai root, tetapi dengan cara yang bersahabat, ini membutuhkan penelitian tambahan.



Nah, gambarannya menjadi sedikit lebih positif, tapi masih suram. Jika Anda memulai suatu proses, maka dijamin dapat menghentikan dan menghentikan banyak proses lainnya. Jika kondisi yang sangat sederhana "pengembang proses penerimaan lupa mengabaikan atau menangani salah satu dari banyak sinyal lainnya" terpenuhi, aplikasi maniak akan dapat menyebabkan proses berakhir dengan dump memori atau melanjutkan proses setelah berhenti. Jika pengembang aplikasi penerima telah menggantung penangannya pada beberapa sinyal, Anda dapat mencoba mengganggu fungsi aplikasi ini dengan mengirimkan sinyal ke sana. Yang terakhir adalah topik untuk diskusi terpisah, karena karena eksekusi penangan yang tidak sinkron, balapan dan perilaku tidak terdefinisi dimungkinkan ...



“Penalaran abstrak sangat keren, tapi mari kita lebih dekat dengan yang spesifik,” seorang pembaca yang menuntut akan memberi tahu saya. OK tidak masalah! Semua pengguna * nix terbiasa dengan program seperti bash. Program ini telah berkembang selama hampir 30 tahun dan memiliki segudang kemungkinan. Mari kita isi dia untuk kejelasan dan mendapatkan beberapa yummy dari ingatannya!



Saya mengambil Ubuntu 16.04.2 rumah saya dari kaki lebar dan menjalankan dua salinan bash 4.3.46 di atasnya. Di salah satunya, saya akan menjalankan perintah hipotetis dengan data rahasia: export password = SECRET. Mari lupakan sejenak tentang file dengan riwayat perintah, di mana kata sandi juga akan ditulis. Di jendela yang sama, ketik perintah ps untuk mengetahui pid dari proses ini - katakanlah, 3580.



Tanpa menutup jendela pertama, mari lanjutkan ke jendela kedua. Perintah ps di dalamnya akan memberikan pid lain dari contoh bash ini - katakanlah, 5378. Hanya untuk kejelasan, dari bash kedua inilah kita akan mengirim sinyal ke perintah pertama kill -SIGFPE 3580. Ya, pembaca yang budiman, ini adalah absurditas lengkap: proses 2 tidak mengatakan apa pun yang berhubungan dengan untuk proses 1, bahwa dalam proses 1 ini terjadi operasi aritmatika yang salah. Jendela berikut muncul di layar:







Kelainan yang diinginkan terjadi dengan pembuatan dump memori, yaitu, bash tampaknya tidak memproses atau mengabaikan sinyal ini. Googling tempat saya mencari tempat pembuangan sampah, saya menemukan jawaban terperinci ( satu , dua). Di Ubuntu saya, situasinya seperti ini: jika aplikasi dari paket standar macet karena sinyal selain SIGABRT, maka dump akan ditransfer ke program Apport. Ini hanya kasus kita! Program ini mengumpulkan file dengan informasi diagnostik dan menampilkan jendela yang ditunjukkan di atas. Situs resminya dengan bangga menyatakan: “Apport mengumpulkan data yang berpotensi sensitif, seperti core dumps, stack trace, dan file log. Mereka dapat berisi sandi, nomor kartu kredit, nomor seri, dan materi pribadi lainnya. " Baiklah, saya ingin tahu di mana kita memiliki file ini? Ya, /var/crash/_bin_bash.1000.crash. Mari kita tarik isinya ke folder somedir: apport-unpack /var/crash/_bin_bash.1000.crash somedir. Selain berbagai hal kecil yang tidak menarik, akan ada memory dump yang diidam-idamkan bernama CoreDump.



Ini dia, momen kebenaran! Mari cari file ini untuk string kata sandi dan lihat apa yang menarik sebagai tanggapan. Perintah Strings CoreDump | grep password akan mengingatkan peretas yang pelupa bahwa sandi adalah RAHASIA. Hebat!



Saya melakukan hal yang sama dengan editor teks favorit saya gedit, mulai mengetik buffer dan kemudian membacanya dari dump. Tidak masalah! Pada saat itu, Vicki berbisik di telinganya dengan peringatan: "Kadang-kadang (misalnya, untuk program yang dijalankan atas nama superuser), memory dump tidak dibuat untuk alasan keamanan." Soooo, mari kita periksa ... Saat menerima sinyal dari root bash, root bash kedua macet dengan pembuatan dump memori, tetapi karena izin (-rw-r ----- dengan pemilik root) tidak lagi semudah membacanya seperti yang sebelumnya dimiliki oleh akun pengguna saya. Nah, jika program pembunuh hipotetis berhasil mengirim sinyal dari UID pengguna super, maka itu dapat menyentuh dump seperti itu.



Pembaca yang teliti mungkin berkomentar, "Sangat mudah bagi Anda untuk menemukan data yang Anda cari di lautan sampah." Itu benar, tetapi saya yakin: jika Anda tahu jenis ikan apa yang ingin Anda tangkap dan di mana ia berenang, maka menemukannya di jaring pembuangan hampir selalu realistis. Misalnya, tidak ada yang mau mendownload paket dengan informasi debugging untuk program yang rusak dan mencari tahu konten variabel yang Anda minati di GDB dengan debugging post-mortem.



Semua ini mungkin terlihat tidak berbahaya, tetapi sebenarnya tidak. Semua tindakan yang saya jelaskan dapat dengan mudah dilakukan oleh program atau skrip yang berjalan dalam mode pengguna, belum lagi tingkat akses yang lebih istimewa. Intinya adalah bahwa hal yang dapat dieksekusi berbahaya dapat dengan mudah meretas program ke kanan dan kiri, dan seringkali juga dengan bebas membaca seluruh memori mereka. Berikut sinyal dan laporan bugnya! Saya yakin bahwa di platform * nix lain dan dengan program penerima lain situasinya serupa, tetapi tentu saja saya tidak akan memeriksanya.



Keberatan mungkin timbul: malware dapat dengan mudah menggunakan alat debugging untuk menarik data yang menarik dari aplikasi. Sungguh. Lalu, mengapa posting ini? Maksud saya adalah: hal pertama yang terlintas dalam pikiran ketika mencoba menghentikan pencurian data dari aplikasi hanyalah batasan alat debugging. Tentunya alat antivirus mendeteksi penggunaan ptrace () sejak awal - ini adalah peristiwa yang sangat mencurigakan. Sinyal adalah masalah lain. Satu proses mengirimkan sinyal standar lainnya - lalu apa? Sekilas, ini adalah peristiwa yang sepenuhnya normal. Namun, seperti yang telah kita lihat, hal ini dapat menyebabkan penghentian aplikasi yang tidak normal, membuat core dump di beberapa folder, yang darinya ia dapat dicoba untuk menariknya.



Ketika saya mencoba membuka halaman login vk.com dan membuang Firefox dengan sinyal fatal yang sama, Firefox macet, tetapi memanggil penangan dump. Sampah dalam format minidump yang rumit disimpan di ~ / .mozilla / firefox / Laporan Kerusakan / {tertunda atau dikirim} dan memerlukan penyelidikan lebih lanjut. Inilah yang akan Anda temukan jika, di jendela pengaturan, klik "Pelajari lebih lanjut" di seberang tanda centang (teks di bawah ini digunakan untuk digantung di www.mozilla.org/ru/privacy/firefox/#crash-reporter ):







« Mozilla Firefox. , Firefox, , URL- , . , , . crash-stats.mozilla.com. . .»Jarang ada sesuatu yang benar-benar enak di URL, tetapi apakah dump berisi kata sandi atau cookie adalah pertanyaan yang bagus!



Pada catatan misterius dan menarik ini, saya akan mengakhirinya. Saya menerima sinyal bahwa saya lupa memproses secara eksplisit.



PS Saya menulis program sederhana dengan penangan sinyal seperti SIGUSR1: mencetak string "1" di layar, masukkan loop tanpa akhir. Saya berharap jika Anda mengirim sinyal SIGUSR1 berkali-kali ke program ini, penangan akan dipanggil berkali-kali, menyebabkan stack overflow. Sayangnya bagi saya, pawang hanya dipanggil sekali. Oke, mari kita tulis penangan serupa untuk sinyal SIGUSR2 dan mengirim dua sinyal berbeda dengan harapan ini akan membuang korban ... Sayangnya, itu juga tidak membantu: setiap penangan dipanggil hanya sekali. Meluap, meluap, tapi tidak meluap!



PS 2. Dalam dunia Windows terdapat semacam sinyal - pesan yang dapat dikirim ke windows . Sangat mungkin bahwa mereka juga dapat digunakan untuk kesenangan dan keuntungan!



Asli diterbitkan di blog saya 05.05.17.



All Articles