การตรวจสอบความถูกต้องของไบนารีคำสั่งก่อนดำเนินการ


13

มีวิธีการตรวจสอบสิ่งที่คุณกำลังดำเนินการจากสคริปต์ทุบตีจริง ๆ ?

บอกว่าทุบตีสคริปต์ของคุณจะถูกเรียกหลายคำสั่ง (ตัวอย่างเช่น: tar, mail, scp, mysqldump) และคุณยินดีที่จะให้แน่ใจว่าtarเป็นจริงจริงtarซึ่งเป็นที่ระบุโดยrootผู้ใช้เป็นไฟล์และไดเรกทอรีแม่เจ้าของและเป็นคนเดียวที่มีสิทธิ์ในการเขียน และไม่ได้/tmp/surprise/tarมีwww-dataหรือapache2เป็นเจ้าของ

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

ตัวอย่าง: (หลอกรหัส)

tarfile=$(which tar)
isroot=$(ls -l "$tarfile") | grep "root root"
#and so on...

2
หากคุณหวาดระแวงแล้วให้ใช้ไบนารีของคุณเอง!
Ipor Sircer

8
นอกเหนือจากการwhichบอกว่าสิ่งที่tarจะทำไม่ถูกต้องตามที่ xhienne ตอบlsอาจถูกแฮ็กเพื่อส่งคืนข้อมูลเท็จเกี่ยวกับไฟล์ถ้ามี นอกจากนี้ยังgrepอาจถูกแฮ็กเพื่อกลับข้อมูลเท็จ ที่สามารถหลีกเลี่ยงได้โดยใช้การจับคู่เชลล์แทน แต่เชลล์สามารถแฮ็กได้ และเชลล์อาจถูกแฮ็กเพื่อให้ได้ผลลัพธ์ที่ผิดตั้งแต่typeแรก - หรือถูกแทนที่ทั้งหมดเนื่องจากความสามารถในการเชลล์ของเชลล์เป็นนวัตกรรมที่สำคัญของ Unix เมื่อเทียบกับระบบปฏิบัติการอายุ 50 ปี ดูที่อยู่ของทัวริงในปี 1984 ของ Ken Thompson มันเต่าตลอดทางลง
dave_thompson_085

