อ่าน 8 นาที
การเขียนโปรแกรมที่มุ่งเน้นผลตอบแทน
การเขียน โปรแกรมแบบ Return-oriented programming ( ROP ) เป็น เทคนิค การโจมตีความปลอดภัยของคอมพิวเตอร์ที่อนุญาตให้ผู้โจมตีสามารถเรียกใช้โค้ดได้แม้จะมีระบบป้องกันความปลอดภัย...
การเขียนโปรแกรมที่มุ่งเน้นผลตอบแทน
การเขียน โปรแกรมแบบ Return-oriented programming ( ROP ) เป็น เทคนิค การโจมตีความปลอดภัยของคอมพิวเตอร์ที่อนุญาตให้ผู้โจมตีสามารถเรียกใช้โค้ดได้แม้จะมีระบบป้องกันความปลอดภัย[ 1 ] [ 2 ]ที่จะป้องกันได้ เช่นการป้องกันพื้นที่ปฏิบัติการและ การลง นามโค้ด[ 3 ]
ในเทคนิคนี้ ผู้โจมตีจะควบคุมสแต็กการเรียกเพื่อยึดการควบคุมการไหล ของโปรแกรม จากนั้นจึงดำเนินการ ลำดับ คำสั่งเครื่อง ที่เลือกอย่างระมัดระวัง ซึ่งมีอยู่แล้วในหน่วยความจำของเครื่อง เรียกว่า "แกดเจ็ต" [ 4 ] [ nb 1 ]โดยทั่วไปแล้ว แกดเจ็ตแต่ละตัวจะลงท้ายด้วยคำสั่ง returnและอยู่ในซับรูทีนภายในโปรแกรมที่มีอยู่และ/หรือโค้ดไลบรารีที่ใช้ร่วมกัน[ nb 1 ]เมื่อนำแกดเจ็ตเหล่านี้มาเชื่อมต่อกัน ผู้โจมตีจะสามารถดำเนินการใดๆ ก็ได้กับเครื่องที่ใช้การป้องกันที่สามารถตรวจจับการโจมตีที่ง่ายกว่าได้
พื้นหลัง

