เรียกใช้โปรแกรม C ที่ไม่น่าเชื่อถือในแซนด์บ็อกซ์ใน Linux ที่ป้องกันไม่ให้เปิดไฟล์ฟอร์ก ฯลฯ ?


110

ฉันสงสัยว่ามีวิธีเรียกใช้โปรแกรม C ที่ไม่น่าเชื่อถือภายใต้ Sandbox ใน Linux หรือไม่ สิ่งที่จะป้องกันไม่ให้โปรแกรมเปิดไฟล์หรือการเชื่อมต่อเครือข่ายหรือการปลอมแปลง exec ฯลฯ ?

มันจะเป็นโปรแกรมขนาดเล็กการบ้านที่อัปโหลดไปยังเซิร์ฟเวอร์และมีการทดสอบหน่วยที่ดำเนินการอยู่ ดังนั้นโปรแกรมจะมีอายุสั้น


นี่เหมือนกับโปรแกรม C เดียวที่คุณต้องรัน 1 ครั้งเป็นเวลา 5 นาทีหรือสิ่งที่คุณต้องทำงานตลอดเวลา?
bwawok

มันจะเป็นโปรแกรมขนาดเล็กที่ได้รับการอัปโหลดและมีการทดสอบหน่วยที่ดำเนินการอยู่ ดังนั้นโปรแกรมจะมีอายุสั้น
Frank

การกระจายใช้ระบบอะไร? การแจกแจงบางอย่างมีเครื่องมือสำเร็จรูปสำหรับการทำแซนด์บ็อกซ์ ระบบของคุณมีรูปแบบความปลอดภัยเช่น SELinux หรือ AppArmor หรือไม่?
thkala

ฉันใช้ Fedora 13 ฉันกำลังพิจารณานโยบาย SELinux Sandbox ฉันสงสัยว่ามีตัวเลือกอะไรอีกบ้าง
Frank

6
คำถามที่คล้ายกันในกระบวนการแซนด์บ็อกซ์ / การเจลใน Linux หรือ Unix: * unix.stackexchange.com/q/6433/4319 * stackoverflow.com/q/3859710/94687 * stackoverflow.com/q/4410447/94687 * stackoverflow.com/q / 1019707/94687
imz - Ivan Zakharyaschev

คำตอบ:


47

ฉันใช้Systraceเพื่อแซนด์บ็อกซ์โปรแกรมที่ไม่น่าเชื่อถือทั้งแบบโต้ตอบและในโหมดอัตโนมัติ มีptrace()แบ็กเอนด์ตามฐานซึ่งอนุญาตให้ใช้งานบนระบบ Linux โดยไม่มีสิทธิพิเศษรวมถึงแบ็กเอนด์ที่เร็วและมีประสิทธิภาพมากขึ้นซึ่งต้องใช้การแพตช์เคอร์เนล

นอกจากนี้ยังสามารถสร้างแซนด์บ็อกซ์บนระบบที่คล้าย Unix ได้โดยใช้chroot(1)แม้ว่าจะไม่ง่ายหรือปลอดภัยก็ตาม Linux ContainersและFreeBSD jailsเป็นทางเลือกที่ดีกว่าสำหรับ chroot อีกทางเลือกหนึ่งบน Linux คือการใช้กรอบความปลอดภัยเช่นSELinuxหรือAppArmorซึ่งเป็นสิ่งที่ฉันจะเสนอสำหรับระบบการผลิต

เราจะสามารถช่วยคุณได้มากขึ้นหากคุณบอกว่าคุณต้องการทำอะไร

แก้ไข:

Systrace จะใช้งานได้สำหรับกรณีของคุณ แต่ฉันคิดว่าสิ่งที่ใช้Linux Security Modelเช่น AppArmor หรือ SELinux เป็นมาตรฐานที่มากกว่าและเป็นทางเลือกที่ดีกว่าทั้งนี้ขึ้นอยู่กับการแจกจ่ายของคุณ

แก้ไข 2:

