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


9

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

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

ตัวอย่างของสิ่งที่ฉันมีอยู่ในใจ:

$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...

คำตอบ:


10

มันเป็นความเสี่ยงด้านความปลอดภัย โดยทั่วไปแล้วทำไมคุณไม่สามารถทำได้เมื่อเปลี่ยนไปใช้บริบทอื่น (การควบคุมระยะไกลของระบบการเปลี่ยนผู้ใช้ ฯลฯ )

หากคุณมีความสามารถในการสร้างตัวแปรสภาพแวดล้อมใด ๆ ที่คุณต้องการมีหลายวิธีที่เป็นไปได้ที่คุณสามารถรันโค้ดโดยพลการ
ใช้$LD_PRELOADเป็นตัวอย่าง หากคุณมีความสามารถในการตั้งค่าตัวแปรนั้นคุณสามารถแทนที่ฟังก์ชั่นห้องสมุดและติดรหัสของคุณได้ คุณสามารถตั้งค่า$DISPLAYตัวแปรและเปลี่ยนเส้นทาง X แสดงโปรแกรมเชื่อมต่อเพื่อให้คุณได้รับการควบคุมของแอป

นี่คือเหตุผลที่สิ่งต่าง ๆ เช่นsudoตัดสภาพแวดล้อมของตัวแปรทั้งหมด sudoอนุญาตให้เลือกตัวแปรเพียงไม่กี่ตัวเท่านั้น และตัวแปรเหล่านั้นมันทำให้พวกมันสะอาด (มันผ่าน$TERMตัวแปร แต่มันจะไม่เกิดขึ้นถ้ามันมีตัวอักษรผิดปกติ)


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

3

ฉันจะบอกว่ามันคือเมื่อทุบตีเป็น / bin / sh ของคุณ มันไม่ใช่คุณสมบัติของ bourne shell และฉันคิดว่ามันไม่ใช่คุณสมบัติของ posix shell เช่นกันในความเป็นจริงพวกเขาอาจต้องการห้ามอย่างชัดแจ้ง

Bash นั้นเป็นเปลือกอนุพันธ์ korn มากกว่าเปลือก bourne แม้จะมีชื่อและเปลือกหอย Korn เพียงเปลือกเดียวที่มีคุณสมบัติและในความคิดของฉันมันคือคุณลักษณะinkinkที่ไม่มีประโยชน์จริง นักพัฒนาที่หลีกเลี่ยงคุณสมบัติทุบตีสำหรับมาตรฐานเช่นเชลล์ bourne, posix shell หรือชุดย่อย ksh88 ที่เชลล์สมัยใหม่มีเหมือนกันหรือกล่าวอีกนัยหนึ่งคือมุ่งมั่นในการปฏิบัติที่ดีและสำนวนมาตรฐานต่างตกใจเมื่อซอฟต์แวร์ของพวกเขาเปิดอยู่ linux และ mac และตอนนี้อาจมีความเสี่ยงเนื่องจากผู้เขียนหาประโยชน์สามารถใช้ 'bashisms' แม้จะมีเจตนา การปรับปรุงความเข้ากันได้เมื่อเรียกใช้เป็น / bin / sh มากกว่าอนุพันธ์เชลล์ korn อื่น ๆ ก็ต่อเมื่อ / bin / sh เป็นเชลล์ล็อกอินของคุณหรือเชลล์แบบโต้ตอบเมื่อ bash ทำงานเหมือนเชลล์ bourne มากกว่า korn เชลล์

ฉันจะพยายามเกลี้ยกล่อมให้คุณรู้ว่ามันเป็นคุณสมบัติอ่างล้างจาน 2 กรณี: คุณเป็นนักพัฒนาที่ฝังตัวซึ่งทำให้อุปกรณ์เช่นเราเตอร์เครือข่ายที่เก็บข้อมูลที่แนบมากับเครือข่ายที่ใหญ่ขึ้นเป็นอันดับที่ 1 env หมายถึงมากขึ้น ผลกำไรที่น้อยลงดังนั้นถ้านี่เป็นเหตุผลที่ควรพิจารณาใช้คุณลักษณะของการทุบตีคุณไม่ควรใช้คุณสมบัติ FPATH และ autoload, ksh88 แทนหรือไม่ แทนที่จะส่งไบต์ฟังก์ชันทั้งหมดสำหรับไบต์ในสภาพแวดล้อม คุณสามารถพิจารณาการแยกวิเคราะห์และตัดสภาพแวดล้อมที่ขายส่งก่อนที่มันจะได้รับไปยัง shellscript ที่อาจทำให้ตัวแปรเข้าใจผิดเช่นเพียงกรอง ^ $ (. *) $ และอื่น ๆ ...

