파일 열기, 분기 등을 방지하는 Linux의 샌드 박스에서 신뢰할 수없는 C 프로그램을 실행 하시겠습니까?


110

Linux의 샌드 박스에서 신뢰할 수없는 C 프로그램을 실행하는 방법이 있는지 궁금합니다. 프로그램이 파일이나 네트워크 연결을 열지 못하도록 막거나 분기, exec 등을 차단하는 것이 있습니까?

서버에 업로드되고 단위 테스트가 실행되는 작은 프로그램, 숙제 일 것입니다. 따라서 프로그램은 수명이 짧습니다.


이것은 5 분 동안 한 번 실행해야하는 단일 C 프로그램입니까, 아니면 지속적으로 실행해야하는 것입니까?
bwawok 2010

업로드되고 단위 테스트가 실행되는 작은 프로그램입니다. 따라서 프로그램은 수명이 짧습니다.
Frank

시스템은 어떤 배포를 사용합니까? 일부 배포에는 샌드 박싱을위한 기성 도구가 있습니다. 시스템에 SELinux 또는 AppArmor와 같은 보안 모델이 활성화되어 있습니까?
thkala 2010

Fedora 13을 사용하고 있습니다. SELinux Sandbox 정책을 조사 중입니다. 다른 옵션이 있는지 궁금합니다.
Frank

답변:


47

Systrace 를 사용 하여 신뢰할 수없는 프로그램을 대화 형 및 자동 모드로 샌드 박스 했습니다. ptrace()특별한 권한없이 Linux 시스템에서 사용할 수 있는 기반 백엔드와 커널 패치가 필요한 훨씬 더 빠르고 강력한 백엔드가 있습니다.

를 사용하여 유닉스 계열 시스템에서 샌드 박스를 만드는 것도 가능 chroot(1)하지만 그렇게 쉽지도 안전하지는 않습니다. Linux 컨테이너FreeBSD jail 은 chroot에 대한 더 나은 대안입니다. Linux의 또 다른 대안은 SELinux 또는 AppArmor 와 같은 보안 프레임 워크를 사용하는 것입니다. 이것이 제가 프로덕션 시스템을 위해 제안하는 것입니다.

당신이하고 싶은 것이 정확히 무엇인지 말씀하시면 더 많은 도움을 드릴 수 있습니다.

편집하다:

Systrace는 귀하의 경우에 적합하지만 AppArmor 또는 SELinux와 같은 Linux 보안 모델을 기반으로하는 것이 더 표준이므로 배포에 따라 선호되는 대안 이라고 생각합니다 .

편집 2 :

chroot(1)대부분의 (모든?) 유닉스 계열 시스템에서 사용할 수 있지만 몇 가지 문제가 있습니다.

  • 그것은 깨질 수 있습니다. 실제로 시스템에서 신뢰할 수없는 C 프로그램을 컴파일하거나 실행하려는 경우 특히이 문제에 취약합니다. 그리고 당신의 학생들이 나와 같은 사람이라면 누군가가 감옥에서 탈출하려고 할 것입니다.

  • 작업에 필요한 모든 것이 포함 된 완전한 독립 파일 시스템 계층을 만들어야합니다. chroot에 컴파일러가있을 필요는 없지만 컴파일 된 프로그램을 실행하는 데 필요한 모든 것이 포함되어야합니다. 이를 돕는 유틸리티가 있지만 여전히 사소한 것은 아닙니다.

  • chroot를 유지해야합니다. 독립적이기 때문에 chroot 파일은 배포와 함께 업데이트되지 않습니다. chroot를 정기적으로 다시 만들거나 필요한 업데이트 도구를 포함해야합니다.이 경우 본질적으로 완전한 Linux 배포판이어야합니다. 또한 시스템 및 사용자 데이터 (암호, 입력 파일 등)를 호스트 시스템과 동기화 상태로 유지해야합니다.

  • chroot()파일 시스템 만 보호합니다. 악성 프로그램이 네트워크 소켓을 열거 나 잘못 작성된 것이 사용 가능한 모든 리소스를 빨아들이는 것을 막지는 않습니다.

자원 사용 문제는 모든 대안에서 일반적입니다. 파일 시스템 할당량 은 프로그램이 디스크를 채우는 것을 방지합니다. 적절한 ulimit( setrlimit()C에서) 설정은 메모리 남용 및 포크 폭탄으로부터 보호 할 수있을뿐만 아니라 CPU 돼지를 막을 수 있습니다. nice(1)더 중요하다고 생각되는 모든 작업에 문제없이 컴퓨터를 사용할 수 있도록 해당 프로그램의 우선 순위를 낮출 수 있습니다.


systrace는 간단한 프로그램을 위해 저를 위해 일했지만 GCC가 GNU를 (1)로 실행하면 무기한 멈췄습니다. 그래서 포기했습니다. systrace의 수정되지 않은 버그입니다 : forum.soft32.com/linux/…
pts

공유 메모리, 메시지 큐 및 세마포가 샌드 박스 프로세스간에 공유되지 않도록하는 방법이 있습니까?
daveagp 2014 년