2
ฉันไม่สามารถตอบคำถามนี้สำหรับ Linux - เฉพาะ AIX - ซึ่งมีส่วนประกอบที่เรียกว่า Trusted Execution ( TE) - ซึ่งมีฐานข้อมูลที่มีลายเซ็น (เช่นมีความครอบคลุมมากกว่า MD5 checksum เมื่อ TE แอ็คทีฟและไฟล์อยู่ในฐานข้อมูลคุณสามารถเลือกได้ ไม่ว่าจะเป็นโปรแกรมที่ทำงาน - หรือเพียงเตือนว่ามันไม่ตรงกับฐานข้อมูลนอกจากนี้ยังมีการตั้งค่าอื่น ๆ ที่สอง: TEP(เส้นทางการดำเนินการที่เชื่อถือได้) และTLP(เส้นทาง LIBrary ที่เชื่อถือได้) เฉพาะโปรแกรมใน TEP เท่านั้นที่สามารถทำงานได้ ไดเรกทอรีรวมอยู่ใน TLP ใน Linux ฉันมีบางสิ่งที่เรียกว่า 'AppArmor' ที่อาจช่วยคุณได้
Michael Felt

1
คุณสามารถมีความปลอดภัยเช่นนี้ แต่ไม่ใช่จากสคริปต์ - เมื่อสคริปต์ของคุณทำงานในสภาพแวดล้อมที่ไม่สามารถควบคุมได้มันก็สายเกินไป สำหรับทุกสิ่งที่คุณรู้ทุกสิ่งที่คุณสามารถเห็นได้คือชุดโจมตีโดยผู้โจมตี
Charles Duffy

2
... หากคุณต้องการมีระบบที่ไว้วางใจได้ตลอดคุณจะต้องเข้าสู่ระบบ ChromeOS: ลงชื่อเฟิร์มแวร์ของคุณด้วยรหัสที่ฝังอยู่ในฮาร์ดแวร์ของคุณ bootloader / kernel ตรวจสอบโดยเฟิร์มแวร์ของคุณ; พาร์ติชันระบบปฏิบัติการรูทของคุณอ่านอย่างเดียวโดยใช้ลายเซ็นระดับบล็อกสำหรับการตรวจสอบ; เป็นต้นนอกจากนี้ยังมีวิธีการคล้ายกับสิ่งที่ @MichaelFelt พูดถึง - ดูสถาปัตยกรรมการวัดความสมบูรณ์ - แต่ผลกระทบด้านประสิทธิภาพนั้นสูงกว่าและระดับความสมบูรณ์ลดลง (เนื่องจากการตรวจสอบลายเซ็นไบนารีไม่ช่วยให้คุณโจมตีผ่านทางปฏิบัติการไม่ได้ เนื้อหา).
Charles Duffy

คำตอบ:


24

แทนการตรวจสอบความถูกต้องของไบนารีที่คุณกำลังจะรันคุณสามารถรันไบนารีที่ถูกต้องตั้งแต่เริ่มต้น เช่นถ้าคุณต้องการให้แน่ใจว่าคุณจะไม่ทำงาน/tmp/surprise/tarให้เรียกใช้/usr/bin/tarในสคริปต์ของคุณ หรือตั้งค่าของคุณ$PATHเป็นค่าสติก่อนที่จะเรียกใช้อะไร

หากคุณไม่เชื่อถือไฟล์ใน/usr/bin/และไดเรกทอรีระบบอื่น ๆคุณจะไม่สามารถมั่นใจได้ ในตัวอย่างของคุณกำลังตรวจสอบเจ้าของด้วยlsแต่อย่างไรคุณรู้ว่าคุณสามารถไว้วางใจls? อาร์กิวเมนต์เช่นเดียวกับการแก้ปัญหาอื่น ๆ เช่นและmd5sumstrace

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


ซึ่งแบ่งการแจกแจงที่แตกต่างกันเมื่อเลือกที่จะใส่ในไบนารีแทน/bin /usr/bin
Damian Yerrick

IMA เป็นหนึ่งในสองวิธีที่พร้อมใช้งานสำหรับการผลิตนี้อีกวิธีหนึ่งคือแนวทาง dm-verity ที่ ChromeOS ใช้เพื่อทำการตรวจสอบความถูกต้องระดับบล็อกของรูต
Charles Duffy

@DamianYerrick แฟร์หมายเหตุ ตั้งค่า$PATHเป็นทั้งพา ธ เหล่านั้นหากจำเป็นต้องมีการสนับสนุนการกระจายหลายอย่าง
Dmitry Grigoryev

AIX TE (ที่มีหรือไม่มี RBAC) จะเป็นเคอร์เนล "พร้อมใช้งานจริง" ตัวที่สามที่จะทำสิ่งนี้ - อาจมากกว่า TE เมื่อเปิดใช้งานแล้วจะมากกว่าแฝง - จะป้องกันไฟล์จากการเปิดและ / หรือโปรแกรมจากการถูกดำเนินการ นอกจากนี้แอปพลิเคชันและการใช้งานห้องสมุดสามารถตั้งค่าให้เป็นแบบเอกสิทธิ์เฉพาะบุคคลบน TEP (เส้นทางการดำเนินการที่เชื่อถือได้) หรือ TLP (เส้นทางห้องสมุดที่เชื่อถือได้) ดูibm.com/support/knowledgecenter/en/ssw_aix_61/…สำหรับข้อมูลพื้นฐาน
Michael Felt

6

หากผู้บุกรุกเข้าถึงระบบของคุณและสามารถปรับเปลี่ยนของคุณ$PATH(ซึ่งไม่ควรรวม/tmpอยู่ในสถานการณ์ใด ๆ ) แสดงว่าสายเกินไปที่จะเริ่มกังวลเกี่ยวกับการเป็นเจ้าของไฟล์ปฏิบัติการ

แต่คุณควรอ่านเกี่ยวกับวิธีการจัดการกับการบุกรุก

ดีกว่าที่จะมีสมาธิกับการหลีกเลี่ยงการบุกรุกโดยสิ้นเชิง

หากคุณมีระบบที่สิ่งต่าง ๆ เหล่านี้มีความสำคัญก็อาจเป็นความคิดที่ดีที่จะแยกส่วนต่าง ๆ ของมันที่จะต้องเป็นสาธารณะจากส่วนที่ต้องเป็นส่วนตัวเช่นเดียวกับการตรวจสอบรูปแบบของการสื่อสาร ระหว่างสิ่งเหล่านี้


4

มีความเป็นไปได้ที่จะตรวจสอบmd5sumไฟล์ ดังนั้นในระบบที่ใช้aptการจัดการแพ็คเกจ - ในกรณีของฉัน Ubuntu 16.04 - มีไฟล์/var/lib/dpkg/info/tar.md5sumsที่เก็บ md5 จำนวนรวมของไฟล์ทั้งหมดที่มาจากtarการติดตั้ง ดังนั้นคุณสามารถเขียนคำสั่ง if ง่าย ๆ ที่ตรวจสอบว่าผลลัพธ์ของการmd5sum /bin/tarจับคู่ที่อยู่ในไฟล์นั้น

แน่นอนว่าไฟล์เองไม่ได้ถูกดัดแปลง หลักสูตรนี้สามารถเกิดขึ้นได้เมื่อผู้โจมตีมีการเข้าถึงรูท / sudo ซึ่งการเดิมพันทั้งหมดจะปิด


8
แต่คุณจะตรวจสอบได้/usr/bin/md5sumอย่างไร
Dmitry Grigoryev

หากผู้โจมตีสามารถที่จะเปลี่ยน/bin/tarหรือ/usr/bin/tarมันเป็นมากมีแนวโน้มที่พวกเขายังสามารถเพียงแทนที่หรือmd5sum หรือ/var/lib/dpkg/info/tar.md5sums $SHELL
Jonas Schäfer

1
ฉันคิดว่าฉันได้พูดไปแล้วในย่อหน้าสุดท้ายว่าสิ่งที่จะเกิดขึ้นผู้โจมตีจะต้องได้รับสิทธิ์ในการเข้าถึงระบบและในจุดนั้นก็เป็นไปได้ ในกรณีที่ผู้โจมตีไม่มีการเข้าถึงรูท แต่สามารถเปลี่ยนตัวแปร PATH สำหรับผู้ใช้หรือสร้างนามแฝงที่tarชี้ไปยังไบนารีที่แตกต่างกันซึ่งจะทำงาน เมื่อระบบถูกบุกรุกในระดับรากคุณมีทางเลือกหนึ่งแล้ว - ทำมันจากวงโคจร
Sergiy Kolodyazhnyy

3

ใช่มีวิธีการ: typebuiltin ตรงกันข้ามกับwhichคำสั่งที่ค้นหาเฉพาะใน PATH ของคุณtypeจะบอกคุณว่าชื่อคำสั่งนั้นเป็นคำหลักที่สงวนไว้จริง ๆ แล้วคือ builtin, alias, alias, function หรือไฟล์ดิสก์

$ type -t foobar || echo "Not found"
Not found

$ type -t echo
builtin

$ enable -n echo; type -t echo; type -p echo
file
/usr/bin/echo

$ echo() { printf "(echoing) %s\n" "$*"; }; type -t echo
function

$ alias echo="/bin/echo 'I say: ' "; type -t echo
alias

นอกจากนี้type -aจะให้ผู้สมัครทุกคนสำหรับคำสั่งของคุณ (จากตัวเลือกแรกถึงตัวเลือกสุดท้าย):

$ type -a echo
echo is aliased to `/bin/echo 'I say: ' '
echo is a function
echo () 
{ 
    printf "(echoing) %s\n" "$*"
}
echo is a shell builtin
echo is /usr/local/bin/echo
echo is /bin/echo

สุดท้ายหากคุณกังวลเกี่ยวกับไบนารีในดิสก์ของคุณคุณสามารถใช้type -Paเพื่อรับไบนารีทั้งหมดใน PATH ของคุณ (ลำดับเดียวกันตามด้านบน):

$ type -Pa tar
/home/me/bin/tar                <= oh oh, is this normal?
/bin/tar

ที่กล่าวว่าtypeเพียงอย่างเดียวจะไม่บอกคุณว่าคำสั่งจะถูกเรียกในท้ายที่สุด ตัวอย่างเช่นถ้าคุณtarเป็นนามแฝงที่เรียกไบนารี (เช่นalias tar="/tmp/tar") แล้วจะบอกคุณนี้เป็นtypealias


type -aรวมทุกรูปแบบ (เช่นนามแฝงและโปรแกรมภายนอก)
dave_thompson_085

ขอบคุณ @dave มันน่าสนใจจริง ๆ ฉันได้อัปเดตคำตอบของฉันแล้ว
xhienne

1
typeจะแจ้งให้คุณทราบในขณะที่ทุบตีรู้ แต่ถ้าเราอยู่ภายใต้การควบคุมจากผู้โจมตีที่เป็นอันตรายไม่มีเหตุผลที่จะเชื่อว่าสิ่งที่ทุบตีคิดว่ามันรู้สะท้อนความจริงที่แท้จริง สำหรับทุกสิ่งที่คุณรู้ว่ามีLD_PRELOADโมดูลที่ขัดขวางการเรียก C-library ทุกครั้งที่คุณทำ
Charles Duffy

1
@CharlesDuffy คุณถูกต้องแน่นอน ฉันไม่ต้องการที่จะตอบต่อมุมความปลอดภัย "มีวิธีการใด ๆ เพื่อตรวจสอบสิ่งที่คุณเป็นจริงการดำเนินการจากสคริปต์ทุบตี" whichและเสนอทางเลือกให้กับ:
xhienne

ฉันไม่เคยเห็นenableมาก่อน ฉันใช้คำแนะนำจากคำตอบเหล่านี้type enableเพื่อค้นหาว่าเป็นตัวเชลล์ในตัวแล้วhelp enableดูว่ามันทำอะไร
Joe

3

straceคุณสามารถตรวจสอบว่าคำสั่งว่าถูกดำเนินการโดยสคริปต์โดยใช้ ตัวอย่างเช่น:

strace -f -e execve ./script.sh

ด้วยสคริปต์ต่อไปนี้:

#!/bin/bash
touch testfile.txt
echo "Hello" >> testfile.txt
cat testfile.txt
rm testfile.txt

straceจะบอกคุณเส้นทางที่แน่นอนไปยังคำสั่งดำเนินการเมื่อใช้กับ-e execveพารามิเตอร์:

execve("./script.sh", ["./script.sh"], [/* 69 vars */]) = 0 
Process 8524 attached
[pid  8524] execve("/usr/bin/touch", ["touch", "testfile.txt"], [/* 68 vars */]) = 0 
[pid  8524] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8524, si_status=0, si_utime=0, si_stime=0} --- 
Process 8525 attached [pid > 8525] execve("/bin/cat", ["cat", "testfile.txt"], [/* 68 vars */]) = 0
Hello [pid  8525] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8525, si_status=0, si_utime=0, si_stime=0} --- 
Process 8526 attached [pid > 8526] execve("/bin/rm", ["rm", "testfile.txt"], [/* 68 vars */]) = 0
[pid  8526] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8526, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

พารามิเตอร์ (จาก strace man):

-f: ติดตามกระบวนการ child ตามที่สร้างขึ้นโดยกระบวนการที่ติดตามอยู่ในปัจจุบันอันเป็นผลมาจากการเรียกระบบ fork (2), vfork (2) และ clone (2) โปรดทราบว่า-p PID -fจะแนบเธรดกระบวนการ PID ทั้งหมดหากเป็นแบบมัลติเธรดไม่ใช่เฉพาะเธรดที่มี thread_id = PID

-e trace=file: ติดตามการเรียกระบบทั้งหมดที่ใช้ชื่อไฟล์เป็นอาร์กิวเมนต์ คุณสามารถคิดได้ว่านี่เป็นตัวย่อ-e trace=open,stat,chmod,unlink,...ที่มีประโยชน์ในการดูว่าไฟล์ที่กระบวนการกำลังอ้างถึงคืออะไร นอกจากนี้การใช้ตัวย่อจะช่วยให้มั่นใจได้ว่าคุณจะไม่ลืมที่จะรวมการโทรเช่น lstat ไว้ในรายการ


3
นี่ไม่ใช่วิธีการที่สคริปต์ใช้งานได้เพื่อทำการทดสอบอัตโนมัติและไม่มีเหตุผลใดที่จะเชื่อstraceได้ว่าตัวเองไม่ได้ถูกโค่นล้ม
Charles Duffy

0

Linux os ขึ้นอยู่กับไฟล์และคำสั่งมากมายที่ดำเนินการบน linux อาจแก้ไขการเปลี่ยนแปลงบางอย่างของไฟล์ที่อยู่ในเครื่องของคุณ เพราะนั่นอาจเป็นทางออกที่ดีที่สุดสำหรับปัญหาของคุณ คุณสามารถทดสอบคำสั่งของคุณสำหรับการเปลี่ยนแปลงใด ๆ ในระบบไฟล์ก่อนที่จะดำเนินการ

ป้อนคำอธิบายรูปภาพที่นี่

มีคำสั่ง 'strace' ซึ่งจะถอดรหัสคำสั่งของคุณเป็นส่วน ๆ ...

ป้อนคำอธิบายรูปภาพที่นี่

หากคุณต้องการเจาะลึกคุณต้องการเช็คเอาต์ decompilers สำหรับสคริปต์ที่จะดำเนินการ คุณต้องตรวจสอบการตีความแอสเซมเบลอร์ของคำสั่งนั้น objdump -dสำหรับทุบตีมี สคริปต์ช่องเก็บของ Linux ส่วนใหญ่สร้างด้วยCภาษาการเขียนโปรแกรมดังนั้นให้ใช้ตัวCถอดรหัสที่ดี

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