มีเชลล์ที่ตรวจสอบเพื่อให้แน่ใจว่ารหัสถูกเซ็นชื่อหรือไม่?


19

ฉันยุ่งกับ PowerShell ในสัปดาห์นี้และพบว่าคุณต้องลงชื่อสคริปต์ของคุณเพื่อให้สามารถทำงานได้ มีฟังก์ชั่นความปลอดภัยที่คล้ายกันใน Linux ที่เกี่ยวข้องกับการป้องกันสคริปต์ bash ไม่ให้ทำงานหรือไม่?

ฟังก์ชั่นเดียวที่คล้ายกับสิ่งนี้ที่ฉันรู้ว่าเป็นของ SSH ที่ต้องการรหัสบางอย่าง


2
ฟังดูคล้ายโซลูชัน ad-hoc เพื่อแพคเกจเซ็นสัญญากับฉัน ฉันไม่ทราบว่า Windows มีแพ็คเกจการเข้ารหัสที่ลงชื่อด้วยวิธี Linux หรือไม่
Wildcard

6
@ leeand00 สคริปต์เป็นกรณีพิเศษของแพคเกจซอฟต์แวร์และฉันไม่เห็นจุดใดที่จะแยกแยะกรณีดังกล่าว
Gilles 'หยุดความชั่วร้าย'

2
กลไกที่ฉันชอบที่สุดก็คือวิธีที่ ChromeOS ทำเช่นนี้ - วางระบบไฟล์เดียวที่ไม่ได้ตั้งค่าสถานะไว้noexecในพาร์ติชันแบบอ่านอย่างเดียวบนอุปกรณ์บล็อกที่ลงชื่อด้วย dm-verity
ชาร์ลส์ดัฟฟี่

1
source.android.com/security/verifiedbootพูดคุยเกี่ยวกับการนำ Android ของคุณสมบัติ (ChromeOS) เริ่มต้น
ชาร์ลส์ดัฟฟี่

1
คุณสามารถพิจารณาทุบตีเป็นพวงของคำสั่งที่สามารถพิมพ์ด้วยตนเองในอินเตอร์เฟสบรรทัดคำสั่ง อะไรคือจุด จำกัด สคริปต์เมื่อคุณสามารถพิมพ์เนื้อหาในบรรทัดคำสั่งได้หรือไม่
Ding-Yi Chen

คำตอบ:


11

หากคุณล็อคความสามารถของผู้ใช้ในการเรียกใช้สคริปต์ผ่านทางsudoคุณสามารถใช้digestฟังก์ชันการทำงานได้
คุณสามารถระบุแฮชของสคริปต์ / ไฟล์เรียกทำงานsudoersที่จะตรวจสอบsudoก่อนที่จะถูกดำเนินการ ดังนั้นแม้ว่าจะไม่เหมือนกับการเซ็นชื่อ แต่ก็ให้การรับประกันขั้นพื้นฐานว่าอย่างน้อยสคริปต์ไม่ได้รับการแก้ไขหากไม่มี sudoers ก็กำลังถูกแก้ไข

หากชื่อคำสั่งถูกขึ้นต้นด้วย Digest_Spec คำสั่งจะจับคู่สำเร็จเท่านั้นหากสามารถตรวจสอบได้โดยใช้การแยกย่อย SHA-2 ที่ระบุ สิ่งนี้อาจเป็นประโยชน์ในสถานการณ์ที่ผู้ใช้ที่เรียกใช้ sudo มีสิทธิ์เข้าถึงการเขียนไปยังคำสั่งหรือไดเรกทอรีหลัก สนับสนุนรูปแบบสรุปย่อยต่อไปนี้: sha224, sha256, sha384 และ sha512 สตริงอาจถูกระบุในรูปแบบ hex หรือ base64 (base64 มีขนาดเล็กกว่า) มียูทิลิตี้หลายตัวที่สามารถสร้างการแยกย่อย SHA-2 ในรูปแบบฐานสิบหกเช่น openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum

http://www.sudo.ws/man/1.8.13/sudoers.man.html


มันจะกุมฉันไว้จนกว่าฉันจะอ่านเกี่ยวกับ SE Linux และทำถูกต้อง
leeand00

13

ใช่และไม่.

การแจกจ่ายซอฟต์แวร์ Linux นั้นค่อนข้างแตกต่างจากการกระจายซอฟต์แวร์ Windows ในโลกลินุกซ์ (ไม่ฝัง) วิธีการหลักในการเผยแพร่ซอฟต์แวร์คือการแจกจ่าย (Ubuntu, Debian, RHEL, Fedora, Arch ฯลฯ ) การแจกจ่ายที่สำคัญทั้งหมดได้ลงนามในแพ็คเกจของพวกเขาอย่างเป็นระบบมาประมาณสิบปีแล้ว

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

