บทนำ (Overview)
ช่องโหว่ “SQL injection” นั้นปกติแล้วจะเกิดขึ้นกับ “Web application” ฝั่ง “Server side” แต่ในหัวข้อนี้จะกล่าวถึงการทำ “SQL injection” ฝั่งโปรแกรมบนมือถือ แม้จะพบไม่บ่อยครั้งในโปรแกรมสำคัญ ๆ ปัจจุบัน แต่ก็เป็นไปได้ เพราะช่องโหว่ดังกล่าวอาจส่งผลกระทบการโจมตีอื่น ๆ ต่อไปได้ เช่นการดึงข้อมูลสำคัญในฐานข้อมูล แม้ไฟล์จะมีการเข้ารหัส การ “Bypass” หน้า “Login” สำหรับโปรแกรมประเภท “Stand Alone” เป็นต้น
ขั้นตอน (Steps)
- ดาวน์โหลด iGoat
- ติดตั้งโปรแกรม XCODE
- ไปที่โฟลเดอร์ iGoat ที่เราดาวน์โหลดมา แล้วหาไฟล์โปรเจค “xcode” (iGoat.xcodeproj)
- ให้ดับเบิ้ลคลิกไฟล์ “iGoat.xcodeproj” เพื่อโหลดโปรเจคเข้า “xcode”
- คลิกปุ่ม “Run” โปรแกรมบน “iOS Simulator”
- รอจนกระทั่งโปรแกรมถูกเปิดขึ้นมาบน “iOS Simulator”
- ให้คลิก “Dismiss”
- เลือกช่องโหว่ “Injection Flaws”
- เลือก “SQL injection”
- คลิก “Start”
- จากโปรแกรมเป็นฟังก์ชันสำหรับการค้นหา ดังนั้นลองเริ่มต้นหาสัญญาณที่จะบ่งบอกว่ามีช่องโหว่ “SQL injection” โดยทดลองค้นหาแบบไม่ต้องกรอกข้อมูลก่อน พบว่าผลการค้นหามีข้อมูล 2 รายการ
- ที่นี้ลองกรอก Single qoute ( ‘ ) เข้าไป โดยปกติ single qoute ใช้สำหรับข้อมูลประเภทตัวอักษร เพราะฉะนั้นจะต้องมีโครงสร้าง เช่น ‘test‘ คือมีเปิดและมีปิด ที่นี้เราลองใส่ Single qoute ไปอันเดียว โดยสมมติฐานจะต้องมี ข้อความผิดพลาด (database error) ออกมา
- แต่จากการทดลองพบว่าไม่มี “Error” ใด ๆ แต่ก็ยังเป็นไปได้ว่ายังมีช่องโหว่ “SQL injection” อยู่
- เนื่องจากไม่มีผลลัพท์ของข้อผิดพลาดฐานข้อมูล (error-based sql injection) จึงจำเป็นต้องทดสอบโดยใช้ double dash ( — ) ซึ่งเป็นคำสั่งของ “Comments” เป็นผลให้คำสั่งฐานข้อมูลจะไม่ประมวลผล จากสมมติฐานถ้ามี “Error” จากฐานข้อมูลก็อาจเป็นไปได้ว่ามีช่องโหว่ “SQL injection”
- ผลการทดสอบไม่มี “Error” ใด ๆ จากฐานข้อมูล แต่เรากลับพบว่า มี 3 รายการ ที่แสดง และมากกว่าเดิมจากที่ไม่กรอกข้อมูลใด ๆ จากสัญญาณดังกล่าวเป็นไปได้ว่าอาจจะมีช่องโหว่ “SQL injection”
- เราจะเริ่มพยายามเข้าถึงโครงสร้างฐานข้อมูล “SQLite” โดยเริ่มจากทดลองใช้คำสั่ง “order by” เพื่อค้นหาจำนวน “column” ในฐานข้อมูลที่ถูก “query” ขึ้นมาเพื่อแสดงผลบนโปรแกรม โดย “order by” นั้นมีโครงสร้าง คือ order by ลำดับ_column โดยเราเริ่มจาก column ที่ 1 (คำสั่ง order by ถูกใช้สำหรับการเรียงลำดับค่าของ record ของแต่ละข้อมูล จากมากไปน้อย หรือน้อยไปมาก ตามแต่ที่กำหนดตำแหน่ง column)
- ตรวจสอบผลลัพท์พบว่า มีรายการแสดง 3 รายการ แสดงว่าตำแหน่ง “column” ที่ 1 มีอยู่จริง
- ที่นี้ลองเปลี่ยนจาก column 1 เป็น column 2
- จากผลการตรวจสอบไปผลรายการใด ๆ เลย โดยปกติจะมีข้อมูลผิดพลาดจากฐานข้อมูล แต่ในกรณีอาจเป็นเหตุได้ว่า โปรแกรม “query” เพียง “1 column” เท่านั้น
- เมื่อเราทราบแล้วว่า โปรแกรม “query” ข้อมูลโดยใช้เพียง “column” เดียวเราทดลอง “join” ข้อมูลของเราเข้าไปร่วมด้วยโดยใช้คำสั่ง union select ‘test’ ดังนี้
- ผลจากการทดสอบพบว่า คำสั่ง “SQL” ของเราสามารถประมวลผลร่วมกับคำสั่งของโปรแกรมส่งผลให้สามารถแสดงผลข้อความ (test) ตามที่เรากำหนด
- ลองเปลี่ยนมาใช้คำสั่งแสดง version ดังนี้ select sqlite_version();
- ทดลองหาตารางทั้งหมดภายในฐานข้อมูลโดย “query” ข้อมูลจากตาราง “sqlite_master” โดยใช้คำสั่ง “select name from sqlite_master” จากตัวอย่างเราพบว่ามีตาราง “article” เพียงตารางเดียว