ช่องโหว่รูปแบบสตริง
ใช้ประโยชน์จากรูปแบบสตริงของ printf เพื่ออ่านหน่วยความจำตามอำเภอใจและเขียนไปยังแอดเดรสตามอำเภอใจ
ช่องโหว่รูปแบบสตริง เป็นบทเรียน Cyber Security Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Cyber Security Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Cyber Security Academy มีบทเรียนทั้งหมด 4 บทเรียน
ช่องโหว่สตริงรูปแบบคืออะไร
ช่องโหว่สตริงรูปแบบ เกิดขึ้นเมื่อส่งอินพุตของผู้ใช้โดยตรงเป็นอาร์กิวเมนต์สตริงรูปแบบให้กับ printf() หรือฟังก์ชันที่คล้ายกัน ผู้โจมตีสามารถอ่านหน่วยความจำ ทำให้แอดเดรสบนสแตกและเขียนค่าตามต้องการได้
รูปแบบที่มีช่องโหว่
แบบที่มีช่องโหว่เทียบกับแบบปลอดภัย:
// VULNERABLE - user controls the format string:
printf(user_input);
fprintf(stderr, user_input);
// SAFE - user input is a data argument:
printf("%s", user_input);การอ่านหน่วยความจำด้วย %x และ %p
ตัวระบุรูปแบบที่ไม่มีอาร์กิวเมนต์สอดคล้องกันจะอ่านค่าจากสแตก:
# Input: %p.%p.%p.%p.%p
# Output: 0x7ffd12345678.0x400580.0x0.0x1.0x7f3a...
# Each %p prints the next value off the stack - leaking addresses!การเอาชนะ ASLR ด้วยการรั่วไหลจากสตริงรูปแบบ
สแตกมักมีพอยน์เตอร์ไปยังไลบ์ซี สแตก และไบนารี ผู้โจมตีสามารถคำนวณแอดเดรสเริ่มต้นและเอาชนะ ASLR ได้ด้วยการทำให้ข้อมูลเหล่านี้รั่วไหลผ่านตัวระบุ %p หรือ %lx แม้จะไม่มีช่องโหว่อื่นใด
การอ่านหน่วยความจำตามต้องการด้วย %s
%s จะถือค่าบนสแตกเป็นพอยน์เตอร์และพิมพ์สตริงที่แอดเดรสนั้น การวางแอดเดรสเป้าหมายไว้ในตำแหน่งที่ถูกต้องบนสแตกและใช้การเข้าถึงพารามิเตอร์ (%7$s) ทำให้ผู้โจมตีอ่านตำแหน่งหน่วยความจำใด ๆ ได้
# Direct parameter access:
printf("%7$s") # prints string at 7th stack parameter
# If 7th param is an address you control, reads that memoryการเขียนหน่วยความจำด้วย %n
%n จะเขียนจำนวนอักขระที่พิมพ์ไปแล้วลงในแอดเดรสที่อาร์กิวเมนต์ที่สอดคล้องกันชี้อยู่ ทำให้สามารถเขียนค่าที่ควบคุมได้ลงในแอดเดรสใด ๆ และอาจเขียนทับพอยน์เตอร์ฟังก์ชันหรือแอดเดรสคืนค่าได้
เทคนิคการเขียนในทางปฏิบัติ
ในการเขียนค่าเฉพาะด้วย %n:
- ควบคุมพอยน์เตอร์บนสแตกให้ชี้ไปยังแอดเดรสเป้าหมาย
- ใช้
%Xc%N$nเพื่อเขียนอักขระ X ตัว แล้วเขียนจำนวนดังกล่าวลงในพารามิเตอร์ลำดับที่ N (แอดเดรสเป้าหมาย)
เครื่องมืออย่างไลบรารีไพดับเบิลยูเอ็นทูลส์ช่วยสร้างช่องโหว่จากสตริงรูปแบบโดยอัตโนมัติ
การค้นหาข้อผิดพลาดของสตริงรูปแบบ
การทดสอบหาช่องโหว่สตริงรูปแบบ:
# Test inputs:
%x.%x.%x
%p.%p.%p
%s%s%s
AAAA.%p.%p.%p.%p (looking for 0x41414141 in output)
# Automated testing with fuzzer:
python3 -c "print('%p.' * 20)" | ./vulnการป้องกัน: แก้ไขโค้ด
วิธีแก้ไขนั้นง่ายมาก เพียงส่งอินพุตของผู้ใช้เป็นอาร์กิวเมนต์ข้อมูลเสมอ และอย่าส่งเป็นสตริงรูปแบบ
// WRONG:
printf(buffer);
// RIGHT:
printf("%s", buffer);
// Compiler warning:
// gcc -Wformat-security will flag thisสตริงรูปแบบในภาษาอื่น
ช่องโหว่สตริงรูปแบบเกิดขึ้นได้ในหลายภาษา:
- ซี:
printf(input) - ไพธอน: ไม่เหมือนกันเสียทีเดียว — แต่การจัดรูปแบบด้วย
%ร่วมกับอินพุตแบบพจนานุกรมอาจเปิดเผยตัวแปรได้ - Java:
String.format(input)— อันตรายน้อยกว่าและไม่สามารถเข้าถึงหน่วยความจำได้
ตัวอย่างในโลกจริง
ข้อผิดพลาดของสตริงรูปแบบเคยส่งผลกระทบต่อ:
- ProFTPD — ทำให้สามารถเรียกใช้โค้ดจากระยะไกลผ่านคำสั่ง FTP
- WU-FTPD — ช่องโหว่โจมตีสิทธิ์ผู้ดูแลระบบจากระยะไกลผ่านสตริงรูปแบบ
- ดีมอนของลินุกซ์หลายรายการก่อนช่วงคริสต์ทศวรรษ 2000
คอมไพเลอร์สมัยใหม่และ FORTIFY_SOURCE ช่วยลดปัญหาได้ แต่ไม่สามารถกำจัดช่องโหว่ประเภทนี้ได้ทั้งหมด
ตรวจสอบอย่างรวดเร็ว: สตริงรูปแบบ
ตัวระบุรูปแบบใดสามารถใช้เพื่อเขียนไปยังแอดเดรสหน่วยความจำใด ๆ ในการโจมตีด้วยสตริงรูปแบบ
สรุปบทเรียน
ช่องโหว่สตริงรูปแบบเกิดขึ้นเมื่อใช้อินพุตของผู้ใช้โดยตรงเป็นสตริงรูปแบบของ printf %p/%x ทำให้หน่วยความจำบนสแตกรั่วไหล %s อ่านแอดเดรสใด ๆ ได้ และ %n เขียนไปยังแอดเดรสใด ๆ ได้ วิธีแก้ไขใช้เพียงอักขระเดียว: printf("%s", input) เปิดใช้ -Wformat-security ในแฟล็กของคอมไพเลอร์เพื่อตรวจจับปัญหาเหล่านี้
คำถามที่พบบ่อย
บทเรียน “ช่องโหว่รูปแบบสตริง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ช่องโหว่รูปแบบสตริง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Cyber Security Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Cyber Security Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ช่องโหว่รูปแบบสตริง”
ใช้ประโยชน์จากรูปแบบสตริงของ printf เพื่ออ่านหน่วยความจำตามอำเภอใจและเขียนไปยังแอดเดรสตามอำเภอใจ คุณปฏิบัติ Cyber Security Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Cyber Security Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Cyber Security Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ช่องโหว่รูปแบบสตริง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Cyber Security Academy นี้ได้ไหม
ได้ บทเรียน Cyber Security Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- บัฟเฟอร์ล้นบนสแตก
- การเขียนโปรแกรมแบบ Return-Oriented (ROP)
- ช่องโหว่รูปแบบสตริง
- การใช้ประโยชน์จากฮีป: Use-After-Free และการโปรยฮีป