
ไขรหัสลับฐานข้อมูล: เจาะลึก SQL Injection ด้วย Union Attack เพื่อตามหาข้อความสำคัญ
เมื่อพูดถึงช่องโหว่ทางความปลอดภัยบนเว็บแอปพลิเคชัน ชื่อของ SQL Injection มักเป็นที่รู้จักดี
มันคือเทคนิคที่ผู้ไม่หวังดีใช้คำสั่ง SQL เพื่อหลอกให้ฐานข้อมูลเปิดเผย หรือแม้แต่เปลี่ยนแปลงข้อมูลสำคัญ
หนึ่งในรูปแบบการโจมตีที่ทรงพลังคือ Union Attack ซึ่งช่วยผนวกผลลัพธ์จาก Query ของผู้โจมตีเข้ากับ Query ดั้งเดิมของเว็บไซต์
เป้าหมายหลักคือการดึงข้อมูลที่เป็น ข้อความ ออกมา ไม่ว่าจะเป็นชื่อผู้ใช้ รหัสผ่าน หรือข้อมูลสำคัญอื่นๆ ที่เก็บในฐานข้อมูล
แต่จะทำอย่างไรถ้าไม่รู้ว่าคอลัมน์ไหนในฐานข้อมูลรองรับข้อความ? นี่คือสิ่งที่จะพาไปเจาะลึก
ทำความเข้าใจพื้นฐาน Union Attack
Union Attack ทำงานโดยการรวมชุดผลลัพธ์ของสองคำสั่ง SELECT เข้าด้วยกัน
เงื่อนไขสำคัญคือจำนวนคอลัมน์และประเภทข้อมูลของคอลัมน์ในแต่ละ SELECT ต้องตรงกัน
หากไม่ตรงกัน ฐานข้อมูลจะแสดงข้อผิดพลาดออกมา ซึ่งข้อผิดพลาดนี้มีประโยชน์อย่างยิ่งในการโจมตี
ผู้โจมตีมักเริ่มต้นด้วยการหาจุดที่เว็บไซต์รับอินพุตที่สามารถสร้าง SQL Query ได้ เช่น พารามิเตอร์ใน URL หรือช่องค้นหา
จากนั้นจึงใส่คำสั่ง SQL พิเศษเพื่อทดสอบการตอบสนองของระบบ
ตามล่าจำนวนคอลัมน์ที่ถูกต้อง
ขั้นตอนแรกของ Union Attack คือการหาว่า Query ดั้งเดิมของเว็บไซต์ส่งคืนข้อมูลกี่คอลัมน์
วิธีที่นิยมคือใช้คำสั่ง ORDER BY และลองเพิ่มตัวเลขไปเรื่อยๆ
เช่น ' ORDER BY 1 --, ' ORDER BY 2 --, ' ORDER BY 3 --
หากใส่ตัวเลขเกินจำนวนคอลัมน์จริง ฐานข้อมูลจะฟ้อง error บอกว่าคอลัมน์นั้นไม่มีอยู่
ตัวเลขก่อนเกิด error จึงเป็นจำนวนคอลัมน์ที่ถูกต้อง
อีกวิธีคือใช้ UNION SELECT NULL, NULL, ...
ลองใส่ ' UNION SELECT NULL --, ' UNION SELECT NULL, NULL -- ไปเรื่อยๆ
จนกว่าจะไม่มี error และเว็บไซต์แสดงผลลัพธ์ได้
จำนวน NULL ที่ใส่แล้วไม่มี error คือจำนวนคอลัมน์นั่นเอง
ค้นหาคอลัมน์ที่รองรับข้อความ
เมื่อทราบจำนวนคอลัมน์แล้ว ขั้นตอนต่อไปคือการหาว่าคอลัมน์ไหนบ้างที่สามารถแสดง ข้อความ (string) ออกมาได้
เพราะการพยายามใส่ข้อความลงในคอลัมน์ที่รองรับแค่ตัวเลข จะทำให้ระบบเกิด error ขึ้นมา
เราจะทดสอบโดยใช้คำสั่ง UNION SELECT
เปลี่ยนค่า NULL ทีละตำแหน่งให้เป็น string เช่น 'a' เพื่อดูการตอบสนอง
ตัวอย่าง หากมี 3 คอลัมน์:
' UNION SELECT 'a', NULL, NULL --
หากเกิด error แสดงว่าคอลัมน์แรกไม่รองรับข้อความ
ลองเปลี่ยนไปตำแหน่งที่สอง:
' UNION SELECT NULL, 'a', NULL --
ถ้าปรากฏ 'a' บนหน้าเว็บ แสดงว่าคอลัมน์ที่สองรองรับข้อความได้
คอลัมน์นี้คือจุดที่เราจะใช้ดึงข้อมูลสำคัญในอนาคต
ทำแบบนี้ไปจนกว่าจะพบคอลัมน์ที่แสดงผลข้อความได้ตามต้องการ
หากเจอหลายคอลัมน์ ก็เลือกใช้คอลัมน์ที่สะดวกที่สุด
ตัวอย่างการใช้งานจริง
สมมติว่าพบแล้วว่าคอลัมน์ที่ 2 รองรับข้อความ
และทราบว่ามีตารางชื่อ users ซึ่งมีคอลัมน์ username และ password
สามารถดึงข้อมูลรหัสผ่านออกมาได้ง่ายๆ ด้วยคำสั่งประมาณนี้:
' UNION SELECT NULL, password FROM users --
หรือถ้าต้องการทั้งชื่อผู้ใช้และรหัสผ่าน อาจใช้ฟังก์ชันรวม string ของฐานข้อมูล เช่น CONCAT():
' UNION SELECT NULL, CONCAT(username, ':', password) FROM users --
ผลลัพธ์ที่ได้จะแสดงข้อมูลที่ต้องการบนหน้าเว็บ ซึ่งเป็นข้อมูลที่ผู้ไม่หวังดีต้องการอย่างมาก
การเข้าใจกระบวนการเหล่านี้ไม่เพียงช่วยในการทดสอบช่องโหว่
แต่ยังช่วยให้นักพัฒนาเว็บเข้าใจการป้องกันและออกแบบระบบให้ปลอดภัยยิ่งขึ้น เพื่อปกป้องข้อมูลสำคัญไม่ให้รั่วไหล