แม้ว่าchroot(1)จะมีให้บริการในระบบที่คล้าย Unix ส่วนใหญ่ แต่ก็มีปัญหาเล็กน้อย:

  • มันสามารถแตกออกมา หากคุณกำลังจะคอมไพล์หรือเรียกใช้โปรแกรม C ที่ไม่น่าเชื่อถือในระบบของคุณคุณจะเสี่ยงต่อปัญหานี้เป็นพิเศษ และถ้านักเรียนของคุณเป็นเหมือนของฉันใครบางคนจะพยายามแยกตัวออกจากคุก

  • คุณต้องสร้างลำดับชั้นของระบบไฟล์ที่เป็นอิสระเต็มรูปแบบพร้อมทุกสิ่งที่จำเป็นสำหรับงานของคุณ คุณไม่จำเป็นต้องมีคอมไพเลอร์ใน chroot แต่ควรรวมสิ่งที่จำเป็นในการรันโปรแกรมที่คอมไพล์ไว้ แม้ว่าจะมีโปรแกรมอรรถประโยชน์ที่ช่วยในเรื่องนี้ แต่ก็ยังไม่สำคัญ

  • คุณต้องรักษา chroot เนื่องจากเป็นไฟล์อิสระไฟล์ chroot จะไม่ได้รับการอัปเดตพร้อมกับการแจกจ่ายของคุณ คุณจะต้องสร้าง chroot ใหม่เป็นประจำหรือรวมเครื่องมืออัปเดตที่จำเป็นไว้ด้วยซึ่งโดยพื้นฐานแล้วจะต้องมีการแจกจ่าย Linux ที่สมบูรณ์ คุณจะต้องเก็บข้อมูลระบบและผู้ใช้ (รหัสผ่านไฟล์อินพุต ฯลฯ ) ให้ตรงกับระบบโฮสต์

  • chroot()ปกป้องระบบไฟล์เท่านั้น ไม่ได้ป้องกันโปรแกรมที่เป็นอันตรายจากการเปิดซ็อกเก็ตเครือข่ายหรือโปรแกรมที่เขียนไม่ดีจากการดูดทรัพยากรทั้งหมดที่มีอยู่

ปัญหาการใช้ทรัพยากรเป็นเรื่องปกติของทางเลือกอื่น ๆ โควต้าของระบบไฟล์จะป้องกันไม่ให้โปรแกรมเติมดิสก์ การตั้งค่าulimit( setrlimit()ใน C) ที่เหมาะสมสามารถป้องกันการใช้หน่วยความจำมากเกินไปและส้อมระเบิดใด ๆ รวมทั้งหยุดการทำงานของหมู CPU nice(1)สามารถลดลำดับความสำคัญของโปรแกรมเหล่านั้นลงเพื่อให้สามารถใช้คอมพิวเตอร์สำหรับงานใด ๆ ที่ถือว่าสำคัญกว่าได้โดยไม่มีปัญหา


systrace ทำงานให้ฉันสำหรับโปรแกรมที่เรียบง่าย แต่ติดขัดไปเรื่อย ๆ เมื่อ GNU เป็น (1) ตามที่เรียกใช้โดย GCC ฉันก็เลยยอมแพ้มัน มันเป็นบั๊กที่ไม่มีการแก้ไขใน systrace: forum.soft32.com/linux/…
pts

มีวิธีการตรวจสอบว่าหน่วยความจำที่แบ่งใช้คิวข้อความและเซมาโฟเรสไม่ถูกแบ่งใช้ระหว่างกระบวนการแซนด์บ็อกซ์
daveagp

1
ลิงก์ systrace เสีย
Collin

2
แล้ว Firejail ล่ะ? คุณไม่ต้องรักษา fs อีกต่อไปโดยใช้มัน
m3nda

18

ฉันเขียนภาพรวมของเทคนิคการทำแซนด์บ็อกซ์ใน Linuxเมื่อเร็ว ๆ นี้ ฉันคิดว่าวิธีที่ง่ายที่สุดของคุณคือการใช้คอนเทนเนอร์ Linux (lxc) หากคุณไม่สนใจเรื่องการฟอร์กและอื่น ๆ ซึ่งไม่สำคัญในสภาพแวดล้อมนี้ คุณสามารถกำหนดให้กระบวนการเป็นระบบไฟล์รูทแบบอ่านอย่างเดียวการเชื่อมต่อเครือข่ายลูปแบ็คที่แยกได้และคุณยังสามารถฆ่ามันได้อย่างง่ายดายและตั้งค่าขีด จำกัด หน่วยความจำเป็นต้น

Seccomp จะค่อนข้างยากเนื่องจากโค้ดไม่สามารถจัดสรรหน่วยความจำได้

Selinux เป็นอีกทางเลือกหนึ่ง แต่ฉันคิดว่ามันน่าจะเวิร์คกว่าตู้คอนเทนเนอร์


6

คุณสามารถใช้ Qemu เพื่อทดสอบงานได้อย่างรวดเร็ว ขั้นตอนด้านล่างนี้ใช้เวลาน้อยกว่า 5 วินาทีกับแล็ปท็อปอายุ 5 ปีของฉัน