ไม่มีกลไกพิเศษที่แยกแพคเกจซอฟต์แวร์ที่ประกอบด้วยสคริปต์เดียวจากชุดซอฟต์แวร์ที่ประกอบด้วยไฟล์ปฏิบัติการดั้งเดิมไฟล์ข้อมูลหรือไฟล์หลายไฟล์ หรือการตรวจสอบลายเซ็นใด ๆ ที่สร้างขึ้นในล่ามสคริปต์ทั่วไปเพราะการตรวจสอบแพคเกจซอฟต์แวร์นั้นเป็นข้อกังวลอย่างสมบูรณ์จากการรันสคริปต์

ฉันคิดว่า Windows ใส่คำอธิบายประกอบไฟล์ที่มีต้นกำเนิดของพวกเขาและต้องการการยืนยันจากผู้ใช้ในการเรียกใช้ไฟล์ที่มีต้นกำเนิด "ดาวน์โหลด" แทนที่จะเป็น "ท้องถิ่น" Linux ไม่มีกลไกคล้ายกันจริงๆ สิ่งที่ใกล้เคียงที่สุดคือการอนุญาตให้ดำเนินการ: ไฟล์ที่ดาวน์โหลดไม่มีสิทธิ์ดำเนินการผู้ใช้จำเป็นต้องเปิดใช้งานอย่างชัดเจน ( chmod +xบนบรรทัดคำสั่งหรือการดำเนินการเทียบเท่าในตัวจัดการไฟล์)


2
FWIW ที่ด้านบนของ PowerShell นี้สามารถกำหนดค่าได้ (โดยการตั้งค่านโยบาย) เพื่อเรียกใช้งานสคริปต์ที่ลงนามเท่านั้นและนโยบายนี้สามารถกำหนดค่าเพื่อให้สคริปต์ทั้งหมดต้องลงนามหรือสคริปต์ "แหล่งกำเนิดระยะไกล" เท่านั้นหรือไม่มีสคริปต์ มันทำงานได้ดีที่สุดในสภาพแวดล้อมโฆษณาด้วยการจัดการที่สำคัญและการจัดการนโยบายกลาง มันสามารถจะข้าม :-)
สตีเฟ่นแฮร์ริส

@StephenHarris ใช่แล้วถ้าคุณตั้งให้มันบายพาส ...
leeand00

@ leeand00 - การเข้ารหัส base64 เห็นได้ชัดว่าทำงานเป็นบายพาส แต่ฉันไม่ทราบว่าปิดใน PowerShell เวอร์ชันใหม่กว่าหรือไม่
Stephen Harris

1
@ leeand00 - ดูdarkoperator.com/blog/2013/3/5//เพื่อความสนุก :-) โดยทั่วไปผ่านสคริปต์ที่เข้ารหัส base64 เป็นพารามิเตอร์ในบรรทัดคำสั่ง :-) ง่ายพอที่จะคลุม!
Stephen Harris

2
SeLinux ใส่คำอธิบายประกอบไฟล์ด้วยต้นกำเนิด มันเป็นหนึ่งในสถานที่หลัก
loa_in_

10

Linux ไม่ได้ให้ความสามารถในการ จำกัด การดำเนินการของสคริปต์ทุบตีตามลายเซ็นดิจิทัล

มีงานบางส่วนในการตรวจสอบความถูกต้องของโปรแกรมเรียกทำงานแบบไบนารี ดูhttps://lwn.net/Articles/488906/สำหรับข้อมูล


โหวตขึ้นสำหรับคำตอบโดยตรงโดยไม่แนะนำให้คนรู้จักทำงานเป็นทีม
user394

8

ในคำว่า "ไม่"

Linux ไม่ได้แยกความแตกต่างระหว่างโปรแกรมเรียกใช้งานและสคริปต์ #!ที่จุดเริ่มต้นคือวิธีที่จะบอกเคอร์เนลว่าโปรแกรมที่จะเรียกใช้ในการประเมินการป้อนข้อมูล แต่มันไม่ได้เป็นวิธีเดียวที่สคริปต์สามารถดำเนินการได้

ตัวอย่างเช่นถ้าฉันมีสคริปต์

$ cat x
#!/bin/sh 
echo hello

จากนั้นฉันก็สามารถรันสิ่งนี้ได้ด้วยคำสั่ง

$ ./x

ที่จะทำให้เคอร์เนลลองและดำเนินการให้ตรวจหาจุด#!แล้วรันอย่างมีประสิทธิภาพ/bin/sh xแทน

อย่างไรก็ตามฉันยังสามารถเรียกใช้ตัวแปรเหล่านี้เช่นกัน:

$ sh ./x
$ bash ./x
$ cat x | sh
$ cat x | bash
$ sh < x

หรือแม้กระทั่ง

. ./x

