How to bypass authentication using SQLi

บทนำ (Overview)

ปัญหาใหญ่ของการโจมตีเว็บไซต์ที่มีหน้า “Login” คือ “Hacker” สามารถ “Login” เข้าระบบได้โดยไม่มีบัญชีผู้ใช้ (Username และ Password) แล้วเขาเหล่า “Login” ด้วยอะไร เขาใช้คำสั่งของฐานข้อมูลทำให้หน้า “Login” เกิดความสับสนจนนำไปสู่ การ “Login” ที่สำเร็จ

ประเด็นสำคัญคือโปรแกรมเมอร์อาจไม่ทราบหรือไม่ใส่ใจในกระบวนการ “Login” โดยรับค่าจากผู้ใช้งานและไปตรวจสอบว่าในฐานข้อมูลนั้นมีข้อมูลตามที่ผู้ใช้กรอกหรือไม่ ถ้ามีแสดงว่าถูกต้อง ถ้าไม่มีแสดงว่าไม่ถูกต้อง ด้วยเหตุนี้อาจเป็นไปได้ว่า ค่าที่ Hacker ใส่เข้าไปนั้นสามารถทำให้แสดงว่าถูกต้องเสมอ

ความเสี่ยงของ SQLi (SQL injection) นั้นเป็นความเสี่ยงที่อยู่ใน TOP 10 ของ OWASP https://www.owasp.org/index.php/Top_10_2013-A1-Injection

ขั้นตอน (Steps)

  1.  ติดตั้ง OWASP Mutillidae II (เว็บไซต์ใช้สำหรับการทดสอบช่องโหว่ของ OWASP) จาก http://sourceforge.net/projects/mutillidae/?source=typ_redirect
  2. ไปที่หัวข้อ “SQLi – Bypass Authentication”sqli_bypass_login1
  3. จากนั้นลองทดสอบใส่ ‘ (single quote) และคลิกปุ่ม “Login” เพื่อหาว่ามีข้อผิดพลาดใดที่เปิดเผยมาบ้าง sqli_bypass_login2
  4. พบว่าที่ข้อความแสดงข้อผิดพลาดของฐานข้อมูลออกมา เมื่อ ‘ ทุกไปแทนที่ ” ส่งผลให้ เป็น ”’ นั้นหมายความว่าคำสั่งของภาษา SQL มีการปิดไม่สมบูรณ์ เพราะข้อความประเภท String จะต้องถูกเปิดและปิดด้วย ” เช่น ‘username’ เป็นต้นsqli_bypass_login3
  5. ด้วยเหตุผลนี้เราจึงใช้คำสั่งในข่อง “username” เป็น ‘ or ‘1’  = ‘1 จะมี “Syntax SQL” ดังนี้
    SELECT username FROM accounts WHERE username='' or '1' = '1';
    

    ความหมายนั้นคือให้ค้นหา username ที่ไม่มี (”) หรือมี (‘1′ =’1’) ออกมานั้นหมายความว่าเราจะสามารถดึง account ในฐานข้อมูลทั้งหมดออกมา

  6. ลองใส่ ‘ ซ้ำที่ช่อง “password” จะพบข้อความผิดพลาดเช่นเดิมแต่จะเพิ่ม password เข้ามาsqli_bypass_login4
  7. เพราะฉะนั้นเราสามารถ  “Bypass” หน้า “Login” โดยปราศจาก user account ได้ดังนี้
    • ถ้าใส่ ‘ or ‘1’ = ‘1 ที่ช่อง “Username” และ “Password” จะมี “Syntax SQL” ดังนี้
      SELECT username FROM accounts WHERE username='' or '1' = '1' AND password='' or '1' = '1';
      
    • เราสามารถใส่เฉพาะช่อง “username” ได้ (โดยไม่ต้องกรอก password) โดยใช้คำสั่ง ‘ or ‘1’ = ‘1’# จะมี “Syntax SQL” ดังนี้
      SELECT username FROM accounts WHERE username='' or '1' = '1'#'; AND password='';
      

      โดย # หมายถึง “comment” (จะไม่มีผลต่อการประมวลคำสั่ง) ในคำสั่งของ “SQL” ของฐานข้อมูล “MySQL server”

    • และเราก็สามารถใส่เฉพาะช่อง “password” ได้ (โดยไม่ต้องกรอก username) โดยใช้คำสั่ง ‘ or ‘1’ = ‘1 เช่นเดิม ส่งผลให้มี “Syntax SQL” ดังนี้
      SELECT username FROM accounts WHERE username='' AND password='' or '1' = '1';
      
  8. ผลของการสามารถ “Bypass” ของหน้า “Login”sqli_bypass_login5

สรุปผลการทดสอบ (Conclusion)

การโจมตีของ “SQL injection” นั้นส่งผลต่อความน่าเชื่อของระบบ Hacker สามารถที่จะเข้าระบบโดยปราศจาก “username” และ “password” เพื่อโจมตีระบบต่อไป ซึ่งก็ขึ้นฟังก์ชันการทำงานของระบบนั้น ๆ ในการป้องกันผู้พัฒนาระบบจะต้องมีการป้องกัน ข้อมูลที่สามารถกรอกมาจากผู้ใช้โดยอาจใช้ฟังก์ชัน ของ PreparedStatement ในการเชื่อมต่อกับฐานข้อมูล เพื่อให้มองเห็นว่าอักขระพิเศษ หรือคำสั่งเช่น ‘ # OR AND = เป็นเพียงข้อมูลประเภท “String” เท่านั้น แทนการเขียนเชื่อมต่อ “String” ดังตัวอย่าง

ใส่ความเห็น