Saya bertanya-tanya apakah ada cara untuk menjalankan program C yang tidak tepercaya di bawah kotak pasir di Linux. Sesuatu yang akan mencegah program membuka file, atau koneksi jaringan, atau forking, exec, dll?
Ini akan menjadi program kecil, tugas pekerjaan rumah, yang diunggah ke server dan tes unit dijalankan di atasnya. Jadi, program tersebut akan berumur pendek.
Jawaban:
Saya telah menggunakan Systrace ke program sandbox yang tidak tepercaya baik secara interaktif maupun dalam mode otomatis. Ini memiliki
ptrace()
backend berbasis yang memungkinkan penggunaannya pada sistem Linux tanpa hak khusus, serta backend yang jauh lebih cepat dan lebih kuat yang membutuhkan patch kernel.Dimungkinkan juga untuk membuat kotak pasir pada sistem mirip Unix menggunakan
chroot(1)
, meskipun itu tidak semudah atau seaman. Linux Containers dan FreeBSD jail adalah alternatif yang lebih baik untuk chroot. Alternatif lain di Linux adalah menggunakan kerangka keamanan seperti SELinux atau AppArmor , yang akan saya usulkan untuk sistem produksi.Kami akan dapat membantu Anda lebih banyak jika Anda diberi tahu seperti apa sebenarnya yang ingin Anda lakukan.
EDIT:
Systrace akan bekerja untuk kasus Anda, tetapi saya pikir sesuatu yang didasarkan pada Model Keamanan Linux seperti AppArmor atau SELinux lebih standar, dan dengan demikian lebih disukai, alternatif, tergantung pada distribusi Anda.
EDIT 2:
Meskipun
chroot(1)
tersedia di sebagian besar (semua?) Sistem mirip Unix, ia memiliki beberapa masalah:Itu bisa dipatahkan. Jika Anda benar-benar akan mengkompilasi atau menjalankan program C yang tidak tepercaya di sistem Anda, Anda sangat rentan terhadap masalah ini. Dan jika murid-murid Anda seperti saya, seseorang AKAN mencoba untuk keluar dari penjara.
Anda harus membuat hierarki sistem file independen penuh dengan semua yang diperlukan untuk tugas Anda. Anda tidak perlu memiliki kompiler di chroot, tetapi apapun yang diperlukan untuk menjalankan program yang dikompilasi harus disertakan. Meskipun ada utilitas yang membantu hal ini, itu tetap tidak sepele.
Anda harus mempertahankan chroot. Karena independen, file chroot tidak akan diperbarui bersama dengan distribusi Anda. Anda harus membuat ulang chroot secara teratur, atau menyertakan alat pembaruan yang diperlukan di dalamnya, yang pada dasarnya memerlukan distribusi Linux yang lengkap. Anda juga harus menyimpan data sistem dan pengguna (kata sandi, file input, dll) yang disinkronkan dengan sistem host.
chroot()
hanya melindungi sistem file. Itu tidak mencegah program jahat dari membuka soket jaringan atau yang ditulis dengan buruk dari menyedot setiap sumber daya yang tersedia.Masalah penggunaan sumber daya adalah umum di antara semua alternatif. Kuota sistem file akan mencegah program mengisi disk. Pengaturan yang tepat
ulimit
(setrlimit()
di C) dapat melindungi dari penggunaan memori yang berlebihan dan serangan fork, serta menghentikan CPU hogs.nice(1)
dapat menurunkan prioritas program tersebut sehingga komputer dapat digunakan untuk tugas-tugas yang dianggap lebih penting tanpa masalah.sumber
Saya menulis gambaran umum tentang teknik sandboxing di Linux baru-baru ini. Saya pikir pendekatan termudah Anda adalah menggunakan wadah Linux (lxc) jika Anda tidak keberatan tentang forking dan sebagainya, yang tidak terlalu penting di lingkungan ini. Anda dapat memberikan proses tersebut sistem file root hanya baca, koneksi jaringan loopback terisolasi, dan Anda masih dapat membunuhnya dengan mudah dan mengatur batas memori, dll.
Seccomp akan menjadi agak sulit, karena kode tersebut bahkan tidak dapat mengalokasikan memori.
Selinux adalah opsi lain, tetapi saya pikir ini mungkin lebih berhasil daripada wadah.
sumber
Anda dapat menggunakan Qemu untuk menguji tugas dengan cepat. Prosedur di bawah ini membutuhkan waktu kurang dari 5 detik pada laptop saya yang berusia 5 tahun.
Mari kita asumsikan siswa harus mengembangkan program yang mengambil int unsigned, masing-masing pada barisnya sendiri, sampai baris dengan "-1" tiba. Program kemudian harus menghitung rata-rata semua int dan output "Rata-rata:% f". Inilah cara Anda dapat menguji program yang sepenuhnya terisolasi:
Pertama, dapatkan
root.bin
dari Jslinux, kita akan menggunakannya sebagai userland (memiliki compiler-C tcc):wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin
Kami ingin memasukkan kiriman siswa
root.bin
, jadi siapkan perangkat loop:sudo losetup /dev/loop0 root.bin
(Anda juga dapat menggunakan fuseext2 untuk ini, tetapi tidak terlalu stabil. Jika stabil, Anda tidak memerlukan root untuk semua ini)
Buat direktori kosong:
mkdir mountpoint
Mount
root.bin
:sudo mount /dev/loop0 mountpoint
Masuk ke sistem file yang terpasang:
cd mountpoint
.Memperbaiki hak:
sudo chown -R `whoami` .
mkdir -p etc/init.d
vi etc/init.d
:chmod +x etc/init.d/rcS
Salin kiriman ke VM:
cp ~/student_assignment.c root/assignment.c
Keluar dari VM root FS:
cd ..
sudo umount mountpoint
mkfifo /tmp/guest_output
Buka terminal terpisah dan mulai dengarkan keluaran tamu:
dd if=/tmp/guest_output bs=1
Di terminal lain:
qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput
(Saya baru saja menggunakan kernel Ubuntu di sini, tetapi banyak kernel akan berfungsi)Jika guest output menampilkan "READY", Anda dapat mengirim kunci ke VM dari prompt qemu. Misalnya, untuk menguji tugas ini, Anda bisa melakukannya
Sekarang
Average = 12.000000
akan muncul di pipa keluaran tamu. Jika tidak, siswa tersebut gagal.quit
Program yang lulus tes ada di sini: https://stackoverflow.com/a/14424295/309483 . Gunakan saja,
tcclib.h
bukanstdio.h
.sumber
Coba Linux mode Pengguna . Ini memiliki sekitar 1% overhead kinerja untuk pekerjaan intensif CPU, tetapi mungkin 6 kali lebih lambat untuk pekerjaan intensif I / O.
sumber
Firejail adalah salah satu alat paling komprehensif untuk melakukannya - ini mendukung seccomp, wadah sistem file, kemampuan, dan lainnya:
https://firejail.wordpress.com/features-3/
sumber
Menjalankannya di dalam mesin virtual harus menawarkan semua keamanan dan batasan yang Anda inginkan.
QEMU akan cocok untuk itu dan semua pekerjaan (mengunduh aplikasi, memperbarui gambar disk, memulai QEMU, menjalankan aplikasi di dalamnya, dan menyimpan keluaran untuk pengambilan nanti) dapat dibuat skrip untuk pengujian otomatis.
sumber
Ketika membahas sanboxing berdasarkan ptrace (strace), periksa:
" sydbox " sandbox dan " pinktrace " pustaka pemrograman (ini C99 tetapi ada binding ke python dan ruby sejauh yang saya tahu).
Tautan yang terkumpul terkait dengan topik:
http://www.diigo.com/user/wierzowiecki/sydbox
(maaf itu bukan tautan langsung, tetapi belum cukup poin reputasi)
sumber
seccomp dan seccomp-bpf menyelesaikan ini dengan sedikit usaha: https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
sumber
Perpustakaan ini harus memenuhi tujuan Anda dengan baik
http://sandbox.sourceforge.net
Semoga berhasil!
sumber
Ini juga tampaknya menjanjikan. Kotak pasir sistem file untuk Linux menggunakan penyadapan syscall.
https://github.com/adtac/fssb
sumber
ok terima kasih untuk semua jawaban mereka banyak membantu saya. Tetapi saya akan menyarankan tidak satupun dari mereka sebagai solusi untuk orang yang mengajukan pertanyaan asli. Semua alat yang disebutkan membutuhkan banyak pekerjaan untuk tujuan menguji kode siswa sebagai guru, tutor, prof. Cara terbaik dalam hal ini menurut saya virtualbox. Ok, ini mengemulasi sistem x68 lengkap dan tidak ada hubungannya dengan arti sandboxing dengan cara ini tetapi jika saya membayangkan guru pemrograman saya, itu akan menjadi yang terbaik untuknya. Jadi "apt-get install virtualbox" pada sistem berbasis debian, semua yang lain menuju ke http://virtualbox.org/ , buat vm, tambahkan iso, klik install, tunggu beberapa saat dan beruntung. Akan jauh lebih mudah digunakan untuk mengatur mode-pengguna-linux atau melakukan beberapa hal yang berat ...
Dan jika Anda memiliki ketakutan tentang siswa Anda meretas Anda, saya kira Anda memiliki masalah otoritas dan solusi untuk itu akan mengancam mereka bahwa Anda akan menuntut siang hari yang hidup dari mereka jika Anda dapat membuktikan hanya satu gigitan perangkat lunak perusak dalam pekerjaan yang mereka berikan kamu...
Juga jika ada kelas dan 1% darinya adalah sebaik dia bisa melakukan hal-hal seperti itu, jangan membuat mereka bosan dengan tugas-tugas sederhana seperti itu dan beri mereka beberapa tugas besar di mana mereka harus membuat kode lagi. Pembelajaran integratif adalah yang terbaik untuk semua orang, jadi jangan teruskan pada struktur lama yang menemui jalan buntu ...
Dan penyebabnya, jangan pernah menggunakan komputer yang sama untuk hal-hal penting (seperti menulis pengesahan dan ujian), yang Anda gunakan untuk hal-hal seperti menjelajahi web dan menguji perangkat lunak.
Gunakan komputer offline untuk hal-hal penting dan komputer online untuk semua hal lainnya.
Namun untuk semua orang yang bukan guru paranoid (tidak ingin menyinggung siapa pun, saya hanya berpendapat bahwa Anda harus mempelajari dasar-dasar tentang keamanan dan masyarakat kita sebelum Anda mulai menjadi guru programer ...)
... di mana saya ... untuk orang lain:
selamat meretas !!
sumber