DrawLineถูกเรียกโดยDrawSquare... โปรดสังเกตว่า Stack ในแผนภาพนี้กำลังเติบโตขึ้นไปด้านบนการเขียนโปรแกรมแบบ Return-oriented programming เป็นเวอร์ชันขั้นสูงของการโจมตีแบบStack smashingโดยทั่วไป การโจมตีประเภทนี้เกิดขึ้นเมื่อผู้โจมตีทำการเปลี่ยนแปลงCall Stackโดยใช้ประโยชน์จากข้อบกพร่องในโปรแกรม ซึ่งมักจะเป็น Buffer Overrunในกรณี Buffer Overrun ฟังก์ชันที่ไม่ทำการตรวจสอบขอบเขต อย่างถูกต้อง ก่อนที่จะจัดเก็บข้อมูลที่ผู้ใช้ป้อนลงในหน่วยความจำ จะรับข้อมูลอินพุตมากกว่าที่สามารถจัดเก็บได้อย่างถูกต้อง หากข้อมูลถูกเขียนลงบน Stack ข้อมูลส่วนเกินอาจล้นพื้นที่ที่จัดสรรให้กับตัวแปรของฟังก์ชัน (เช่น "locals" ในแผนภาพ Stack ทางด้านขวา) และเขียนทับที่อยู่ Return ที่อยู่ดังกล่าวจะถูกใช้โดยฟังก์ชันในภายหลังเพื่อเปลี่ยนเส้นทางการควบคุมกลับไปยังผู้เรียกหากถูกเขียนทับ การควบคุมจะถูกเปลี่ยนเส้นทางไปยังตำแหน่งที่ระบุโดยที่อยู่ Return ใหม่
ในการโจมตีแบบ buffer overrun มาตรฐาน ผู้โจมตีจะเขียนโค้ดโจมตี (payload) ลงบน stack แล้วเขียนทับที่อยู่ส่งคืนด้วยตำแหน่งของคำสั่งที่เขียนใหม่เหล่านี้ จนกระทั่งช่วงปลายทศวรรษ 1990 ระบบปฏิบัติการ หลัก ๆ ไม่ได้ให้การป้องกันการโจมตีเหล่านี้ ตัวอย่างเช่นMicrosoft Windowsไม่ได้ให้การป้องกัน buffer overrun จนกระทั่งปี 2004 [ 5 ]ในที่สุด ระบบปฏิบัติการก็เริ่มต่อสู้กับการใช้ประโยชน์จากข้อบกพร่อง buffer overflow โดยการทำเครื่องหมายหน่วยความจำที่เขียนข้อมูลว่าเป็นหน่วยความจำที่ไม่สามารถเรียกใช้งานได้ ซึ่งเป็นเทคนิคที่เรียกว่าการป้องกันพื้นที่ที่สามารถเรียกใช้งานได้ เมื่อ เปิดใช้งานแล้ว เครื่องจะปฏิเสธการเรียกใช้โค้ดใด ๆ ที่อยู่ในพื้นที่หน่วยความจำที่ผู้ใช้สามารถเขียนได้ ซึ่งจะป้องกันไม่ให้ผู้โจมตีวาง payload บน stack และกระโดดไปยัง payload นั้นผ่านการเขียนทับที่อยู่ส่งคืน ต่อมามี การสนับสนุนฮาร์ดแวร์ เพื่อเสริมความแข็งแกร่งของการป้องกันนี้
ด้วยระบบป้องกันการเรียกใช้ข้อมูล (Data Execution Prevention: DPC) ผู้โจมตีไม่สามารถเรียกใช้คำสั่งที่เขียนลงในบัฟเฟอร์ได้โดยตรง เนื่องจากส่วนของหน่วยความจำในบัฟเฟอร์นั้นถูกทำเครื่องหมายว่าไม่สามารถเรียกใช้ได้ เพื่อเอาชนะการป้องกันนี้ การโจมตีแบบ Return-Oriented Programming (ROP) จะไม่แทรกคำสั่งที่เป็นอันตราย แต่จะใช้ลำดับคำสั่งที่มีอยู่แล้วในหน่วยความจำที่สามารถเรียกใช้ได้ ซึ่งเรียกว่า "แกดเจ็ต" (gadgets) โดยการจัดการที่อยู่ส่งคืน (return address) การใช้งาน DPC แบบทั่วไปไม่สามารถป้องกันการโจมตีนี้ได้ เพราะผู้โจมตีไม่ได้เรียกใช้โค้ดที่เป็นอันตรายโดยตรง แต่ได้รวมลำดับของคำสั่ง "ที่ดี" โดยการเปลี่ยนที่อยู่ส่งคืนที่จัดเก็บไว้ ดังนั้นโค้ดที่ใช้จึงถูกทำเครื่องหมายว่าสามารถเรียกใช้ได้
เทคนิคการส่งคืนหนังสือเข้าห้องสมุด
การนำระบบป้องกันการเรียกใช้ข้อมูลมาใช้กันอย่างแพร่หลาย ทำให้การโจมตีช่องโหว่บัฟเฟอร์โอเวอร์โฟลว์แบบดั้งเดิมทำได้ยากหรือเป็นไปไม่ได้เลยในลักษณะที่อธิบายไว้ข้างต้น แทนที่จะเป็นเช่นนั้น ผู้โจมตีจะถูกจำกัดให้เข้าถึงเฉพาะโค้ดที่อยู่ในหน่วยความจำซึ่งถูกกำหนดให้สามารถเรียกใช้งานได้ เช่น โค้ดของโปรแกรมเองและไลบรารีที่ใช้ร่วมกันที่ เชื่อมโยงอยู่ เนื่องจากไลบรารีที่ใช้ร่วมกัน เช่นlibcมักจะมีซับรูทีนสำหรับการเรียกใช้ระบบและฟังก์ชันอื่นๆ ที่อาจเป็นประโยชน์ต่อผู้โจมตี ดังนั้นจึงเป็นไปได้มากที่สุดที่จะพบโค้ดเพื่อประกอบการโจมตี
ในการโจมตีแบบส่งกลับไปยังไลบรารี ผู้โจมตีจะเข้าควบคุมการไหลของโปรแกรมโดยใช้ประโยชน์จากช่องโหว่บัฟเฟอร์โอเวอร์รัน ดังที่กล่าวไว้ข้างต้น แทนที่จะพยายามเขียนเพย์โหลดการโจมตีลงบนสแต็ก ผู้โจมตีจะเลือกฟังก์ชันไลบรารีที่มีอยู่และเขียนทับที่อยู่ส่งคืนด้วยตำแหน่งเริ่มต้น จากนั้นจะเขียนทับตำแหน่งสแต็กเพิ่มเติม โดยปฏิบัติตามข้อกำหนดการเรียกที่เหมาะสม เพื่อส่งพารามิเตอร์ที่ถูกต้องไปยังฟังก์ชันอย่างระมัดระวัง เพื่อให้ฟังก์ชันทำงานที่เป็นประโยชน์ต่อผู้โจมตี เทคนิคนี้ได้รับการนำเสนอครั้งแรกโดยSolar Designerในปี 1997 [ 6 ]และต่อมาได้ขยายไปสู่การเชื่อมโยงการเรียกฟังก์ชันแบบไม่จำกัด[ 7 ]
ส่วนของโค้ดที่ยืมมา
การเกิดขึ้นของ โปรเซสเซอร์ x86 แบบ 64 บิตนำมาซึ่งการเปลี่ยนแปลงในข้อกำหนดการเรียกซับรูทีน ซึ่งกำหนดให้ต้องส่งอาร์กิวเมนต์แรกๆ ของฟังก์ชันผ่านทางรีจิสเตอร์แทนที่จะส่งผ่านทางสแต็ก นั่นหมายความว่าผู้โจมตีไม่สามารถตั้งค่าการเรียกฟังก์ชันไลบรารีด้วยอาร์กิวเมนต์ที่ต้องการได้อีกต่อไป เพียงแค่จัดการสแต็กการเรียกผ่านการโจมตีแบบบัฟเฟอร์โอเวอร์รัน นักพัฒนาไลบรารีแบบแชร์ก็เริ่มลบหรือจำกัดฟังก์ชันไลบรารีที่ทำหน้าที่ซึ่งเป็นประโยชน์ต่อผู้โจมตีเป็นพิเศษ เช่น ตัวห่อ การเรียกระบบส่งผลให้การโจมตีแบบส่งกลับไปยังไลบรารีทำได้ยากขึ้นมาก
วิวัฒนาการถัดไปเกิดขึ้นในรูปแบบของการโจมตีที่ใช้ฟังก์ชันไลบรารีบางส่วน แทนที่จะใช้ฟังก์ชันทั้งหมด เพื่อใช้ประโยชน์จากช่องโหว่บัฟเฟอร์โอเวอร์รันบนเครื่องที่มีการป้องกันการโจมตีที่ง่ายกว่า[ 8 ]เทคนิคนี้จะค้นหาฟังก์ชันที่มีลำดับคำสั่งที่ดึงค่าจากสแต็กไปยังรีจิสเตอร์ การเลือกใช้ลำดับโค้ดเหล่านี้อย่างระมัดระวังจะช่วยให้ผู้โจมตีสามารถใส่ค่าที่เหมาะสมลงในรีจิสเตอร์ที่ถูกต้องเพื่อเรียกใช้ฟังก์ชันภายใต้ข้อกำหนดการเรียกใช้แบบใหม่ ส่วนที่เหลือของการโจมตีจะดำเนินการในรูปแบบการโจมตีแบบส่งกลับไปยังไลบรารี
การโจมตี
การเขียนโปรแกรมแบบ Return-oriented สร้างขึ้นจากแนวทางการใช้โค้ดที่ยืมมาและขยายออกไปเพื่อให้ผู้โจมตีมีฟังก์ชันการทำงานที่สมบูรณ์แบบ Turing รวมถึง ลูปและการแยกเงื่อนไข[ 9 ] [ 10 ]กล่าวอีกนัยหนึ่ง การเขียนโปรแกรมแบบ Return-oriented ให้ "ภาษา" ที่มีฟังก์ชันการทำงานครบถ้วน ซึ่งผู้โจมตีสามารถใช้เพื่อทำให้เครื่องที่ถูกบุกรุกดำเนินการใดๆ ก็ได้ตามที่ต้องการHovav Shachamได้เผยแพร่เทคนิคนี้ในปี 2007 [ 11 ]และแสดงให้เห็นว่าโครงสร้างการเขียนโปรแกรมที่สำคัญทั้งหมดสามารถจำลองได้โดยใช้การเขียนโปรแกรมแบบ Return-oriented กับแอปพลิเคชันเป้าหมายที่เชื่อมโยงกับไลบรารีมาตรฐาน C และมีช่องโหว่ buffer overrun ที่สามารถใช้ประโยชน์ได้
การโจมตีแบบ Return-Oriented Programming นั้นเหนือกว่าการโจมตีประเภทอื่นๆ ที่กล่าวถึง ทั้งในด้านพลังการแสดงออกและความต้านทานต่อมาตรการป้องกัน เทคนิคการต่อต้านการโจมตีที่กล่าวมาข้างต้นทั้งหมด รวมถึงการลบฟังก์ชันที่อาจเป็นอันตรายออกจากไลบรารีที่ใช้ร่วมกันนั้น ไม่มีผลใดๆ ต่อการโจมตีแบบ Return-Oriented Programming เลย
บนสถาปัตยกรรม x86
แม้ว่าการโจมตีแบบ Return-Oriented Programming จะสามารถดำเนินการได้บนสถาปัตยกรรมที่หลากหลาย[ 11 ]แต่บทความของ Shacham และงานติดตามส่วนใหญ่มุ่งเน้นไปที่สถาปัตยกรรม Intel x86สถาปัตยกรรม x86 เป็น ชุดคำสั่ง CISC ที่มีความยาวแปรผันได้ การโจมตีแบบ Return-Oriented Programming บน x86 ใช้ประโยชน์จากข้อเท็จจริงที่ว่าชุดคำสั่งนั้น "หนาแน่น" มาก กล่าวคือ ลำดับไบต์แบบสุ่มใดๆ ก็มีแนวโน้มที่จะตีความได้ว่าเป็นชุดคำสั่ง x86 ที่ถูกต้อง
ดังนั้นจึงเป็นไปได้ที่จะค้นหาโอเปอเรเตอร์โค้ดที่เปลี่ยนแปลงการควบคุมการไหล โดยเฉพาะอย่างยิ่งคำสั่งส่งคืน (0xC3) จากนั้นมองย้อนกลับไปในไบนารีเพื่อหาไบต์ก่อนหน้าที่สร้างคำสั่งที่มีประโยชน์ได้ ชุดคำสั่ง "แกดเจ็ต" เหล่านี้สามารถเชื่อมโยงกันได้โดยการเขียนทับที่อยู่ส่งคืนผ่านการโจมตีบัฟเฟอร์โอเวอร์รันด้วยที่อยู่ของคำสั่งแรกของแกดเจ็ตแรก จากนั้นที่อยู่แรกของแกดเจ็ตถัดไปจะถูกเขียนลงบนสแต็กตามลำดับ เมื่อสิ้นสุดแกดเจ็ตแรก คำสั่งส่งคืนจะถูกดำเนินการ ซึ่งจะดึงที่อยู่ของแกดเจ็ตถัดไปออกจากสแต็กและกระโดดไปยังแกดเจ็ตนั้น เมื่อสิ้นสุดแกดเจ็ตนั้น ห่วงโซ่จะดำเนินต่อไปด้วยแกดเจ็ตที่สาม และต่อไปเรื่อยๆ โดยการเชื่อมโยงลำดับคำสั่งเล็กๆ ผู้โจมตีสามารถสร้างพฤติกรรมโปรแกรมตามอำเภอใจจากโค้ดไลบรารีที่มีอยู่ก่อนแล้ว Shacham ยืนยันว่าหากมีโค้ดจำนวนมากพอ (รวมถึงแต่ไม่จำกัดเฉพาะไลบรารีมาตรฐาน C) จะมีแกดเจ็ตเพียงพอสำหรับฟังก์ชันการทำงานที่สมบูรณ์แบบของ Turing [ 11 ]
มีการพัฒนาเครื่องมืออัตโนมัติเพื่อช่วยทำให้กระบวนการค้นหาแกดเจ็ตและสร้างการโจมตีไบนารีเป็นไปโดยอัตโนมัติ[ 12 ]เครื่องมือนี้เรียกว่า ROPgadget จะค้นหาแกดเจ็ตที่มีประโยชน์ในไบนารี และพยายามประกอบแกดเจ็ตเหล่านั้นเข้ากับเพย์โหลดการโจมตีที่สร้างเชลล์เพื่อรับคำสั่งตามอำเภอใจจากผู้โจมตี
การสุ่มจัดวางพื้นที่แอดเดรส
การสุ่มเค้าโครงพื้นที่แอดเดรสก็มีช่องโหว่เช่นกัน ตามเอกสารของ Shacham et al. [ 13 ] ASLR บนสถาปัตยกรรม 32 บิตนั้นถูกจำกัดด้วยจำนวนบิตที่ใช้ได้สำหรับการสุ่มแอดเดรส มีเพียง 16 บิตจาก 32 บิตแอดเดรสเท่านั้นที่ใช้ได้สำหรับการสุ่ม และการสุ่มแอดเดรส 16 บิตนั้นสามารถถูกทำลายได้ด้วยการโจมตีแบบ Brute Forceภายในไม่กี่นาที สถาปัตยกรรม 64 บิตนั้นมีความแข็งแกร่งกว่า โดยมี 40 บิตจาก 64 บิตที่ใช้ได้สำหรับการสุ่ม การโจมตีแบบ Brute Force กับการสุ่ม 40 บิตนั้นเป็นไปได้ แต่ไม่น่าจะรอดพ้นสายตาไปได้ นอกจากการโจมตีแบบ Brute Force แล้ว ยังมี เทคนิคสำหรับ การลบการสุ่มออกไป อีกด้วย
แม้ว่าจะมีการสุ่มอย่างสมบูรณ์แบบ การรั่วไหลของข้อมูลเนื้อหาหน่วยความจำใดๆ ก็จะช่วยคำนวณที่อยู่ฐานของไลบรารีที่ใช้ร่วมกันได้ในระหว่างการทำงาน[ 14 ]
โดยไม่ต้องใช้คำสั่งส่งคืน
ตามเอกสารของ Checkoway et al. [ 15 ]เป็นไปได้ที่จะทำการเขียนโปรแกรมแบบ return-oriented-programming บนสถาปัตยกรรม x86 และ ARM โดยไม่ต้องใช้คำสั่ง return (0xC3 บน x86) พวกเขาใช้ลำดับคำสั่งที่สร้างขึ้นอย่างระมัดระวังซึ่งมีอยู่แล้วในหน่วยความจำของเครื่องเพื่อทำหน้าที่เหมือนคำสั่ง return คำสั่ง return มีผลสองอย่าง: อย่างแรกคือ อ่านค่าสี่ไบต์ที่ด้านบนสุดของสแต็ก และตั้งค่าตัวชี้คำสั่งเป็นค่านั้น และอย่างที่สองคือ เพิ่มค่าตัวชี้สแต็กขึ้นสี่ (เทียบเท่ากับการดำเนินการ pop) บนสถาปัตยกรรม x86 ลำดับของคำสั่ง jmp และ pop สามารถทำหน้าที่เป็นคำสั่ง return ได้ บน ARM ลำดับของคำสั่ง load และ branch สามารถทำหน้าที่เป็นคำสั่ง return ได้
เนื่องจากวิธีการใหม่นี้ไม่ได้ใช้คำสั่ง return จึงส่งผลเสียต่อระบบป้องกัน เมื่อโปรแกรมป้องกันตรวจสอบไม่เพียงแต่คำสั่ง return หลายคำสั่ง แต่ยังตรวจสอบคำสั่ง jump หลายคำสั่งด้วย การโจมตีนี้อาจถูกตรวจพบได้
การป้องกัน
จี-ฟรี
เทคนิค G-Free ได้รับการพัฒนาโดย Kaan Onarlioglu, Leyla Bilge, Andrea Lanzi, Davide Balzarotti และ Engin Kirda เป็นวิธีแก้ปัญหาที่ใช้ได้จริงเพื่อต่อต้านการเขียนโปรแกรมแบบ return-oriented ในรูปแบบใดๆ ก็ตาม วิธีแก้ปัญหานี้จะกำจัดคำสั่ง free-branch ที่ไม่ตรงแนวทั้งหมด (คำสั่งเช่น RET หรือ CALL ซึ่งผู้โจมตีสามารถใช้เพื่อเปลี่ยนการควบคุมการไหล) ภายในไฟล์ปฏิบัติการไบนารี และป้องกันคำสั่ง free-branch จากการถูกผู้โจมตีนำไปใช้ วิธีที่ G-Free ป้องกันที่อยู่ส่งคืนนั้นคล้ายกับXOR canaryที่ใช้โดย StackGuard นอกจากนี้ยังตรวจสอบความถูกต้องของการเรียกฟังก์ชันโดยการเพิ่มบล็อกการตรวจสอบ หากไม่พบผลลัพธ์ที่คาดหวัง G-Free จะทำให้แอปพลิเคชันล่ม[ 16 ]
การสุ่มจัดวางพื้นที่ที่อยู่
มีการเสนอเทคนิคหลายอย่างเพื่อทำลายการโจมตีที่อิงตามการเขียนโปรแกรมแบบส่งคืน[ 17 ]ส่วนใหญ่อาศัยการสุ่มตำแหน่งของโค้ดโปรแกรมและไลบรารี เพื่อไม่ให้ผู้โจมตีสามารถคาดเดาตำแหน่งของคำสั่งที่อาจมีประโยชน์ในแกดเจ็ตได้อย่างแม่นยำ และด้วยเหตุนี้จึงไม่สามารถสร้างห่วงโซ่การโจมตีการเขียนโปรแกรมแบบส่งคืนที่ประสบความสำเร็จได้ การใช้งานเทคนิคนี้ที่ค่อนข้างแพร่หลายอย่างหนึ่งคือการสุ่มเค้าโครงพื้นที่แอดเดรส (ASLR) ซึ่งโหลดไลบรารีที่ใช้ร่วมกันไปยังตำแหน่งหน่วยความจำที่แตกต่างกันในแต่ละการโหลดโปรแกรม แม้ว่าระบบปฏิบัติการสมัยใหม่จะใช้งานอย่างแพร่หลาย แต่ ASLR ก็มีความเสี่ยงต่อ การโจมตี การรั่วไหลของข้อมูลและวิธีการอื่นๆ ในการกำหนดแอดเดรสของฟังก์ชันไลบรารีที่รู้จักในหน่วยความจำ หากผู้โจมตีสามารถกำหนดตำแหน่งของคำสั่งที่รู้จักได้สำเร็จ ตำแหน่งของคำสั่งอื่นๆ ทั้งหมดก็สามารถอนุมานได้ และสามารถสร้างการโจมตีการเขียนโปรแกรมแบบส่งคืนได้
แนวทางการสุ่มนี้สามารถนำไปใช้ได้ต่อไปโดยการย้ายคำสั่งทั้งหมดและ/หรือสถานะโปรแกรมอื่นๆ (รีจิสเตอร์และออบเจ็กต์สแต็ก) ของโปรแกรมแยกกัน แทนที่จะย้ายเฉพาะตำแหน่งไลบรารี[ 18 ] [ 19 ] [ 20 ]ซึ่งต้องใช้การสนับสนุนรันไทม์อย่างกว้างขวาง เช่น ตัวแปลแบบไดนามิกซอฟต์แวร์ เพื่อประกอบคำสั่งที่สุ่มกลับเข้าด้วยกันในรันไทม์ เทคนิคนี้ประสบความสำเร็จในการทำให้แกดเจ็ตหาและใช้งานได้ยาก แต่มาพร้อมกับค่าใช้จ่ายที่สูง
แนวทางอื่นที่ kBouncer ใช้คือการปรับเปลี่ยนระบบปฏิบัติการเพื่อตรวจสอบว่าคำสั่ง return จริงๆ แล้วเบี่ยงเบนการไหลของควบคุมกลับไปยังตำแหน่งถัดจากคำสั่ง call ทันที ซึ่งจะป้องกันการเชื่อมโยงแกดเจ็ต แต่ไม่มีประสิทธิภาพต่อการโจมตีการเขียนโปรแกรมแบบกระโดดที่เปลี่ยนแปลงคำสั่งกระโดดและคำสั่งแก้ไขการไหลของควบคุมอื่นๆ แทนที่จะเป็นคำสั่ง return [ 21 ]
การสุ่มรหัสไบนารี
ระบบสมัยใหม่บางระบบ เช่น Cloud Lambda (FaaS) และการอัปเดตระยะไกล IoT ใช้โครงสร้างพื้นฐานคลาวด์เพื่อทำการคอมไพล์แบบเรียลไทม์ก่อนการปรับใช้ซอฟต์แวร์เทคนิคที่เพิ่มความหลากหลายให้กับแต่ละอินสแตนซ์ของโปรแกรมซอฟต์แวร์ที่กำลังทำงานอยู่สามารถเพิ่มภูมิคุ้มกันของซอฟต์แวร์ต่อการโจมตี ROP ได้อย่างมาก การโจมตีแบบ Brute force บน Cloud Lambda อาจส่งผลให้โจมตีหลายอินสแตนซ์ของซอฟต์แวร์แบบสุ่ม ซึ่งลดประสิทธิภาพของการโจมตี Asaf Shelly ได้เผยแพร่เทคนิคนี้ในปี 2017 [ 22 ]และสาธิตการใช้ Binary Randomization ในระบบอัปเดตซอฟต์แวร์ สำหรับอุปกรณ์ที่ได้รับการอัปเดตแต่ละเครื่อง บริการบนคลาวด์จะเพิ่มความหลากหลายให้กับโค้ด ทำการคอมไพล์ออนไลน์ และส่งไบนารี เทคนิคนี้มีประสิทธิภาพมากเนื่องจากการโจมตี ROP อาศัยความรู้เกี่ยวกับโครงสร้างภายในของซอฟต์แวร์ ข้อเสียของเทคนิคนี้คือซอฟต์แวร์จะไม่ได้รับการทดสอบอย่างเต็มที่ก่อนที่จะปรับใช้ เนื่องจากไม่สามารถทดสอบความหลากหลายทั้งหมดของซอฟต์แวร์แบบสุ่มได้ ซึ่งหมายความว่าเทคนิค Binary Randomization จำนวนมากนั้นใช้ได้กับอินเทอร์เฟซเครือข่ายและการเขียนโปรแกรมระบบ และไม่แนะนำสำหรับอัลกอริทึมที่ซับซ้อน
เซฮอป
การป้องกันการเขียนทับตัวจัดการข้อ ยกเว้นที่มีโครงสร้าง (Structured Exception Handler Overwrite Protection) เป็นคุณสมบัติของ Windows ที่ป้องกันการโจมตีแบบ Stack Overflow ที่พบบ่อยที่สุด โดยเฉพาะอย่างยิ่งการโจมตีตัวจัดการข้อยกเว้นที่มีโครงสร้าง
ป้องกันการโจมตีแบบควบคุมการไหลของโปรแกรม
เนื่องจากระบบฝังตัวขนาดเล็กกำลังแพร่หลายมากขึ้นอันเนื่องมาจากการขยายตัวของอินเทอร์เน็ตของสิ่งต่างๆความต้องการในการปกป้องระบบฝังตัวดังกล่าวจึงเพิ่มขึ้นเช่นกัน การใช้การควบคุมการเข้าถึงหน่วยความจำตามคำสั่ง (IB-MAC) ที่นำมาใช้ในฮาร์ดแวร์ ทำให้สามารถปกป้องระบบฝังตัวราคาประหยัดจากการโจมตีการไหลของควบคุมที่เป็นอันตรายและการโจมตีการล้นสแต็กได้ การป้องกันสามารถทำได้โดยการแยกสแต็กข้อมูลและสแต็กส่งคืน อย่างไรก็ตาม เนื่องจากระบบฝังตัวบางระบบขาดหน่วยจัดการหน่วยความจำโซลูชันฮาร์ดแวร์จึงไม่สามารถนำไปใช้กับระบบฝังตัวทั้งหมดได้[ 23 ]
ต่อต้านรูทคิตที่มุ่งเน้นผลตอบแทน
ในปี 2010 Jinku Li และคณะได้เสนอ[ 24 ]ว่าคอมไพเลอร์ ที่ได้รับการแก้ไขอย่างเหมาะสม สามารถกำจัด "แกดเจ็ต" ที่มุ่งเน้นการส่งคืนได้โดยการแทนที่แต่ละด้วยลำดับคำสั่งและแต่ละด้วยลำดับคำสั่งโดยที่แทนตารางที่ไม่สามารถเปลี่ยนแปลงได้ของที่อยู่ส่งคืน "ที่ถูกต้อง" ทั้งหมดในโปรแกรม และแทนดัชนีเฉพาะในตารางนั้น[ 24 ] : 5–6 ซึ่งจะป้องกันการสร้างแกดเจ็ตที่มุ่งเน้นการส่งคืนที่ส่งคืนโดยตรงจากจุดสิ้นสุดของฟังก์ชันไปยังที่อยู่ใดๆ ในกลางฟังก์ชันอื่น แทนที่จะเป็นเช่นนั้น แกดเจ็ตสามารถส่งคืนได้เฉพาะที่อยู่ส่งคืน "ที่ถูกต้อง" เท่านั้น ซึ่งจะเพิ่มความยากลำบากในการสร้างแกดเจ็ตที่มีประโยชน์อย่างมาก Li และคณะอ้างว่า "เทคนิคการส่งกลับทางอ้อมของเราโดยพื้นฐานแล้วทำให้การเขียนโปรแกรมที่มุ่งเน้นการส่งคืนกลับไปสู่รูปแบบเก่าของการส่งคืนไปยัง libc" [ 24 ]คอมไพเลอร์ต้นแบบของพวกเขามี ขั้นตอน การเพิ่มประสิทธิภาพแบบ peephole เพื่อจัดการกับ "คำ สั่ง เครื่องบางอย่างที่มีรหัสส่งคืนอยู่ในรหัสคำสั่งหรือตัวถูกดำเนินการทันที" [ 24 ]เช่นcallfpushl$index; jmpfretpopl%reg; jmptable(%reg)tableindexmovl$0xC3,%eax
รหัสยืนยันตัวชี้ (PAC)
สถาปัตยกรรมARMv8.3-Aนำเสนอคุณสมบัติใหม่ในระดับฮาร์ดแวร์ที่ใช้ประโยชน์จากบิตที่ไม่ได้ใช้ในพื้นที่แอดเดรสพอยเตอร์เพื่อลงนามแอดเดรสพอยเตอร์ทางคริปโตกราฟีโดยใช้บล็อกไซเฟอร์ที่ปรับแต่งได้ ซึ่งออกแบบมาเป็นพิเศษ [ 25 ] [ 26 ]ซึ่งลงนามค่าที่ต้องการ (โดยทั่วไปคือแอดเดรสส่งคืน) รวมกับค่า "บริบทท้องถิ่น" (เช่น พอยเตอร์สแต็ก)
ก่อนที่จะดำเนินการใดๆ ที่มีความละเอียดอ่อน (เช่น การกลับไปยังตัวชี้ที่บันทึกไว้) สามารถตรวจสอบลายเซ็นเพื่อตรวจจับการดัดแปลงหรือการใช้งานในบริบทที่ไม่ถูกต้อง (เช่น การใช้ที่อยู่ส่งคืนที่บันทึกไว้จากบริบทการโจมตีแบบ trampoline)
Apple Siliconตั้งแต่รุ่น A12 ได้อัปเกรดเป็น ARMv8.3 และใช้ PAC แล้วLinuxได้รับการสนับสนุนการตรวจสอบความถูกต้องของตัวชี้ภายในเคอร์เนลในเวอร์ชัน 5.7ที่วางจำหน่ายในปี 2020 และมีการเพิ่มการสนับสนุนสำหรับ แอปพลิเคชัน ในพื้นที่ผู้ใช้ในปี 2018 [ 27 ]
ในปี 2022 นักวิจัยที่MITได้เผยแพร่การโจมตีช่องทางด้านข้างต่อ PAC ที่เรียกว่าPACMAN [ 28 ]
การระบุเป้าหมายสาขา (BTI)
ARMv8.5-Aได้นำคุณสมบัติระดับฮาร์ดแวร์มาใช้เพื่อระบุเป้าหมายที่ถูกต้องของคำสั่งกระโดดอย่างชัดเจน คอมไพเลอร์จะแทรกคำสั่งพิเศษที่มีรหัสปฏิบัติการว่า "BTI" ในแต่ละจุดที่คาดว่าจะลงจอดของ คำสั่ง กระโดดทางอ้อม ปลายทาง ของ การกระโดดที่ระบุเหล่านี้โดยทั่วไปจะรวมถึงจุดเริ่มต้นของฟังก์ชันและบล็อกโค้ด switch/case
คำสั่ง BTI ถูกใช้ในหน้าหน่วยความจำโค้ดซึ่งถูกทำเครื่องหมายว่าเป็น "หน้าที่มีการป้องกัน" โดยคอมไพเลอร์และลิงเกอร์ คำสั่งกระโดดทางอ้อมใดๆ ที่เข้าไปในหน้าที่มีการป้องกัน ไม่ว่าจะเป็นคำสั่งใดก็ตามที่ไม่ใช่ BTI จะทำให้เกิดข้อผิดพลาด
ปลายทางที่ระบุซึ่งมีการแทรกคำสั่ง BTI คิดเป็นประมาณ 1% ของคำสั่งทั้งหมดในโค้ดแอปพลิเคชันโดยเฉลี่ย ดังนั้น การใช้ BTI จะเพิ่มขนาดโค้ดในปริมาณเท่ากัน[ 29 ]
อุปกรณ์ที่ใช้ในการโจมตีแบบ ROP นั้นอยู่ได้ทุกที่ในโค้ดของแอปพลิเคชัน ดังนั้นโดยเฉลี่ยแล้ว 99% ของอุปกรณ์เหล่านี้จะเริ่มต้นด้วยคำสั่งที่ไม่ใช่ BTI การกระโดดไปยังอุปกรณ์เหล่านี้จึงส่งผลให้เกิดข้อผิดพลาด เมื่อพิจารณาว่าการโจมตีแบบ ROP ประกอบด้วยอุปกรณ์หลายตัวเรียงต่อกัน ความน่าจะเป็นที่อุปกรณ์ทั้งหมดในห่วงโซ่จะเป็นส่วนหนึ่งของ 1% ที่เริ่มต้นด้วย BTI นั้นต่ำมาก
PAC และ BTI เป็นกลไกเสริมเพื่อป้องกันการแทรกโค้ดที่ไม่พึงประสงค์โดยใช้การโจมตีการเขียนโปรแกรมแบบ return-oriented และ jump-oriented ในขณะที่ PAC มุ่งเน้นไปที่แหล่งที่มาของการดำเนินการสาขา (ตัวชี้ที่มีเครื่องหมาย) BTI จะมุ่งเน้นไปที่ปลายทางของสาขา[ 30 ]
ดูเพิ่มเติม
- การเขียนโปรแกรมแบบมุ่งเน้นผลตอบแทนโดยไม่เปิดเผยตัวตน
- จำนวนเต็มเกินขีดจำกัด
- การพ่นแบบ JIT
- การเขียนโปรแกรมเชิงผลลัพธ์แบบ Sigreturn (SROP)
- โค้ดแบบมัลติเธรด – การเขียนโปรแกรมแบบเน้นการส่งคืนค่า คือการค้นพบใหม่ของโค้ดแบบมัลติเธรด
หมายเหตุ
ลิงก์ภายนอก
- "นักวิทยาศาสตร์คอมพิวเตอร์เข้าควบคุมเครื่องลงคะแนนอิเล็กทรอนิกส์ด้วยเทคนิคการเขียนโปรแกรมใหม่" Science Daily. 11 สิงหาคม 2552.
- "วิดีโอสาธิตการ โจมตี ด้วยการ เขียนโปรแกรมแบบ Return-oriented Programming" YouTube
- AntiJOP: โปรแกรมที่กำจัดช่องโหว่ JOP/ROP จากโค้ดภาษาแอสเซมบลี
สรุปเนื้อหา
ข้อมูลสำคัญจากบทความ
ข้อมูลสำคัญเกี่ยวกับ การเขียนโปรแกรมที่มุ่งเน้นผลตอบแทน
การเขียน โปรแกรมแบบ Return-oriented programming ( ROP ) เป็น เทคนิค การโจมตีความปลอดภัยของคอมพิวเตอร์ที่อนุญาตให้ผู้โจมตีสามารถเรียกใช้โค้ดได้แม้จะมีระบบป้องกันความปลอดภัย...
พื้นหลัง
การเขียนโปรแกรมแบบ Return-oriented programming เป็นเวอร์ชันขั้นสูงของการโจมตีแบบ Stack smashing โดยทั่วไป การโจมตีประเภทนี้เกิดขึ้นเมื่อผู้โจมตีทำการเปลี่ยนแปลง Call Stack โดยใช้ประโยชน์จาก ข้อบกพร่อง ในโปรแกรม ซึ่งมักจะ เป็น Buffer Overrun ในกรณี Buffer...
เทคนิคการส่งคืนหนังสือเข้าห้องสมุด
การนำระบบป้องกันการเรียกใช้ข้อมูลมาใช้กันอย่างแพร่หลาย ทำให้การโจมตีช่องโหว่บัฟเฟอร์โอเวอร์โฟลว์แบบดั้งเดิมทำได้ยากหรือเป็นไปไม่ได้เลยในลักษณะที่อธิบายไว้ข้างต้น แทนที่จะเป็นเช่นนั้น...
ส่วนของโค้ดที่ยืมมา
การเกิดขึ้นของ โปรเซสเซอร์ x86 แบบ 64 บิต นำมาซึ่งการเปลี่ยนแปลงในข้อกำหนดการเรียกซับรูทีน ซึ่งกำหนดให้ต้องส่งอาร์กิวเมนต์แรกๆ ของฟังก์ชันผ่านทาง รีจิสเตอร์ แทนที่จะส่งผ่านทางสแต็ก...