0Pricing
Cyber Security Academy · บทเรียน

ช่องโหว่รูปแบบสตริง

ใช้ประโยชน์จากรูปแบบสตริงของ 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:

  1. ควบคุมพอยน์เตอร์บนสแตกให้ชี้ไปยังแอดเดรสเป้าหมาย
  2. ใช้ %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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. บัฟเฟอร์ล้นบนสแตก
  2. การเขียนโปรแกรมแบบ Return-Oriented (ROP)
  3. ช่องโหว่รูปแบบสตริง
  4. การใช้ประโยชน์จากฮีป: Use-After-Free และการโปรยฮีป
← กลับไปที่ Cyber Security Academy