Chạy một chương trình C không đáng tin cậy trong hộp cát trong Linux ngăn chương trình đó mở tệp, phân tách, v.v.?


110

Tôi tự hỏi liệu có cách nào để chạy một chương trình C không đáng tin cậy trong hộp cát trong Linux hay không. Điều gì đó có thể ngăn chương trình mở tệp, hoặc kết nối mạng, hoặc phân nhánh, thực thi, v.v.?

Nó sẽ là một chương trình nhỏ, một bài tập về nhà, được tải lên một máy chủ và thực hiện các bài kiểm tra đơn vị trên đó. Vì vậy, chương trình sẽ tồn tại trong thời gian ngắn.


Điều này giống như một chương trình C duy nhất bạn cần chạy 1 lần trong 5 phút, hay thứ gì đó bạn cần chạy liên tục?
bwawok

Nó sẽ là một chương trình nhỏ được tải lên và có các bài kiểm tra đơn vị được thực hiện trên đó. Vì vậy, chương trình sẽ tồn tại trong thời gian ngắn.
Frank

Hệ thống đang sử dụng phân phối nào? Một số bản phân phối có các công cụ làm sẵn cho hộp cát. Hệ thống của bạn có bật bất kỳ mô hình bảo mật nào như SELinux hoặc AppArmor không?
thkala

Tôi đang sử dụng Fedora 13. Tôi đang xem xét chính sách SELinux Sandbox. Tôi đang tự hỏi những lựa chọn khác tồn tại.
Frank

Câu trả lời:


47

Tôi đã sử dụng Systrace để hộp cát các chương trình không đáng tin cậy cả tương tác và ở chế độ tự động. Nó có một chương trình ptrace()phụ trợ dựa trên nền tảng cho phép sử dụng nó trên hệ thống Linux mà không cần các đặc quyền đặc biệt, cũng như một chương trình phụ trợ nhanh hơn và mạnh mẽ hơn yêu cầu vá hạt nhân.

Cũng có thể tạo một hộp cát trên các hệ thống giống Unix bằng cách sử dụng chroot(1), mặc dù điều đó không hoàn toàn dễ dàng hoặc an toàn. Linux ContainersFreeBSD jails là giải pháp thay thế tốt hơn cho chroot. Một giải pháp thay thế khác trên Linux là sử dụng khung bảo mật như SELinux hoặc AppArmor , đó là những gì tôi sẽ đề xuất cho các hệ thống sản xuất.

Chúng tôi sẽ có thể giúp bạn nhiều hơn nếu bạn nói chính xác những gì bạn muốn làm.

BIÊN TẬP:

Systrace sẽ phù hợp với trường hợp của bạn, nhưng tôi nghĩ rằng thứ gì đó dựa trên Mô hình bảo mật Linux như AppArmor hoặc SELinux là tiêu chuẩn hơn và do đó được ưu tiên, thay thế, tùy thuộc vào bản phân phối của bạn.

CHỈNH SỬA 2:

Mặc dù chroot(1)có sẵn trên hầu hết (tất cả?) Các hệ thống giống Unix, nó có một số vấn đề:

  • Nó có thể bị phá vỡ. Nếu bạn đang thực sự biên dịch hoặc chạy các chương trình C không đáng tin cậy trên hệ thống của mình, bạn đặc biệt dễ gặp phải vấn đề này. Và nếu học sinh của bạn giống tôi, ai đó SẼ cố gắng thoát ra khỏi nhà tù.

  • Bạn phải tạo một hệ thống phân cấp hệ thống tệp độc lập đầy đủ với mọi thứ cần thiết cho nhiệm vụ của bạn. Bạn không nhất thiết phải có trình biên dịch trong chroot, nhưng bất kỳ thứ gì cần thiết để chạy các chương trình đã biên dịch đều nên được đưa vào. Mặc dù có những tiện ích hỗ trợ việc này, nhưng nó vẫn không hề nhỏ.

  • Bạn phải duy trì chroot. Vì nó độc lập, các tệp chroot sẽ không được cập nhật cùng với bản phân phối của bạn. Bạn sẽ phải tạo lại chroot thường xuyên hoặc bao gồm các công cụ cập nhật cần thiết trong đó, về cơ bản sẽ yêu cầu nó phải là một bản phân phối Linux toàn diện. Bạn cũng sẽ phải đồng bộ hóa hệ thống và dữ liệu người dùng (mật khẩu, tệp đầu vào, v.v.) với hệ thống máy chủ.

  • chroot()chỉ bảo vệ hệ thống tập tin. Nó không ngăn một chương trình độc hại mở các ổ cắm mạng hoặc một chương trình viết xấu hút mọi tài nguyên có sẵn.