สมมติว่านักเรียนต้องพัฒนาโปรแกรมที่ใช้ ints ที่ไม่ได้ลงนามแต่ละรายการในบรรทัดของตัวเองจนกว่าบรรทัดที่มี "-1" จะมาถึง จากนั้นโปรแกรมควรเฉลี่ย ints และเอาต์พุตทั้งหมด "Average:% f" นี่คือวิธีที่คุณสามารถทดสอบโปรแกรมที่แยกได้โดยสิ้นเชิง:

  1. ขั้นแรกรับroot.binจาก Jslinux เราจะใช้สิ่งนั้นเป็น userland (มี tcc C-compiler):

    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. ออกจากรูท FS ของ VM:

    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. เมื่อเอาต์พุตของแขกแสดง "พร้อม" คุณสามารถส่งคีย์ไปยัง VM จากพร้อมต์ qemu ตัวอย่างเช่นหากต้องการทดสอบงานนี้คุณสามารถทำได้

    (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

ลองโหมดผู้ใช้ลินุกซ์ มีค่าใช้จ่ายด้านประสิทธิภาพประมาณ 1% สำหรับงานที่ใช้ CPU มาก แต่อาจช้ากว่า 6 เท่าสำหรับงานที่ต้องใช้ I / O


4

Firejail เป็นหนึ่งในเครื่องมือที่ครอบคลุมที่สุดในการทำเช่นนั้น - รองรับ seccomp คอนเทนเนอร์ระบบไฟล์ความสามารถและอื่น ๆ :

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


คำตอบนี้ยอดเยี่ยมมากสมควรได้รับคะแนนโหวตมากขึ้นเมื่อพิจารณาว่า firejail ได้รับการบำรุงรักษาอย่างแข็งขันด้วยเอกสารที่ยอดเยี่ยมครอบคลุมคำตอบอื่น ๆ ส่วนใหญ่หากไม่ใช่คำตอบอื่น ๆ ทั้งหมดและได้รับการออกแบบมาให้ใช้งานได้ค่อนข้างง่าย
Jeff Hykin

3

การใช้งานภายในเครื่องเสมือนควรให้ความปลอดภัยและข้อ จำกัด ทั้งหมดที่คุณต้องการ

QEMUจะเหมาะสำหรับสิ่งนั้นและงานทั้งหมด (ดาวน์โหลดแอปพลิเคชันอัปเดตภาพดิสก์เริ่มต้น QEMU เรียกใช้แอปพลิเคชันภายในและบันทึกเอาต์พุตเพื่อเรียกคืนในภายหลัง) สามารถเขียนสคริปต์สำหรับการทดสอบอัตโนมัติได้


2
ฉันไม่รู้เกี่ยวกับ OP แต่การเปิด VM ต่อโปรแกรมทดสอบจะไม่เป็นที่ยอมรับในหลาย ๆ กรณี ในสภาพแวดล้อมของฉัน (ฉันเป็น TA) อาจมีนักเรียนมากถึง 200 คนที่ส่งโปรแกรม 10-12 โปรแกรมต่อคนภายในระยะเวลา 2 ชั่วโมง ไม่มีโปรแกรมใดที่รันได้นานกว่า 10 วินาที CPU-time แต่เมื่อการส่งเข้ามาเต็มเราจะได้เวลาหมุนเวียน 15 นาทีขึ้นไป การแนะนำ VM สำหรับแต่ละโปรแกรมจะผลักเวลา CPU ไปที่ 60 วินาทีขึ้นไปต่อโปรแกรมและฉันไม่ต้องการคิดถึงเวลาหมุนเวียนเลย อาจจะเป็น VM ต่อเซสชัน แต่เราไม่สามารถทำสิ่งนั้นต่อโปรแกรมได้ ...
thkala

@thkala นี่คือจุดที่ดี ฉันชอบแนวคิดของ QEMU แต่การเริ่ม VM สำหรับการส่งแต่ละครั้งนั้นไม่ดี
Frank

ในกรณีนี้ให้ VM เดียวกันทำงานตลอดเวลา
Laurent Parenteau

คุณสามารถทำอะไรบางอย่างโดยใช้สแนปชอตของ vm ที่บูตและพร้อมที่จะคอมไพล์และรันโค้ดได้หรือไม่? FYI, vm ไม่จำเป็นต้องมีภูมิคุ้มกันต่อการเจาะ คุณยังสามารถสร้างเวอร์ชันฮาร์ดแวร์ของสิ่งนี้ - ระบบขนาดเล็กที่บู๊ตอิมเมจเรซูเม่จากสื่อแบบอ่านอย่างเดียวหรือผ่านเครือข่ายและให้เอาต์พุตผ่านเครือข่ายหรืออนุกรมจากนั้นจะรีบูตในครั้งต่อไป มีความก้าวหน้าในการบูตอย่างรวดเร็วที่ทำให้ linux ทำงานได้ในไม่กี่วินาที
Chris Stratton

@thkala: นั่นหมายความว่าคุณต้องใช้เวลาน้อยกว่า 3 วินาทีต่อการส่งหนึ่งครั้งหากคุณเรียกใช้แบบต่อเนื่อง วิธีที่ฉันโพสต์อาจใช้เวลาประมาณ 3 วินาทีในเครื่องสมัยใหม่ (ต่อเนื่อง) หากคุณขนานกัน (ซึ่งคุณอาจเช่นกัน) ก็จะเร็วพอ
Janus Troelsen

3

เมื่อพูดถึง sanboxing ตาม ptrace (strace) เช็คเอาต์:

" sydbox sandbox" และ " pinktrace " การเขียนโปรแกรมห้องสมุด (มัน C99 แต่มีการผูกหลามทับทิมและเท่าที่ผมรู้)

รวบรวมลิงค์ที่เกี่ยวข้องกับหัวข้อ:

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

(ขออภัยที่ไม่ใช่ลิงก์โดยตรง แต่ยังไม่มีคะแนนชื่อเสียงเพียงพอ)



1

ห้องสมุดนี้ควรตอบสนองเป้าหมายของคุณได้ดี

http://sandbox.sourceforge.net

โชคดี!


8
ดูเหมือนจะไม่ได้รับการบำรุงรักษาอย่างจริงจัง ดูเหมือนว่าจะต้องใช้แพทช์เคอร์เนลลินุกซ์ซึ่งจะทำให้ส่วนใหญ่ไร้ประโยชน์เมื่อพิจารณาว่าเวอร์ชันล่าสุดมีอายุย้อนไปถึงปี 2546
thkala


-1

โอเคขอบคุณสำหรับคำตอบทั้งหมดที่พวกเขาช่วยฉันได้มาก แต่ฉันไม่อยากจะแนะนำว่าไม่มีข้อใดเป็นทางออกสำหรับผู้ที่ถามคำถามเดิม เครื่องมือที่กล่าวถึงทั้งหมดจำเป็นต้องใช้ในการทดสอบรหัสนักเรียนในฐานะครูติวเตอร์ศ. วิธีที่ดีที่สุดในกรณีนี้คือ virtualbox ในความคิดของฉัน โอเคมันเลียนแบบระบบ x68 ที่สมบูรณ์และไม่มีส่วนเกี่ยวข้องกับความหมายของแซนด์บ็อกซ์ด้วยวิธีนี้ แต่ถ้าฉันนึกภาพครูสอนเขียนโปรแกรมของฉันมันจะดีที่สุดสำหรับเขา ดังนั้น "apt-get install virtualbox" บนระบบที่ใช้เดเบียนคนอื่น ๆ ทั้งหมดตรงไปที่http://virtualbox.org/สร้าง vm เพิ่ม iso คลิกติดตั้งรอสักครู่แล้วจะโชคดี มันจะง่ายกว่ามากในการตั้งค่า user-mode-linux หรือทำของหนัก ๆ ...

และถ้าคุณกลัวว่านักเรียนของคุณจะแฮ็กคุณฉันเดาว่าคุณมีปัญหาเรื่องอำนาจและวิธีแก้ปัญหานั้นอาจเป็นการขู่พวกเขาว่าคุณจะฟ้องพวกเขาที่ยังมีชีวิตอยู่ถ้าคุณสามารถพิสูจน์ได้ว่ามีมาเลแวร์เพียงตัวเดียวในงานที่พวกเขามอบให้ คุณ...

นอกจากนี้หากมีชั้นเรียนและ 1% ของชั้นเรียนนั้นดีเท่าที่เขาจะทำได้อย่าเบื่อพวกเขากับงานง่ายๆเช่นนี้และให้งานใหญ่ ๆ ที่พวกเขาต้องเขียนโค้ดเพิ่มเติม การเรียนรู้เชิงบูรณาการดีที่สุดสำหรับทุกคนดังนั้นอย่าถ่ายทอดโครงสร้างเก่าที่หยุดชะงัก ...

และด้วยเหตุนี้อย่าใช้คอมพิวเตอร์เครื่องเดียวกันในสิ่งที่สำคัญ (เช่นการเขียนคำรับรองและการสอบ) ที่คุณใช้สำหรับสิ่งต่างๆเช่นการท่องเว็บและการทดสอบซอฟต์แวร์

ใช้คอมพิวเตอร์ออฟไลน์สำหรับสิ่งสำคัญและคอมพิวเตอร์ออนไลน์สำหรับสิ่งอื่น ๆ ทั้งหมด

อย่างไรก็ตามสำหรับคนอื่น ๆ ที่ไม่ใช่ครูที่หวาดระแวง (ไม่อยากทำให้ใครขุ่นเคืองฉันแค่เห็นว่าคุณควรเรียนรู้พื้นฐานเกี่ยวกับความปลอดภัยและสังคมของเราก่อนที่คุณจะเริ่มเป็นครูโปรแกรมเมอร์ ... )

... ฉันอยู่ที่ไหน ... สำหรับคนอื่น ๆ :

แฮ็คแฮปปี้ !!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.