พัฒนาโดย Michal Zalewski [email protected]
ดู QuickStartGuide.txt หากคุณไม่มีเวลาอ่านไฟล์นี้
Fuzzing เป็นหนึ่งในกลยุทธ์ที่ทรงพลังและได้รับการพิสูจน์แล้วที่สุดในการระบุปัญหาด้านความปลอดภัยในซอฟต์แวร์ในโลกแห่งความเป็นจริง โดยมีหน้าที่รับผิดชอบต่อการเรียกใช้โค้ดจากระยะไกลและข้อบกพร่องในการยกระดับสิทธิ์ส่วนใหญ่ที่พบในซอฟต์แวร์ที่มีความสำคัญต่อความปลอดภัยในปัจจุบัน
น่าเสียดายที่การคลุมเครือก็ค่อนข้างตื้นเช่นกัน การกลายพันธุ์แบบสุ่มทำให้ไม่น่าจะเข้าถึงเส้นทางโค้ดบางเส้นทางในโค้ดที่ทดสอบได้ ทิ้งช่องโหว่บางอย่างไว้อย่างมั่นคงนอกเหนือเทคนิคนี้
มีความพยายามหลายครั้งในการแก้ไขปัญหานี้ หนึ่งในแนวทางแรกๆ ที่บุกเบิกโดย Tavis Ormandy คือการกลั่นจากคลังข้อมูล วิธีการนี้อาศัยสัญญาณที่ครอบคลุมเพื่อเลือกชุดย่อยของเมล็ดที่น่าสนใจจากคลังข้อมูลขนาดใหญ่และมีคุณภาพสูงของไฟล์ที่ต้องการ จากนั้นจึงแยกพวกมันด้วยวิธีดั้งเดิม วิธีการนี้ใช้งานได้ดีเป็นพิเศษ แต่จำเป็นต้องมีคลังข้อมูลดังกล่าวให้พร้อมใช้งาน นอกจากนี้ การวัดความครอบคลุมของบล็อกยังให้ความเข้าใจที่เรียบง่ายมากเกี่ยวกับสถานะของโปรแกรม และมีประโยชน์น้อยกว่าในการชี้แนะความพยายามที่คลุมเครือในระยะยาว
การวิจัยที่ซับซ้อนอื่นๆ มุ่งเน้นไปที่เทคนิคต่างๆ เช่น การวิเคราะห์การไหลของโปรแกรม ("การดำเนินการแบบ Concolic") การดำเนินการเชิงสัญลักษณ์ หรือการวิเคราะห์แบบคงที่ วิธีการทั้งหมดเหล่านี้มีแนวโน้มที่ดีอย่างมากในการตั้งค่าการทดลอง แต่มีแนวโน้มที่จะประสบปัญหาด้านความน่าเชื่อถือและประสิทธิภาพในการใช้งานจริง และในปัจจุบันยังไม่มีทางเลือกอื่นที่ใช้ได้แทนเทคนิคการคลุมเครือแบบ "โง่"
American Fuzzy Lop เป็นเครื่องฟอกเสียงแบบเดรัจฉานควบคู่กับอัลกอริธึมทางพันธุกรรมที่มีการนำทางด้วยเครื่องมือที่เรียบง่ายแต่แข็งแกร่ง ใช้รูปแบบที่ปรับเปลี่ยนของ Edge Coverage เพื่อรับการเปลี่ยนแปลงเล็กๆ น้อยๆ ในระดับท้องถิ่นกับโฟลว์การควบคุมโปรแกรมได้อย่างง่ายดาย
ลดความซับซ้อนลงเล็กน้อย อัลกอริธึมโดยรวมสามารถสรุปได้ดังนี้:
โหลดกรณีทดสอบเริ่มต้นที่ผู้ใช้ระบุลงในคิว
นำไฟล์อินพุตถัดไปจากคิว
พยายามตัดแต่งกรณีทดสอบให้มีขนาดเล็กที่สุดที่ไม่เปลี่ยนพฤติกรรมที่วัดได้ของโปรแกรม
กลายพันธุ์ไฟล์ซ้ำๆ โดยใช้กลยุทธ์ฟัซซิ่งแบบดั้งเดิมที่หลากหลายและได้รับการวิจัยอย่างดี
หากการกลายพันธุ์ที่สร้างขึ้นใดๆ ส่งผลให้เกิดการเปลี่ยนแปลงสถานะใหม่ที่บันทึกโดยเครื่องมือวัด ให้เพิ่มเอาต์พุตที่กลายพันธุ์เป็นรายการใหม่ในคิว
ไปที่ 2.
กรณีทดสอบที่ค้นพบจะถูกคัดออกเป็นระยะๆ เพื่อกำจัดกรณีทดสอบที่ล้าสมัยจากการค้นพบใหม่ที่มีความครอบคลุมสูงกว่า และผ่านขั้นตอนการลดความพยายามที่ขับเคลื่อนด้วยเครื่องมือวัดอื่นๆ อีกหลายขั้นตอน
จากผลข้างเคียงของกระบวนการคลุมเครือ เครื่องมือนี้จะสร้างคลังข้อมูลกรณีทดสอบที่น่าสนใจขนาดเล็กในตัวเอง สิ่งเหล่านี้มีประโยชน์อย่างยิ่งในการเริ่มระบบการทดสอบอื่นๆ ที่ต้องใช้แรงงานหรือทรัพยากรมาก ตัวอย่างเช่น สำหรับเบราว์เซอร์ทดสอบความเครียด แอปพลิเคชันในสำนักงาน ชุดกราฟิก หรือเครื่องมือแบบปิด
Fuzzer ได้รับการทดสอบอย่างละเอียดเพื่อให้ประสิทธิภาพที่แกะกล่องได้เหนือกว่า Blind Fuzzing หรือเครื่องมือที่ครอบคลุมเท่านั้น
เมื่อซอร์สโค้ดพร้อมใช้งาน เครื่องมือเสริมสามารถแทรกเข้ามาได้โดยเครื่องมือคู่หูที่ทำงานแทนแบบดรอปอินสำหรับ gcc หรือ clang ในกระบวนการสร้างมาตรฐานสำหรับโค้ดของบุคคลที่สาม
เครื่องมือวัดมีผลกระทบด้านประสิทธิภาพค่อนข้างปานกลาง เมื่อใช้ร่วมกับการปรับให้เหมาะสมอื่น ๆ ที่ดำเนินการโดย afl-fuzz โปรแกรมส่วนใหญ่สามารถคลุมเครือได้เร็วหรือเร็วกว่าที่เป็นไปได้ด้วยเครื่องมือแบบเดิม
วิธีที่ถูกต้องในการคอมไพล์โปรแกรมเป้าหมายใหม่อาจแตกต่างกันไปขึ้นอยู่กับลักษณะเฉพาะของกระบวนการสร้าง แต่แนวทางที่เกือบจะเป็นสากลคือ:
$ CC=/path/to/afl/afl-gcc ./configure
$ make clean all
สำหรับโปรแกรม C++ คุณต้องการตั้งค่า CXX=/path/to/afl/afl-g++
ด้วย
แผ่นปิดเสียงดังกราว (afl-clang และ afl-clang++) สามารถใช้ในลักษณะเดียวกันได้ ผู้ใช้เสียงดังกราวอาจเลือกที่จะใช้ประโยชน์จากโหมดเครื่องมือวัดที่มีประสิทธิภาพสูงกว่า ตามที่อธิบายไว้ใน llvm_mode/README.llvm
เมื่อทดสอบไลบรารี่ คุณต้องค้นหาหรือเขียนโปรแกรมง่ายๆ ที่อ่านข้อมูลจาก stdin หรือจากไฟล์แล้วส่งต่อไปยังไลบรารีที่ทดสอบ ในกรณีเช่นนี้ จำเป็นต้องเชื่อมโยงไฟล์ปฏิบัติการนี้กับเวอร์ชันคงที่ของไลบรารี่ที่ควบคุมด้วยเครื่องมือ หรือเพื่อให้แน่ใจว่าไฟล์ .so ที่ถูกต้องได้รับการโหลดขณะรันไทม์ (โดยปกติจะโดยการตั้งค่า LD_LIBRARY_PATH
) ตัวเลือกที่ง่ายที่สุดคือบิลด์แบบคงที่ ซึ่งโดยปกติจะทำได้ผ่าน:
$ CC=/path/to/afl/afl-gcc ./configure --disable-shared
การตั้งค่า AFL_HARDEN=1
เมื่อเรียก 'make' จะทำให้ CC wrapper เปิดใช้งานตัวเลือกการทำให้โค้ดแข็งตัวโดยอัตโนมัติ ซึ่งทำให้ง่ายต่อการตรวจจับจุดบกพร่องของหน่วยความจำธรรมดา Libdislocator ซึ่งเป็นไลบรารีตัวช่วยที่มาพร้อมกับ AFL (ดู libdislocator/README.dislocator) สามารถช่วยเปิดเผยปัญหาความเสียหายของฮีปได้เช่นกัน
ป.ล. ผู้ใช้ ASAN ควรตรวจสอบไฟล์ note_for_asan.txt เพื่อดูคำเตือนที่สำคัญ
เมื่อซอร์สโค้ด ไม่ พร้อมใช้งาน fuzzer จะให้การสนับสนุนการทดลองสำหรับเครื่องมือไบนารีกล่องดำที่รวดเร็วและทันที ซึ่งสามารถทำได้ด้วยเวอร์ชันของ QEMU ที่ทำงานในโหมด "การจำลองพื้นที่ผู้ใช้" ที่ไม่ค่อยมีใครรู้จัก
QEMU เป็นโปรเจ็กต์ที่แยกจาก AFL แต่คุณสามารถสร้างฟีเจอร์นี้ได้อย่างสะดวกโดยทำดังนี้
$ cd qemu_mode
$ ./build_qemu_support.sh
สำหรับคำแนะนำและคำเตือนเพิ่มเติม โปรดดูที่ qemu_mode/README.qemu
โหมดนี้จะช้ากว่าเครื่องมือวัดเวลาคอมไพล์ประมาณ 2-5 เท่า ซึ่งเอื้อต่อการขนานน้อยกว่า และอาจมีลักษณะพิเศษอื่นๆ อยู่บ้าง
เพื่อให้ทำงานได้อย่างถูกต้อง fuzzer จำเป็นต้องมีไฟล์เริ่มต้นอย่างน้อยหนึ่งไฟล์ที่มีตัวอย่างที่ดีของข้อมูลอินพุตที่โดยปกติแล้วแอปพลิเคชันเป้าหมายคาดหวัง มีกฎพื้นฐานสองข้อ:
เก็บไฟล์ให้มีขนาดเล็ก ขนาดต่ำกว่า 1 kB ถือว่าเหมาะสม แม้ว่าจะไม่จำเป็นก็ตาม หากต้องการทราบว่าเหตุใดขนาดจึงมีความสำคัญ โปรดดูที่ perf_tips.txt
ใช้กรณีทดสอบหลายกรณีก็ต่อเมื่อมีฟังก์ชันการทำงานที่แตกต่างกันเท่านั้น ไม่มีประโยชน์ที่จะใช้ภาพถ่ายวันหยุดที่แตกต่างกันห้าสิบภาพเพื่อคลุมเครือคลังภาพ
คุณจะพบตัวอย่างดีๆ มากมายของไฟล์เริ่มต้นได้ใน testcases/ subdirectory ที่มาพร้อมกับเครื่องมือนี้
ป.ล. หากมีคลังข้อมูลขนาดใหญ่สำหรับการคัดกรอง คุณอาจต้องการใช้ยูทิลิตี afl-cmin เพื่อระบุชุดย่อยของไฟล์ที่แตกต่างกันตามฟังก์ชันซึ่งใช้พาธโค้ดที่แตกต่างกันในไบนารี่เป้าหมาย
กระบวนการฟัซซิ่งนั้นดำเนินการโดยยูทิลิตี้ afl-fuzz โปรแกรมนี้ต้องการไดเร็กทอรีแบบอ่านอย่างเดียวพร้อมกรณีการทดสอบเริ่มต้น สถานที่แยกต่างหากสำหรับจัดเก็บผลการวิจัย รวมถึงเส้นทางไปยังไบนารี่ที่จะทดสอบ
สำหรับไบนารีเป้าหมายที่รับอินพุตโดยตรงจาก stdin ไวยากรณ์ปกติคือ:
$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program [...params...]
สำหรับโปรแกรมที่รับอินพุตจากไฟล์ ให้ใช้ '@@' เพื่อทำเครื่องหมายตำแหน่งในบรรทัดคำสั่งของเป้าหมายที่ควรวางชื่อไฟล์อินพุต fuzzer จะทดแทนสิ่งนี้ให้กับคุณ:
$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@
คุณยังสามารถใช้ตัวเลือก -f เพื่อเขียนข้อมูลที่กลายพันธุ์ไปยังไฟล์ที่ต้องการได้ สิ่งนี้มีประโยชน์หากโปรแกรมคาดว่าจะมีนามสกุลไฟล์ประมาณนั้น
ไบนารีที่ไม่มีเครื่องมือสามารถถูกคลุมเครือได้ในโหมด QEMU (เพิ่ม -Q ในบรรทัดคำสั่ง) หรือในโหมด blind-fuzzer แบบดั้งเดิม (ระบุ -n)
คุณสามารถใช้ -t และ -m เพื่อแทนที่การหมดเวลาเริ่มต้นและขีดจำกัดหน่วยความจำสำหรับกระบวนการที่ดำเนินการ ตัวอย่างที่หายากของเป้าหมายที่อาจต้องสัมผัสการตั้งค่าเหล่านี้ ได้แก่ คอมไพเลอร์และตัวถอดรหัสวิดีโอ
เคล็ดลับในการเพิ่มประสิทธิภาพการทำงานแบบคลุมเครือมีการพูดคุยกันใน perf_tips.txt
โปรดทราบว่า afl-fuzz เริ่มต้นด้วยการดำเนินการอาร์เรย์ของขั้นตอนการ fuzzing ที่กำหนดขึ้น ซึ่งอาจใช้เวลาหลายวัน แต่มีแนวโน้มที่จะสร้างกรณีทดสอบที่เรียบร้อย หากคุณต้องการผลลัพธ์ที่รวดเร็วและสกปรกทันที - เช่นเดียวกับ zzuf และ fuzzers แบบดั้งเดิมอื่น ๆ - ให้เพิ่มตัวเลือก -d ลงในบรรทัดคำสั่ง
ดูไฟล์ status_screen.txt สำหรับข้อมูลเกี่ยวกับวิธีการตีความสถิติที่แสดงและตรวจสอบความสมบูรณ์ของกระบวนการ อย่าลืมอ่านไฟล์นี้ โดยเฉพาะหากองค์ประกอบ UI ใดถูกไฮไลต์ด้วยสีแดง
กระบวนการคลุมเครือจะดำเนินต่อไปจนกว่าคุณจะกด Ctrl-C อย่างน้อยที่สุด คุณต้องการให้ fuzzer ดำเนินการหนึ่งรอบคิว ซึ่งอาจใช้เวลาประมาณสองสามชั่วโมงถึงหนึ่งสัปดาห์หรือประมาณนั้น
มีไดเร็กทอรีย่อยสามไดเร็กทอรีที่สร้างขึ้นภายในไดเร็กทอรีเอาต์พุตและอัปเดตแบบเรียลไทม์:
Queue/ - กรณีทดสอบสำหรับพาธการดำเนินการเฉพาะทุกรายการ รวมถึงไฟล์เริ่มต้นทั้งหมดที่ผู้ใช้กำหนด นี่คือคลังข้อมูลสังเคราะห์ที่กล่าวถึงในส่วนที่ 2 ก่อนที่จะใช้คลังข้อมูลนี้เพื่อวัตถุประสงค์อื่น คุณสามารถย่อขนาดให้เล็กลงได้โดยใช้เครื่องมือ afl-cmin เครื่องมือจะค้นหาชุดย่อยของไฟล์ที่มีขนาดเล็กกว่าซึ่งครอบคลุมขอบเท่ากัน
ล่ม/ - กรณีทดสอบเฉพาะที่ทำให้โปรแกรมที่ทดสอบได้รับสัญญาณร้ายแรง (เช่น SIGSEGV, SIGILL, SIGABRT) รายการจะถูกจัดกลุ่มตามสัญญาณที่ได้รับ
hangs/ - กรณีทดสอบเฉพาะที่ทำให้โปรแกรมที่ทดสอบหมดเวลา การจำกัดเวลาดีฟอลต์ก่อนที่บางสิ่งจะถูกจัดประเภทเป็นการแฮงค์นั้นมีค่ามากกว่า 1 วินาทีและค่าของพารามิเตอร์ -t สามารถปรับค่าอย่างละเอียดได้โดยการตั้งค่า AFL_HANG_TMOUT แต่ไม่ค่อยจำเป็น
การขัดข้องและการแฮงค์จะถือว่า "ไม่ซ้ำกัน" หากเส้นทางการดำเนินการที่เกี่ยวข้องเกี่ยวข้องกับการเปลี่ยนสถานะใดๆ ที่ไม่เคยเห็นในข้อบกพร่องที่บันทึกไว้ก่อนหน้านี้ หากสามารถเข้าถึงจุดบกพร่องเพียงจุดเดียวได้หลายวิธี จะมีการนับอัตราเงินเฟ้อในช่วงต้นของกระบวนการ แต่การดำเนินการนี้ควรจะลดลงอย่างรวดเร็ว
ชื่อไฟล์สำหรับข้อขัดข้องและการแฮงค์มีความสัมพันธ์กับรายการคิวหลักที่ไม่ใช่ข้อผิดพลาด สิ่งนี้ควรช่วยในการดีบัก
เมื่อคุณไม่สามารถสร้างข้อขัดข้องที่พบโดย afl-fuzz สาเหตุที่เป็นไปได้มากที่สุดคือคุณไม่ได้ตั้งค่าขีดจำกัดหน่วยความจำเดียวกันกับที่เครื่องมือใช้ พยายาม:
$ LIMIT_MB=50
$ ( ulimit -Sv $[LIMIT_MB << 10] ; /path/to/tested_binary ... )
เปลี่ยน LIMIT_MB เพื่อให้ตรงกับพารามิเตอร์ -m ที่ส่งไปยัง afl-fuzz บน OpenBSD ให้เปลี่ยน -Sv เป็น -Sd
ไดเร็กทอรีเอาต์พุตใดๆ ที่มีอยู่สามารถใช้เพื่อดำเนินงานที่ถูกยกเลิกต่อไปได้ พยายาม:
$ ./afl-fuzz -i- -o existing_output_dir [...etc...]
หากคุณติดตั้ง gnuplot ไว้ คุณสามารถสร้างกราฟสวยๆ สำหรับงาน fuzzing ที่ใช้งานอยู่โดยใช้ afl-plot ได้ สำหรับตัวอย่างลักษณะนี้ โปรดดูที่ http://lcamtuf.coredump.cx/afl/plot/
ทุกอินสแตนซ์ของ afl-fuzz จะใช้ประมาณหนึ่งคอร์ ซึ่งหมายความว่าบนระบบมัลติคอร์ จำเป็นต้องมีการทำงานแบบขนานเพื่อใช้งานฮาร์ดแวร์ได้อย่างเต็มที่ สำหรับเคล็ดลับเกี่ยวกับวิธีการคลุมเครือเป้าหมายทั่วไปบนหลายคอร์หรือเครื่องที่เชื่อมต่อเครือข่ายหลายเครื่อง โปรดดูที่parallel_fuzzing.txt
โหมดการฟัซซิงคู่ขนานยังนำเสนอวิธีง่ายๆ ในการเชื่อมต่อ AFL กับฟัซเซอร์อื่นๆ กับเอ็นจิ้นการดำเนินการเชิงสัญลักษณ์หรือแบบคอนโคลิค และอื่นๆ อีกครั้ง โปรดดูคำแนะนำในส่วนสุดท้ายของ Parallel_fuzzing.txt
ตามค่าเริ่มต้น เอ็นจิ้นการกลายพันธุ์ afl-fuzz ได้รับการปรับให้เหมาะสมสำหรับรูปแบบข้อมูลขนาดกะทัดรัด เช่น รูปภาพ มัลติมีเดีย ข้อมูลที่บีบอัด ไวยากรณ์นิพจน์ทั่วไป หรือเชลล์สคริปต์ ค่อนข้างไม่ค่อยเหมาะกับภาษาที่มีการใช้คำฟุ่มเฟือยและซ้ำซ้อน โดยเฉพาะ HTML, SQL หรือ JavaScript
เพื่อหลีกเลี่ยงความยุ่งยากในการสร้างเครื่องมือที่คำนึงถึงไวยากรณ์ afl-fuzz จัดเตรียมวิธีการเริ่มต้นกระบวนการคลุมเครือด้วยพจนานุกรมเสริมของคีย์เวิร์ดภาษา ส่วนหัวเวทย์มนตร์ หรือโทเค็นพิเศษอื่น ๆ ที่เกี่ยวข้องกับประเภทข้อมูลเป้าหมาย และใช้สิ่งนั้นเพื่อสร้างใหม่ ไวยากรณ์พื้นฐานในระหว่างการเดินทาง:
http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html
หากต้องการใช้คุณลักษณะนี้ คุณต้องสร้างพจนานุกรมในรูปแบบใดรูปแบบหนึ่งจากสองรูปแบบที่กล่าวถึงในพจนานุกรม/README.dictionaries ก่อน จากนั้นชี้ fuzzer ไปที่มันผ่านตัวเลือก -x ในบรรทัดคำสั่ง
(มีพจนานุกรมทั่วไปหลายพจนานุกรมไว้ในไดเรกทอรีย่อยนั้นด้วย)
ไม่มีวิธีใดที่จะให้คำอธิบายที่มีโครงสร้างมากขึ้นของไวยากรณ์พื้นฐานได้ แต่ fuzzer มีแนวโน้มที่จะเข้าใจสิ่งนี้บางส่วนตามคำติชมของเครื่องมือวัดเพียงอย่างเดียว สิ่งนี้ใช้ได้จริงในทางปฏิบัติ พูดว่า:
http://lcamtuf.blogspot.com/2015/04/finding-bugs-in-sqlite-easy-way.html
ป.ล. แม้ว่าจะไม่ได้ให้พจนานุกรมที่ชัดเจนก็ตาม afl-fuzz จะพยายามแยกโทเค็นไวยากรณ์ที่มีอยู่ในคลังข้อมูลอินพุตโดยดูเครื่องมืออย่างใกล้ชิดระหว่างการพลิกไบต์ที่กำหนด วิธีนี้ใช้ได้กับ parsers และไวยากรณ์บางประเภท แต่ทำงานได้ไม่ดีเท่าโหมด -x
หากพจนานุกรมนั้นหาได้ยากจริงๆ อีกทางเลือกหนึ่งคือปล่อยให้ AFL ทำงานสักพักหนึ่ง จากนั้นใช้ไลบรารีการจับโทเค็นที่มาพร้อมกับโปรแกรมอรรถประโยชน์ที่ใช้ร่วมกับ AFL หากต้องการดู libtokencap/README.tokencap
การจัดกลุ่มข้อขัดข้องตามความครอบคลุมมักจะสร้างชุดข้อมูลขนาดเล็กที่สามารถทดสอบด้วยตนเองได้อย่างรวดเร็วหรือด้วยสคริปต์ GDB หรือ Valgrind ที่เรียบง่าย ทุกข้อขัดข้องยังสามารถตรวจสอบย้อนกลับไปยังกรณีทดสอบการไม่ขัดข้องหลักในคิว ทำให้วินิจฉัยข้อผิดพลาดได้ง่ายขึ้น
ต้องบอกว่า สิ่งสำคัญคือต้องรับทราบว่าข้อขัดข้องที่ไม่ชัดเจนบางอย่างอาจเป็นเรื่องยากที่จะประเมินความสามารถในการหาประโยชน์ได้อย่างรวดเร็ว โดยไม่ต้องทำการดีบักและวิเคราะห์โค้ดมากนัก เพื่อช่วยในงานนี้ afl-fuzz รองรับโหมด "การสำรวจข้อขัดข้อง" ที่เป็นเอกลักษณ์ซึ่งเปิดใช้งานด้วยแฟล็ก -C
ในโหมดนี้ fuzzer จะใช้กรณีทดสอบการขัดข้องตั้งแต่หนึ่งกรณีขึ้นไปเป็นอินพุต และใช้กลยุทธ์การคลุมเครือที่ขับเคลื่อนด้วยผลตอบรับเพื่อระบุเส้นทางโค้ดทั้งหมดที่สามารถเข้าถึงได้ในโปรแกรมอย่างรวดเร็ว ในขณะเดียวกันก็รักษาให้อยู่ในสถานะขัดข้อง
การกลายพันธุ์ที่ไม่ส่งผลให้เกิดความผิดพลาดจะถูกปฏิเสธ การเปลี่ยนแปลงใด ๆ ที่ไม่ส่งผลกระทบต่อเส้นทางการดำเนินการก็เช่นกัน
ผลลัพธ์คือคลังข้อมูลไฟล์ขนาดเล็กที่สามารถตรวจสอบได้อย่างรวดเร็วเพื่อดูว่าผู้โจมตีมีระดับการควบคุมที่อยู่ที่มีข้อบกพร่องหรือไม่ หรือเป็นไปได้หรือไม่ที่จะข้ามการอ่านนอกขอบเขตเริ่มต้น - และดูว่ามีอะไรอยู่ข้างใต้ .
โอ้ อีกอย่างหนึ่ง: สำหรับการลดขนาดกรณีทดสอบ ให้ลอง afl-tmin ดู เครื่องมือนี้สามารถใช้งานได้ด้วยวิธีง่ายๆ:
$ ./afl-tmin -i test_case -o minimized_result -- /path/to/program [...]
เครื่องมือนี้ใช้งานได้กับกรณีทดสอบการขัดข้องและไม่ขัดข้อง ในโหมดแครช ระบบจะยอมรับไบนารีที่มีเครื่องมือและไม่มีเครื่องมืออย่างมีความสุข ในโหมดไม่ขัดข้อง ตัวย่อขนาดจะขึ้นอยู่กับเครื่องมือ AFL มาตรฐานเพื่อทำให้ไฟล์ง่ายขึ้นโดยไม่ต้องเปลี่ยนเส้นทางการดำเนินการ
ตัวย่อยอมรับไวยากรณ์ -m, -t, -f และ @@ ในลักษณะที่เข้ากันได้กับ afl-fuzz
สิ่งเพิ่มเติมล่าสุดของ AFL คือเครื่องมือวิเคราะห์ afl ใช้ไฟล์อินพุต พยายามพลิกไบต์ตามลำดับ และสังเกตพฤติกรรมของโปรแกรมที่ทดสอบ จากนั้นจะกำหนดรหัสสีให้กับอินพุตตามส่วนที่เห็นว่ามีความสำคัญและส่วนที่ไม่สำคัญ แม้ว่าจะไม่กันกระสุน แต่ก็มักจะให้ข้อมูลเชิงลึกอย่างรวดเร็วเกี่ยวกับรูปแบบไฟล์ที่ซับซ้อน ข้อมูลเพิ่มเติมเกี่ยวกับการดำเนินงานสามารถดูได้ที่ส่วนท้ายของtechnical_details.txt
Fuzzing เป็นเทคนิคที่ยอดเยี่ยมและใช้งานน้อยเกินไปในการค้นหาข้อผิดพลาดด้านการออกแบบและการใช้งานที่ไม่ขัดข้องเช่นกัน พบข้อบกพร่องที่น่าสนใจบางประการโดยการปรับเปลี่ยนโปรแกรมเป้าหมายให้เรียก abort() เมื่อพูดว่า:
ไลบรารี่ bignum สองแห่งสร้างเอาต์พุตที่แตกต่างกันเมื่อได้รับอินพุตที่สร้างจากฟัซเซอร์เดียวกัน
ไลบรารีรูปภาพจะสร้างเอาต์พุตที่แตกต่างกันเมื่อถูกขอให้ถอดรหัสรูปภาพอินพุตเดียวกันหลายครั้งติดต่อกัน
ไลบรารีการทำให้เป็นอนุกรม / ดีซีเรียลไลซ์ล้มเหลวในการสร้างเอาต์พุตที่เสถียรเมื่อทำการซีเรียลไลซ์และดีซีเรียลไลซ์ข้อมูลที่มาจาก fuzzer ซ้ำ ๆ
ไลบรารีการบีบอัดจะสร้างเอาต์พุตที่ไม่สอดคล้องกับไฟล์อินพุตเมื่อถูกขอให้บีบอัดแล้วขยายขนาดหยดเฉพาะ
การดำเนินการตรวจสอบสุขภาพจิตเหล่านี้หรือที่คล้ายกันมักใช้เวลาน้อยมาก หากคุณเป็นผู้ดูแลแพ็คเกจใดแพ็คเกจหนึ่ง คุณสามารถทำให้โค้ดนี้มีเงื่อนไขด้วย #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
(แฟล็กที่แชร์กับ libfuzzer ด้วย) หรือ #ifdef __AFL_COMPILER
(อันนี้มีไว้สำหรับ AFL เท่านั้น)
โปรดจำไว้ว่า เช่นเดียวกับงานอื่นๆ ที่ต้องใช้การคำนวณสูง การคลุมเครืออาจทำให้ฮาร์ดแวร์และระบบปฏิบัติการของคุณเกิดความตึงเครียด โดยเฉพาะ:
CPU ของคุณจะร้อนและต้องการการระบายความร้อนที่เพียงพอ ในกรณีส่วนใหญ่ หากการระบายความร้อนไม่เพียงพอหรือหยุดทำงานตามปกติ ความเร็วของ CPU จะถูกควบคุมโดยอัตโนมัติ ดังที่กล่าวไว้ โดยเฉพาะอย่างยิ่งเมื่อต้องยุ่งเกี่ยวกับฮาร์ดแวร์ที่เหมาะสมน้อยกว่า (แล็ปท็อป สมาร์ทโฟน ฯลฯ) ก็ไม่ใช่เรื่องที่เป็นไปไม่ได้เลยที่จะมีบางอย่างระเบิด
โปรแกรมเป้าหมายอาจจบลงด้วยการคว้าหน่วยความจำกิกะไบต์หรือทำให้พื้นที่ดิสก์เต็มด้วยไฟล์ขยะ แอฟพยายามบังคับใช้ขีดจำกัดหน่วยความจำพื้นฐาน แต่ไม่สามารถป้องกันอุบัติเหตุที่อาจเกิดขึ้นได้ทุกครั้ง สิ่งสำคัญที่สุดคือคุณไม่ควรสับสนกับระบบที่ข้อมูลอาจสูญหายไม่ใช่ความเสี่ยงที่ยอมรับได้
การฟัซซิ่งเกี่ยวข้องกับการอ่านและเขียนหลายพันล้านครั้งไปยังระบบไฟล์ ในระบบสมัยใหม่ สิ่งนี้มักจะถูกแคชไว้อย่างหนัก ส่งผลให้ I/O "ทางกายภาพ" ค่อนข้างเรียบง่าย - แต่มีหลายปัจจัยที่อาจเปลี่ยนแปลงสมการนี้ได้ เป็นความรับผิดชอบของคุณที่จะต้องติดตามปัญหาที่อาจเกิดขึ้น ด้วย I/O ที่หนักมาก อายุการใช้งานของ HDD และ SSD จำนวนมากอาจลดลง
วิธีที่ดีในการตรวจสอบดิสก์ I/O บน Linux คือคำสั่ง 'iostat':
$ iostat -d 3 -x -k [...optional disk ID...]
คำเตือนที่สำคัญที่สุดสำหรับ AFL มีดังนี้
AFL ตรวจพบข้อผิดพลาดโดยการตรวจสอบกระบวนการที่เกิดครั้งแรกที่ตายเนื่องจากสัญญาณ (SIGSEGV, SIGABRT ฯลฯ) โปรแกรมที่ติดตั้งตัวจัดการแบบกำหนดเองสำหรับสัญญาณเหล่านี้อาจจำเป็นต้องมีโค้ดที่เกี่ยวข้องใส่เครื่องหมายความคิดเห็นไว้ ในทำนองเดียวกัน ข้อผิดพลาดในเด็กที่ประมวลผลโดยเป้าหมายที่คลุมเครืออาจหลบเลี่ยงการตรวจจับ เว้นแต่คุณจะเพิ่มโค้ดด้วยตนเองเพื่อตรวจจับสิ่งนั้น
เช่นเดียวกับเครื่องมือแบบ brute-force อื่นๆ fuzzer ให้ความคุ้มครองที่จำกัด หากมีการใช้การเข้ารหัส เช็คซัม ลายเซ็นการเข้ารหัส หรือการบีบอัดเพื่อรวมรูปแบบข้อมูลจริงที่จะทดสอบทั้งหมด
หากต้องการแก้ไขปัญหานี้ คุณสามารถแสดงความคิดเห็นเกี่ยวกับการตรวจสอบที่เกี่ยวข้องได้ (ดูการทดลอง/libpng_no_checksum/ เพื่อเป็นแรงบันดาลใจ) หากเป็นไปไม่ได้ คุณยังสามารถเขียนโปรเซสเซอร์หลังได้ ตามที่อธิบายไว้ในการทดลอง/post_library/
มีข้อเสียบางประการกับ ASAN และไบนารี 64 บิต นี่ไม่ได้เกิดจากความผิดพลาดเฉพาะของ afl-fuzz; ดู tips_for_asan.txt สำหรับเคล็ดลับ
ไม่มีการสนับสนุนโดยตรงสำหรับบริการเครือข่ายแบบคลุมเครือ เดมอนพื้นหลัง หรือแอปแบบโต้ตอบที่ต้องใช้การโต้ตอบกับ UI จึงจะทำงานได้ คุณอาจต้องเปลี่ยนแปลงโค้ดง่ายๆ เพื่อให้โค้ดทำงานในลักษณะดั้งเดิมมากขึ้น Preeny อาจเสนอตัวเลือกที่ค่อนข้างง่ายเช่นกัน - ดู: https://github.com/zardus/preeny
เคล็ดลับที่เป็นประโยชน์สำหรับการปรับเปลี่ยนบริการบนเครือข่ายสามารถดูได้ที่: https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop
แอฟไม่ส่งออกข้อมูลความครอบคลุมที่มนุษย์สามารถอ่านได้ หากคุณต้องการตรวจสอบความครอบคลุม ให้ใช้ afl-cov จาก Michael Rash: https://github.com/mrash/afl-cov
ในบางครั้ง เครื่องจักรที่มีความรู้สึกก็ลุกขึ้นต่อสู้กับผู้สร้าง หากสิ่งนี้เกิดขึ้นกับคุณ โปรดปรึกษา http://lcamtuf.coredump.cx/prep/
นอกเหนือจากนี้ โปรดดูคำแนะนำเฉพาะแพลตฟอร์มในการติดตั้ง
การปรับปรุงหลายอย่างใน afl-fuzz จะไม่สามารถทำได้หากไม่มีข้อเสนอแนะ รายงานข้อผิดพลาด หรือแพตช์จาก:
Jann Horn Hanno Boeck
Felix Groebert Jakub Wilk
Richard W. M. Jones Alexander Cherepanov
Tom Ritter Hovik Manucharyan
Sebastian Roschke Eberhard Mattes
Padraig Brady Ben Laurie
@dronesec Luca Barbato
Tobias Ospelt Thomas Jarosch
Martin Carpenter Mudge Zatko
Joe Zbiciak Ryan Govostes
Michael Rash William Robinet
Jonathan Gray Filipe Cabecinhas
Nico Weber Jodie Cunningham
Andrew Griffiths Parker Thompson
Jonathan Neuschfer Tyler Nighswander
Ben Nagy Samir Aguiar
Aidan Thornton Aleksandar Nikolich
Sam Hakim Laszlo Szekeres
David A. Wheeler Turo Lamminen
Andreas Stieger Richard Godbee
Louis Dassy teor2345
Alex Moneger Dmitry Vyukov
Keegan McAllister Kostya Serebryany
Richo Healey Martijn Bogaard
rc0r Jonathan Foote
Christian Holler Dominique Pelle
Jacek Wielemborek Leo Barnes
Jeremy Barnes Jeff Trull
Guillaume Endignoux ilovezfs
Daniel Godas-Lopez Franjo Ivancic
Austin Seipp Daniel Komaromy
Daniel Binderman Jonathan Metzman
Vegard Nossum Jan Kneschke
Kurt Roeckx Marcel Bohme
Van-Thuan Pham Abhik Roychoudhury
Joshua J. Drake Toby Hutton
Rene Freingruber Sergey Davidoff
Sami Liedes Craig Young
Andrzej Jackowski Daniel Hodson
ขอบคุณ!
คำถาม? กังวล? รายงานข้อผิดพลาด? กรุณาใช้ GitHub
นอกจากนี้ยังมีรายชื่อผู้รับจดหมายสำหรับโครงการ หากต้องการเข้าร่วม โปรดส่งอีเมลไปที่ [email protected] หรือหากคุณต้องการเรียกดูเอกสารสำคัญก่อน ให้ลอง: https://groups.google.com/group/afl-users