Vấn đề sử dụng tài nguyên là phổ biến trong tất cả các giải pháp thay thế. Hạn ngạch hệ thống tập tin sẽ ngăn các chương trình lấp đầy đĩa. Cài đặt thích hợp ulimit( setrlimit()trong C) có thể bảo vệ chống lại việc sử dụng quá mức bộ nhớ và bất kỳ bom fork nào, cũng như ngăn chặn sự cố CPU. nice(1)có thể giảm mức độ ưu tiên của các chương trình đó để máy tính có thể được sử dụng cho bất kỳ tác vụ nào được coi là quan trọng hơn mà không gặp vấn đề gì.


systrace làm việc cho tôi cho các chương trình đơn giản, nhưng bị mắc kẹt vô thời hạn khi GNU dưới dạng (1) do GCC điều hành. Vì vậy, tôi đã từ bỏ nó. Đó là một lỗi chưa được khắc phục trong systrace: forum.soft32.com/linux/…
pts

Có cách nào để đảm bảo rằng bộ nhớ được chia sẻ, hàng đợi tin nhắn và semaphores không được chia sẻ giữa các quá trình hộp cát không?
daveagp

1
Liên kết systrace bị hỏng.
Collin

2
Còn về Firejail? Bạn không phải duy trì fs bằng cách sử dụng nó nữa.
m3nda

18

Tôi đã viết tổng quan về các kỹ thuật hộp cát trong Linux gần đây. Tôi nghĩ cách tiếp cận dễ dàng nhất của bạn sẽ là sử dụng vùng chứa Linux (lxc) nếu bạn không bận tâm về việc phân nhánh, v.v., điều này không thực sự quan trọng trong môi trường này. Bạn có thể cung cấp cho quy trình một hệ thống tệp gốc chỉ đọc, một kết nối mạng lặp lại cô lập và bạn vẫn có thể dễ dàng loại bỏ nó và đặt giới hạn bộ nhớ, v.v.

Seccomp sẽ có một chút khó khăn, vì mã thậm chí không thể cấp phát bộ nhớ.

Selinux là một lựa chọn khác, nhưng tôi nghĩ nó có thể hoạt động nhiều hơn là một vùng chứa.


6

Bạn có thể sử dụng Qemu để kiểm tra các bài tập một cách nhanh chóng. Quy trình dưới đây mất chưa đến 5 giây trên máy tính xách tay 5 năm tuổi của tôi.

Giả sử sinh viên phải phát triển một chương trình nhận các int không dấu, mỗi int nằm trên dòng riêng của chúng, cho đến khi xuất hiện dòng có "-1". Sau đó, chương trình sẽ lấy giá trị trung bình của tất cả các int và xuất ra "Average:% f". Đây là cách bạn có thể kiểm tra chương trình hoàn toàn bị cô lập:

  1. Đầu tiên, lấy root.bintừ Jslinux, chúng ta sẽ sử dụng nó làm userland (nó có trình biên dịch tcc C):

    wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin

  2. Chúng tôi muốn đưa bài nộp của học sinh vào root.bin, vì vậy hãy thiết lập thiết bị lặp:

    sudo losetup /dev/loop0 root.bin

    (bạn cũng có thể sử dụng fuseext2 cho điều này, nhưng nó không ổn định lắm. Nếu nó ổn định, bạn sẽ không cần root cho bất kỳ điều này)

  3. Tạo một thư mục trống:

    mkdir mountpoint

  4. Gắn kết root.bin:

    sudo mount /dev/loop0 mountpoint

  5. Nhập hệ thống tệp được gắn kết:

    cd mountpoint.

  6. Sửa quyền:

    sudo chown -R `whoami` .

  7. mkdir -p etc/init.d
  8. vi etc/init.d:

    #!/bin/sh
    cd /root
    echo READY 2>&1 > /dev/ttyS0
    tcc assignment.c 2>&1 > /dev/ttyS0
    ./a.out 2>&1 > /dev/ttyS0
    
  9. chmod +x etc/init.d/rcS

  10. Sao chép nội dung gửi tới VM:

    cp ~/student_assignment.c root/assignment.c

  11. Thoát FS gốc của máy ảo:

    cd ..

  12. sudo umount mountpoint
  13. Bây giờ hình ảnh đã sẵn sàng, chúng ta chỉ cần chạy nó. Nó sẽ biên dịch và chạy trình sau khi khởi động.
  14. mkfifo /tmp/guest_output
  15. Mở một thiết bị đầu cuối riêng biệt và bắt đầu nghe đầu ra của khách:

    dd if=/tmp/guest_output bs=1

  16. Trong một thiết bị đầu cuối khác:

    qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput (Tôi vừa mới sử dụng nhân Ubuntu ở đây, nhưng nhiều nhân sẽ hoạt động)

  17. Khi đầu ra của khách hiển thị "SN SÀNG", bạn có thể gửi các khóa tới máy ảo từ lời nhắc qemu. Ví dụ: để kiểm tra bài tập này, bạn có thể làm

    (qemu) sendkey 1
    (qemu) sendkey 4
    (qemu) sendkey ret
    (qemu) sendkey 1
    (qemu) sendkey 0
    (qemu) sendkey ret
    (qemu) sendkey minus
    (qemu) sendkey 1
    (qemu) sendkey ret
    
  18. Bây giờ Average = 12.000000sẽ xuất hiện trên đường ống xuất khách. Nếu không, học sinh đã thất bại.

  19. Thoát qemu: quit