นั่นเป็นการเน้นย้ำว่ามีอะไรพิเศษเกี่ยวกับเรื่องนี้มันไม่สำคัญว่าตัวแปรคืออะไรและสคริปต์ไม่จำเป็นต้องอ้างอิงหรือใช้ตัวแปร แต่ก็อาจมีความเสี่ยงได้

#!/bin/sh
exec /usr/local/myapp/support/someperlscript.pl

สำหรับทุกสิ่งทุกอย่างภายใต้ดวงอาทิตย์สิ่งข้างต้นควรปลอดภัยพอ ๆ กับสคริปต์ Perl คุณไม่ได้ใช้ตัวแปรใด ๆ เปลี่ยนเป็น

#!/bin/bash -norc
exec /usr/local/myapp/support/someperlscript.pl

ไม่ได้ช่วยอะไรอย่างนี้ไม่มีอะไรเกี่ยวข้องกับ ENV หรืออะไรทำนองนี้ - ทุกคนถูกไฟไหม้เพราะทุบตีต้องไม่ซ้ำกัน ความจริงที่ว่ารุ่นทุบตี 2 มีปัญหากับผมพิสูจน์ให้เห็นว่าไม่มีใครเคยใช้คุณลักษณะนี้สำหรับการใช้งานของพวกเขาเพราะมิฉะนั้นก็ควรจะไม่ได้ซุ่มอยู่รอบนี้ยาว และสิ่งที่แย่กว่านั้นคือไม่มีการหลีกเลี่ยงคุณสมบัตินี้ นี่คือตัวอย่างของ: กับ 'su -' ซึ่งถ้าคุณจะถามใครสักคนคำอธิบายก็คือมันจะทิ้งสิ่งแวดล้อมตรวจสอบหน้าคนและคุณจะพบเพียง 99.9% ฉันทดสอบวิธีการที่ถูกต้องเนื่องจากในระบบนี้ / bin / sh เป็นเปลือกเข้าสู่ระบบของรากและ / bin / sh เป็นทุบตีแต่ในตัวอย่างนี้ฉันลองเพื่อทำให้. bash_profile ของฉันแข็งขึ้น ฉันเปลี่ยนชื่อเป็น root (ซึ่งเปิดใช้งาน) แต่ฉันคิดว่าถ้า su แล้วก็เป็น sudo ต่อไปฉันเปลี่ยนเป็น:

exec env -i TERM=vt102 LOGNAME=root USER=root HOME=/var/root /bin/ksh -i

ดังนั้นฉันจริง ๆ tossing สภาพแวดล้อมอย่างสมบูรณ์และใช้ env น้อยที่สุดแล้วเรียกใช้เชลล์ที่ไม่ควรมีปัญหาแทนกระบวนการปัจจุบัน จากนั้นลองใช้ตัวอย่างมาตรฐานแทน:

%dock='() { echo -e "\e[2t\c"; echo dockshock;} ; dock' su 

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

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su - 

และคาดเดาอะไร หน้าต่างถูกดูดเข้าสู่ท่าเรือ นี่คือสิ่งที่ดูเหมือนหลังจากนั้น ..

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
Password:
dockshock
# env
_=/usr/bin/env
HOME=/var/root
LOGNAME=root
TERM=vt102
USER=root
# echo $0
/bin/ksh
#

ดังนั้นมากสำหรับที่! ฟังก์ชั่นที่ส่งออกมีความสำคัญมากกว่าสคริปต์ rc คุณไม่สามารถหลบมันได้


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