ดังนั้นแม้ว่าเคอร์เนลพยายามบังคับใช้การลงชื่อที่ execเลเยอร์เราสามารถเลี่ยงสิ่งนี้ได้โดยการเรียกใช้ล่ามโดยใช้สคริปต์เป็นพารามิเตอร์เท่านั้น

ซึ่งหมายความว่ารหัสการลงนามจะต้องอยู่ในล่ามเอง และสิ่งใดที่จะหยุดผู้ใช้ไม่ให้รวบรวมเชลล์ของตนเองโดยไม่มีรหัสการลงนาม?

วิธีการแก้ปัญหามาตรฐานในการนี้จะไม่ใช้การลงนาม แต่จะใช้การควบคุมบังคับ Access (MAC) SELinuxเช่น ด้วยระบบ MAC คุณสามารถระบุสิ่งที่ผู้ใช้แต่ละคนได้รับอนุญาตให้เรียกใช้และเลเยอร์การเปลี่ยนแปลง ตัวอย่างเช่นคุณสามารถพูดว่า "ผู้ใช้ปกติสามารถเรียกใช้อะไรก็ได้ แต่กระบวนการเว็บเซิร์ฟเวอร์และกระบวนการ CGI สามารถเข้าถึงสิ่งต่าง ๆ จาก/var/httpdไดเรกทอรีเท่านั้นทุกอย่างถูกปฏิเสธ"


1
This means that signing code would have to be in the interpreter itself. And what would stop a user from compiling their own copy of a shell without the signing enforcement code?ไม่อนุญาตให้เรียกใช้งานไฟล์ปฏิบัติการที่ไม่ได้ลงนามใด ๆหากผู้ใช้ไม่มีรหัสลงนาม มีโครงการ * ระวังต่าง ๆ สำหรับสิ่งนี้อยู่แล้ว
อัลซี

2

distros ลินุกซ์มักจะมีGnuPG ฟังดูแล้วว่าฉันชอบทุกอย่างที่คุณต้องการคือเสื้อคลุมทุบตีเรียบง่ายที่ตรวจสอบลายเซ็น gpg ที่แยกออกมากับสคริปต์อาร์กิวเมนต์และดำเนินการเพื่อเรียกใช้สคริปต์เท่านั้นหากการตรวจสอบสำเร็จ:

#!/bin/sh
gpgv2 $1.asc && bash "$@"

สิ่งเดียวที่ไม่มีในปัจจุบันคือการเรียกใช้สคริปต์ที่บางคนเพิ่งทำ ... ด้วยตัวเอง ...
leeand00

2

คำถามที่คำนึงถึงทันทีคือ "ทำไมคุณต้องการป้องกันผู้ใช้จากการรันโปรแกรมที่พวกเขาเขียน? " มีความเป็นไปได้หลายอย่าง:

  1. แท้จริงมันเป็นไปไม่ได้เลยที่จะตรวจสอบว่าใครเป็นผู้เขียนรหัสตั้งแต่แรก เจ้าของไฟล์สคริปต์คือใครก็ตามที่บันทึกเนื้อหาของไฟล์นั้นโดยไม่คำนึงว่ามาจากที่ใด ดังนั้นการบังคับใช้ลายเซ็นจึงเป็นเพียงสิ่งทดแทนที่ซับซ้อนสำหรับกล่องโต้ตอบการยืนยัน: "คุณแน่ใจหรือว่าต้องการทำสิ่งนี้?" ใน Linux ส่วนหนึ่งของปัญหานี้ได้รับการแก้ไขอย่างโปร่งใสด้วยแพ็คเกจที่ลงนามและบรรเทาผลกระทบจากความจริงที่ว่าผู้ใช้มีการ จำกัด การเข้าถึงตามค่าเริ่มต้น ผู้ใช้คาดหวังว่าจะรู้ว่าการใช้รหัสของผู้อื่นอาจเป็นอันตรายได้ *
  2. ในหลอดเลือดดำเดียวกันการลงนามสคริปต์เป็นการดำเนินการที่ซับซ้อนกว่าการบันทึกไฟล์ ในกรณีที่ดีที่สุดจะทำให้ผู้ใช้ทราบว่าพวกเขากำลังดำเนินการคล้ายกับการลงนามในเอกสารและควรตรวจสอบสิ่งที่กล่าวก่อนที่จะดำเนินการต่อ เป็นไปได้มากว่ามันจะช่วยให้มั่นใจว่าความเชี่ยวชาญทางเทคนิคในระดับน้อยที่สุดในส่วนของผู้ใช้ที่ได้รับอนุญาตให้เรียกใช้สคริปต์ ในกรณีที่เลวร้ายที่สุดมันแสดงให้เห็นถึงความเต็มใจที่จะกระโดดผ่านชุดยาวของห่วงเพื่อเรียกใช้สิ่งที่พวกเขาต้องการ ความเชี่ยวชาญด้านเทคนิคถูกใช้บน Linux *
  3. มีโอกาสมากขึ้นที่คนจะตรวจจับรหัสอันตรายอย่างชัดเจนเมื่อพิมพ์ / วางชุดคำสั่งในบรรทัดคำสั่งของพวกเขา ตัวอย่างข้อความธรรมดาหมายถึงการคัดลอกและวางมักจะมีขนาดเล็กกว่าชุดคำสั่งที่จำเป็นในการทำสิ่งที่เลวร้ายอย่างถูกต้อง ผู้ใช้ยังสามารถคัดลอกและวางทุกบรรทัดแยกจากกันอย่างระมัดระวังเข้าใจว่าเกิดอะไรขึ้น ด้วยสคริปต์เป็นไปได้ที่ผู้ใช้ไม่เคยดูรหัสเลย นี่อาจเป็นแอปพลิเคชันที่มีประโยชน์ของสคริปต์ที่เซ็นชื่อด้วยค่าใช้จ่ายทั้งหมดของความพึงพอใจหลังจากที่คุณต้องทำ