Chương trình vượt qua bài kiểm tra ở đây: https://stackoverflow.com/a/14424295/309483 . Chỉ cần sử dụng tcclib.hthay vì stdio.h.


5

Dùng thử chế độ người dùng Linux . Nó có chi phí hiệu suất khoảng 1% cho các công việc sử dụng nhiều CPU, nhưng nó có thể chậm hơn 6 lần cho các công việc sử dụng nhiều I / O.


4

Firejail là một trong những công cụ toàn diện nhất để làm điều đó - nó hỗ trợ seccomp, vùng chứa hệ thống tệp, khả năng và hơn thế nữa:

https://firejail.wordpress.com/features-3/


Câu trả lời này rất xuất sắc, nó thực sự xứng đáng nhận được nhiều sự ủng hộ hơn vì firejail được duy trì tích cực với tài liệu tuyệt vời, bao gồm hầu hết nếu không phải tất cả các câu trả lời khác và được thiết kế để tương đối dễ sử dụng.
Jeff Hykin

3

Chạy nó bên trong một máy ảo sẽ cung cấp cho bạn tất cả các bảo mật và hạn chế mà bạn muốn.

QEMU sẽ phù hợp cho điều đó và tất cả công việc (tải xuống ứng dụng, cập nhật hình ảnh đĩa, khởi động QEMU, chạy ứng dụng bên trong nó và lưu đầu ra để truy xuất sau này) có thể được viết kịch bản cho các lần chạy kiểm tra tự động.


2
Tôi không biết về OP, nhưng việc khởi chạy một máy ảo cho mỗi chương trình thử nghiệm sẽ không được chấp nhận trong nhiều trường hợp. Trong môi trường của tôi (tôi là kỹ thuật viên), có thể có tới 200 sinh viên nộp 10-12 chương trình mỗi người trong khoảng thời gian 2 giờ. Không có chương trình nào chạy trong thời gian CPU hơn 10 giây, nhưng khi các bài gửi chồng chất lên nhau, chúng tôi nhận được thời gian quay vòng từ 15 phút trở lên. Việc giới thiệu một máy ảo cho mỗi chương trình sẽ đẩy thời gian CPU lên 60 giây hoặc hơn cho mỗi chương trình và tôi không muốn nghĩ về thời gian quay vòng. Có lẽ một VM mỗi phiên, nhưng không có cách nào chúng ta có thể làm điều đó chương trình mỗi ...
thkala

@thkala Đây là một điểm tốt. Tôi thích ý tưởng về QEMU nhưng bắt đầu một máy ảo cho mỗi lần gửi là không tốt.
Frank

Trong trường hợp đó, hãy giữ cho cùng một máy ảo hoạt động mọi lúc.
Laurent Parenteau

Bạn có thể làm gì đó bằng cách sử dụng ảnh chụp nhanh của một vm đã được khởi động và sẵn sàng để biên dịch và chạy mã không? FYI, vm's không nhất thiết phải miễn nhiễm với xuyên không. Bạn cũng có thể xây dựng phiên bản phần cứng của nó - một hệ thống nhỏ khởi động hình ảnh sơ yếu lý lịch từ phương tiện chỉ đọc hoặc qua mạng và cung cấp đầu ra qua mạng hoặc nối tiếp, sau đó được khởi động lại cho lần tiếp theo. Đã có một số tiến bộ khởi động nhanh chóng giúp linux khởi động trong vài giây.
Chris Stratton