1
systrace 링크가 끊어졌습니다.
Collin

2
Firejail은 어떻습니까? 더 이상 fs를 사용하여 유지할 필요가 없습니다.
m3nda

18

최근 에 Linux에서 샌드 박스 기술에 대한 개요를 작성했습니다 . 가장 쉬운 방법은 포크 등을 신경 쓰지 않는다면 Linux 컨테이너 (lxc)를 사용하는 것입니다.이 환경에서는 실제로 중요하지 않습니다. 프로세스에 읽기 전용 루트 파일 시스템, 격리 된 루프백 네트워크 연결을 제공 할 수 있으며 여전히 쉽게 종료하고 메모리 제한 등을 설정할 수 있습니다.

코드가 메모리를 할당 할 수 없기 때문에 Seccomp는 약간 어려울 것입니다.

Selinux는 다른 옵션이지만 컨테이너보다 더 많은 작업이 될 수 있다고 생각합니다.


6

Qemu를 사용하여 과제를 빠르게 테스트 할 수 있습니다. 아래 절차는 5 년 된 랩톱에서 5 초도 채 걸리지 않습니다.

학생이 "-1"줄이 도착할 때까지 각 줄에 서명되지 않은 int를 사용하는 프로그램을 개발해야한다고 가정 해 보겠습니다. 그런 다음 프로그램은 모든 int의 평균을 내고 "Average : % f"를 출력해야합니다. 프로그램을 완전히 분리하여 테스트하는 방법은 다음과 같습니다.

  1. 먼저 root.binJslinux 에서 가져 와서 사용자 영역으로 사용할 것입니다 (tcc C 컴파일러가 있음).

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

  2. 학생의 제출물을에 넣고 싶으 root.bin므로 루프 장치를 설정합니다.

    sudo losetup /dev/loop0 root.bin

    (이 경우에도 fuseext2를 사용할 수 있지만 매우 안정적이지 않습니다. 안정화되면 루트가 필요하지 않습니다.)

  3. 빈 디렉토리 만들기 :

    mkdir mountpoint

  4. 마운트 root.bin:

    sudo mount /dev/loop0 mountpoint

  5. 마운트 된 파일 시스템 입력 :

    cd mountpoint.

  6. 권리 수정 :

    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. 제출을 VM에 복사합니다.

    cp ~/student_assignment.c root/assignment.c

  11. VM의 루트 FS를 종료합니다.

    cd ..

  12. sudo umount mountpoint
  13. 이제 이미지가 준비되었으므로 실행하기 만하면됩니다. 부팅 후 제출을 컴파일하고 실행합니다.
  14. mkfifo /tmp/guest_output
  15. 별도의 터미널을 열고 게스트 출력 수신을 시작합니다.

    dd if=/tmp/guest_output bs=1

  16. 다른 터미널에서 :

    qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput (방금 Ubuntu 커널을 사용했지만 많은 커널이 작동합니다)

  17. 게스트 출력에 "READY"가 표시되면 qemu 프롬프트에서 VM으로 키를 보낼 수 있습니다. 예를 들어이 과제를 테스트하려면 다음을 수행 할 수 있습니다.

    (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. 지금 Average = 12.000000 게스트 출력 파이프에 나타납니다. 그렇지 않으면 학생은 실패한 것입니다.

  19. qemu 종료 : quit

테스트를 통과 한 프로그램은 https://stackoverflow.com/a/14424295/309483 입니다. tcclib.h대신 사용하십시오 stdio.h.


5

사용자 모드 Linux를 사용해보십시오 . CPU 집약적 인 작업의 경우 약 1 %의 성능 오버 헤드가 있지만 I / O 집약적 인 작업의 경우 6 배 더 느릴 수 있습니다.


4

Firejail은이를위한 가장 포괄적 인 도구 중 하나입니다. seccomp, 파일 시스템 컨테이너, 기능 등을 지원합니다.

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


이 답변은 훌륭합니다. Firejail이 훌륭한 문서로 적극적으로 유지 관리되고 다른 모든 답변은 아니지만 대부분을 포함하며 상대적으로 사용하기 쉽도록 설계되었다는 점을 고려할 때 더 많은 찬성 할 가치가 있습니다.
Jeff Hykin apr

3

가상 머신 내에서 실행하면 원하는 모든 보안 및 제한이 제공됩니다.

QEMU 는 이에 적합 할 것이며 모든 작업 (응용 프로그램 다운로드, 디스크 이미지 업데이트, QEMU 시작, 내부 응용 프로그램 실행 및 나중에 검색 할 수 있도록 출력 저장)은 자동화 된 테스트 실행을 위해 스크립팅 될 수 있습니다.


2
OP에 대해 잘 모르지만 테스트 프로그램별로 VM을 시작하는 것은 많은 경우에 허용되지 않습니다. 제 환경에서는 (저는 TA입니다) 2 시간 내에 각각 10-12 개의 프로그램을 제출하는 200 명의 학생이있을 수 있습니다. CPU 시간이 10 초 이상 실행되는 프로그램은 없지만 제출물이 쌓이면 15 분 이상의 처리 시간이 걸립니다. 각 프로그램에 VM을 도입하면 CPU 시간이 프로그램 당 60 초 이상으로 늘어날 수 있으며 처리 시간에 대해 전혀 생각하고 싶지 않습니다. 세션 당 VM 일 수도 있지만 프로그램별로 수행 할 수있는 방법은 없습니다 ...
thkala

@thkala 이것은 좋은 지적입니다. QEMU의 아이디어가 마음에 들지만 제출할 때마다 VM을 시작하는 것은 좋지 않습니다.
Frank

이 경우 항상 동일한 VM을 계속 실행하십시오.
Laurent Parenteau 2010

모두 부팅되고 코드를 컴파일 및 실행할 준비가 된 VM의 스냅 샷을 사용하여 무언가를 할 수 있습니까? 참고로, VM은 반드시 피어싱에 면역성이있는 것은 아닙니다. 또한 이것의 하드웨어 버전을 구축 할 수 있습니다. 읽기 전용 미디어 나 네트워크를 통해 재개 이미지를 부팅하고 네트워크 또는 직렬을 통해 출력을 제공 한 다음 다음에 재부팅되는 작은 시스템입니다. 몇 초 안에 리눅스를 시작할 수있는 빠른 부팅 기능이 있습니다.
Chris Stratton

@thkala : 즉, 연속적으로 실행하는 경우 제출 당 3 초 미만이 필요합니다. 내가 게시 한 접근 방식은 현대 컴퓨터에서 (연속적으로) 약 3 초가 소요됩니다. 병렬화하면 (당신도 마찬가지 일 것입니다) 충분히 빠릅니다.
Janus Troelsen 2013 년

3

ptrace (strace) 체크 아웃을 기반으로하는 sanboxing에 관한 경우 :

" sydbox "샌드 박스 및 " pinktrace "프로그래밍 라이브러리 (C99이지만 내가 아는 한 python 및 ruby에 대한 바인딩이 있습니다).

주제와 관련된 수집 된 링크 :

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

(직접 링크는 아니지만 아직 평판 포인트가 충분하지 않습니다.)



1

이 라이브러리는 목표에 잘 부합해야합니다.

http://sandbox.sourceforge.net

행운을 빕니다!


8
이것은 적극적으로 유지되지 않는 것 같습니다. 또한 Linux 커널 패치가 필요한 것 같습니다. 최신 버전이 2003 년으로 거슬러 올라간다는 점을 고려하면 거의 쓸모가 없습니다.
thkala


-1

좋아, 그들이 나를 많이 도왔던 모든 답변 덕분에. 그러나 나는 그들 중 누구도 원래 질문을 한 사람에게 해결책으로 제안하지 않을 것입니다. 언급 된 모든 도구는 교사, 교사, 교수로서 학생들의 코드를 테스트하기 위해 많은 작업을 필요로합니다. 이 경우 가장 좋은 방법은 내 생각에 virtualbox입니다. 좋아, 그것은 완전한 x68 시스템을 에뮬레이트하고 이런 식으로 샌드 박싱의 의미와 관련이 없지만 프로그래밍 선생님을 상상한다면 그에게 가장 좋을 것입니다. 그래서 "apt-get install virtualbox"는 데비안 기반 시스템에 있고 다른 모든 시스템은 http://virtualbox.org/로 이동합니다. 로 이동하여 VM을 만들고 iso를 추가하고 설치를 클릭 한 다음 잠시 기다렸다가 운이 좋습니다. 사용자 모드 리눅스를 설정하거나 무거운 strace 작업을 수행하는 것보다 훨씬 더 쉽게 사용할 수 있습니다.

그리고 만약 당신이 당신의 학생들이 당신을 해킹하는 것에 대한 두려움이 있다면, 당신은 권위 문제가있는 것 같고, 그에 대한 해결책은 그들이주는 일에서 단지 한 입의 악성 코드를 증명할 수 있다면 그들로부터 살아있는 일광을 고소 할 것이라고 위협 할 것입니다. 당신...

또한 클래스가 있고 그것의 1 %가 그가 그런 일을 할 수있는만큼 좋다면, 그런 간단한 작업으로 그들을 지루하게하지 말고 그들이 더 많은 코드를 작성해야하는 큰 것들을 제공하십시오. 통합 학습은 모든 사람에게 가장 적합하므로 오래된 교착 상태 구조에 릴레이하지 마십시오 ...

또한 웹 검색 및 소프트웨어 테스트와 같은 작업에 사용하는 중요한 작업 (예 : 증명 및 시험 작성)에 동일한 컴퓨터를 사용하지 마십시오.

중요한 일에는 오프라인 컴퓨터를 사용하고 다른 모든 일에는 온라인 컴퓨터를 사용하십시오.

그러나 편집증 교사가 아닌 다른 모든 사람들에게 (누구도 화를 내고 싶지는 않습니다. 저는 프로그래머 교사가되기 전에 보안과 우리 사회에 대한 기본을 배워야한다는 의견 일뿐입니다 ...)

... 다른 모든 사람들을 위해 ...

해피 해킹 !!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.