* นี่อาจเป็นจริงน้อยลงเมื่อผู้คนจำนวนมากเริ่มใช้ Linux


1

เหตุผลที่ระบบมีการพัฒนาที่แตกต่างกันคือ Linux มีคุณลักษณะไฟล์ 'exec' และ Windows ใช้ส่วนขยายของไฟล์เพื่อพิจารณาความสามารถในการปฏิบัติงาน

ดังนั้นใน Windows มันเป็นเรื่องง่ายที่จะหลอกลวงให้ผู้ใช้ในการดาวน์โหลดไฟล์ที่มี ".exe", "ค้างคาว" ขยาย ".scr" ซึ่งจะถูกซ่อนไว้โดยค่าเริ่มต้น การคลิกสองครั้งที่ไฟล์นั้นจะทำให้คุณเรียกใช้รหัสโดยเจตนา ดังนั้นกลไกขนาดใหญ่ของการติดตามต้นทางและการลงนามในการเรียกทำงาน / สคริปต์จึงถูกสร้างขึ้นเพื่อลดความเสี่ยงนี้

บน Linux คุณอาจได้รับไฟล์ให้กับผู้ใช้ แต่คุณไม่สามารถบังคับให้บิต 'exec' ถูกตั้งค่าได้อย่างง่ายดาย นอกจากนี้ยังเป็นไปได้ที่จะทำให้ระบบไฟล์ทั้งหมด 'noexec'

คุณสามารถเรียกใช้สคริปต์อย่างชัดเจนในทุกกรณีโดยการเรียกล่าม คุณสามารถสร้างเชลล์สคริปต์ที่รันไทม์และไพพ์มันลงใน "sh" หรือเรียกใช้ "sh -c"


0

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

bashประเด็นก็คือสิ่งที่ได้อธิบายไว้ในคำตอบที่ขาดการดำเนินการอีกนิดไม่ได้ป้องกันคุณจากการผ่านสคริปต์ดังกล่าวโดยตรงกับ แม้ว่าสคริปต์ดังกล่าวส่วนใหญ่จะเป็นbashสคริปต์ แต่ shebang สามารถระบุโปรแกรมใด ๆ เป็นล่ามได้ ซึ่งหมายความว่าขึ้นอยู่กับผู้ใช้ในการใช้ล่ามที่เหมาะสมหากพวกเขาตัดสินใจที่จะเพิกเฉยต่อซีแมนทิกส์ที่ปฏิบัติการได้

ขณะนี้ไม่มากนี้การป้องกันครอบคลุมสวยมากของการทำงานที่ไม่น่าเชื่อถือใน executables nixes * มีเพียงเคอร์เนลและเปลือก

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

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


โปรแกรมเก็บถาวรจำนวนมากไม่รักษาบิตรันบนไฟล์ที่มี .. ดีนั่นเป็นชนิดของแฮนดิแคปเมื่อคุณต้องการใช้เพื่อเก็บถาวร โชคดีที่tar จะรักษาบิตรันไทม์
pjc50

คุณต้องใช้tar -p แหล่งที่มา
loa_in_

-p, --preserve-permissions, --same-permissionsหมายถึงการดึงข้อมูลเกี่ยวกับการอนุญาตไฟล์ (ค่าเริ่มต้นสำหรับ superuser)
loa_in_

ไม่คุณไม่ต้องการ -p ฉันเห็นสิ่งที่คนหน้าพูด แต่มันไม่ใช่สิ่งที่เกิดขึ้น touch permtest; chmod +x permtest; tar cf permtest.tar.gz permtest; rm permtest; tar xf permtest.tar.gz; ls -l permtest- มันใช้งานได้ที่นี่และฉันไม่ได้รูท
domen

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