@thkala: Điều đó có nghĩa là bạn cần ít hơn 3 giây cho mỗi lần gửi nếu bạn chạy chúng nối tiếp. Cách tiếp cận mà tôi đã đăng có thể mất khoảng 3 giây trên một máy hiện đại (nối tiếp). Nếu bạn song song hóa (mà bạn cũng có thể) thì nó sẽ đủ nhanh.
Janus Troelsen

3

Khi nó nói về sanboxing dựa trên ptrace (strace), hãy kiểm tra:

" Sydbox " sandbox và " pinktrace " lập trình thư viện (đó là C99 nhưng có những cam kết ràng buộc để python và ruby như xa như tôi biết).

Liên kết được thu thập liên quan đến chủ đề:

http://www.diigo.com/user/wierzowiecki/sydbox

(xin lỗi vì không phải là liên kết trực tiếp, nhưng chưa có đủ điểm danh tiếng)



1

Thư viện này sẽ phục vụ tốt mục tiêu của bạn

http://sandbox.sourceforge.net

Chúc may mắn!


8
Điều này dường như không được duy trì tích cực. Nó cũng dường như đòi hỏi một bản vá hạt nhân Linux, mà sẽ làm cho nó hầu như vô dụng xem xét rằng ngày phiên bản mới nhất của nó lại đến năm 2003.
thkala


-1

ok, cảm ơn tất cả các câu trả lời họ đã giúp TÔI rất nhiều. Nhưng tôi sẽ không đề xuất chúng như một giải pháp cho người đã hỏi câu hỏi ban đầu. Tất cả các công cụ được đề cập đòi hỏi phải hoạt động nhiều cho mục đích kiểm tra sinh viên viết mã như một giáo viên, gia sư, prof. Theo tôi, cách tốt nhất trong trường hợp này là hộp thư ảo. Ok, nó mô phỏng một hệ thống x68 hoàn chỉnh và không liên quan gì đến ý nghĩa của sandbox theo cách này nhưng nếu tôi tưởng tượng giáo viên lập trình của mình thì đó sẽ là điều tốt nhất cho ông ấy. Vì vậy, "apt-get install virtualbox" trên các hệ thống dựa trên debian, tất cả những người khác truy cập http://virtualbox.org/ , tạo vm, thêm iso, nhấp vào cài đặt, đợi một chút và may mắn. Nó sẽ dễ sử dụng hơn nhiều khi thiết lập chế độ người dùng-linux hoặc thực hiện một số công việc nặng nề ...

Và nếu bạn lo sợ về việc sinh viên của bạn hack bạn, tôi đoán bạn có vấn đề về thẩm quyền và giải pháp cho điều đó sẽ đe dọa họ rằng bạn sẽ kiện những người đang sống ban ngày ra khỏi họ nếu bạn có thể chứng minh chỉ một chút sơ suất trong công việc họ giao bạn...

Ngoài ra, nếu có một lớp học và 1% trong số đó giỏi như anh ta có thể làm những việc như vậy, thì đừng làm họ với những nhiệm vụ đơn giản như vậy và giao cho họ một số công việc lớn để họ phải viết mã thêm một số thứ nữa. Học tập tích hợp là tốt nhất cho tất cả mọi người, vì vậy đừng tiếp sức trên các cấu trúc cũ đã bế tắc ...

Và vì lẽ đó, đừng bao giờ sử dụng cùng một máy tính cho những việc quan trọng (như viết chứng thực và thi) mà bạn đang sử dụng cho những việc như duyệt web và kiểm tra phần mềm.

Sử dụng máy tính ngoại tuyến cho những việc quan trọng và máy tính trực tuyến cho tất cả những việc khác.

Tuy nhiên, đối với những người khác, những người không phải là một giáo viên hoang tưởng (không muốn xúc phạm bất kỳ ai, tôi chỉ là ý kiến ​​rằng bạn nên tìm hiểu những điều cơ bản về bảo mật và xã hội của chúng ta trước khi bạn bắt đầu trở thành một giáo viên lập trình ...)

... tôi đã ở đâu ... cho những người khác:

hack vui vẻ !!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.