บทช่วยสอนการฉีด SQL: เรียนรู้จากตัวอย่าง

⚡ สรุปอย่างชาญฉลาด

การโจมตีแบบ SQL injection คือการโจมตีที่แทรกแซงคำสั่ง SQL แบบไดนามิกเพื่อหลีกเลี่ยงการตรวจสอบสิทธิ์หรือเปิดเผยข้อมูล โดยใช้ประโยชน์จากแอปพลิเคชันเว็บที่สร้างคำสั่งค้นหาจากข้อมูลที่ผู้ใช้ป้อนเข้ามาโดยไม่ได้ตรวจสอบความถูกต้อง หน้านี้จะแสดงวิธีการทำงานของการโจมตีและวิธีการป้องกัน

  • 💉 ความหมาย: การโจมตีแบบ SQL injection คือการแทรกโค้ด SQL ที่เป็นอันตรายเข้าไปในแบบสอบถามผ่านช่องป้อนข้อมูลที่ไม่ได้ตรวจสอบความถูกต้อง
  • 🔓 ผลกระทบ: การโจมตีที่ประสบความสำเร็จสามารถข้ามขั้นตอนการล็อกอินและอ่าน แก้ไข หรือลบข้อมูลได้
  • 🧪 ตัวอย่าง: เงื่อนไขที่เป็นจริงเสมอ บวกกับข้อความอธิบาย จะเปลี่ยนการตรวจสอบการเข้าสู่ระบบให้กลายเป็นการข้ามการตรวจสอบ
  • 🛠️ เครื่องมือ: SQLMap และ jSQL ช่วยในการตรวจจับและใช้ประโยชน์จากพารามิเตอร์ที่สามารถแทรกเข้าไปได้โดยอัตโนมัติ
  • 🛡️ การป้องกัน: การใช้แบบสอบถามที่มีพารามิเตอร์ การตรวจสอบความถูกต้องของข้อมูล และบัญชีผู้ใช้ที่มีสิทธิ์น้อยที่สุด ช่วยลดช่องว่างดังกล่าวได้
  • 🤖 ความทันสมัยที่ลงตัว: เครื่องสแกนและไฟร์วอลล์ที่ขับเคลื่อนด้วย AI สามารถตรวจจับรูปแบบการแทรกข้อมูลที่ลายเซ็นแบบตายตัวตรวจไม่พบ

บทช่วยสอนการโจมตี SQL Injection

การฉีด SQL คืออะไร?

การโจมตีแบบ SQL Injection คือการปลอมแปลงคำสั่ง SQL แบบไดนามิก โดยการลบส่วนใดส่วนหนึ่งของคำสั่งออก หรือเพิ่มเงื่อนไขที่จะเป็นจริงเสมอ การโจมตีนี้ใช้ประโยชน์จากข้อบกพร่องในการออกแบบเว็บแอปพลิเคชันที่ไม่ดี เพื่อใช้ประโยชน์จากคำสั่ง SQL ในการเรียกใช้โค้ด SQL ที่เป็นอันตราย

ข้อมูลเป็นองค์ประกอบที่สำคัญที่สุดอย่างหนึ่งของระบบสารสนเทศ องค์กรต่างๆ ใช้เว็บแอปพลิเคชันที่ขับเคลื่อนด้วยฐานข้อมูลเพื่อรับข้อมูลจากลูกค้า SQL เป็นตัวย่อของ Structured Query Languageใช้สำหรับเรียกดูและจัดการข้อมูลในฐานข้อมูล

แผนภาพแสดงวิธีการที่การโจมตีแบบ SQL injection เข้าไปเปลี่ยนแปลงคำสั่งค้นหาข้อมูลแบบไดนามิกในฐานข้อมูล

การโจมตีแบบ SQL Injection ทำงานอย่างไร?

ประเภทของการโจมตีที่สามารถทำได้โดยใช้ SQL injection นั้นแตกต่างกันไป ขึ้นอยู่กับประเภทของเอนจินฐานข้อมูล การโจมตีนี้ทำงานกับคำสั่ง SQL แบบไดนามิก คำสั่งแบบไดนามิกคือคำสั่งที่สร้างขึ้นในระหว่างการทำงานโดยใช้พารามิเตอร์ที่ส่งมาจากแบบฟอร์มเว็บหรือสตริงคำค้นหา URI

ตัวอย่างการฉีด SQL

ลองพิจารณาแอปพลิเคชันเว็บอย่างง่ายที่มีแบบฟอร์มล็อกอิน โค้ด HTML สำหรับแบบฟอร์มแสดงอยู่ด้านล่าง

<form action=‘index.php’ method="post">

<input type="email" name="email" required="required"/>

<input type="password" name="password"/>

<input type="checkbox" name="remember_me" value="Remember me"/>

<input type="submit" value="Submit"/>

</form>

ที่นี่

  • แบบฟอร์มด้านบนจะรับที่อยู่อีเมลและรหัสผ่าน จากนั้นส่งข้อมูลไปยัง... PHP ไฟล์ชื่อ index.php
  • มีตัวเลือกในการบันทึกเซสชันการเข้าสู่ระบบลงในคุกกี้ เราอนุมานได้จากช่องทำเครื่องหมาย remember_me ระบบใช้เมธอด POST ในการส่งข้อมูล ซึ่งหมายความว่าค่าต่างๆ จะไม่แสดงในหน้าจอ URL.

สมมติว่าคำสั่งในส่วนแบ็กเอนด์สำหรับการตรวจสอบรหัสผู้ใช้มีดังต่อไปนี้

SELECT * FROM users WHERE email = $_POST['email'] AND password = md5($_POST['password']);

ที่นี่

  • คำสั่งข้างต้นใช้ค่าจากอาร์เรย์ $_POST[] โดยตรงโดยไม่ทำการตรวจสอบความปลอดภัย
  • รหัสผ่านจะถูกเข้ารหัสด้วยอัลกอริทึม MD5

เราจะสาธิตการโจมตีแบบ SQL injection โดยใช้ตัวอย่างต่อไปนี้ SQL Fiddle. เปิด URL http://sqlfiddle.com/ ในเว็บเบราว์เซอร์ของคุณ คุณจะเห็นหน้าต่างต่อไปนี้

หมายเหตุ: คุณจะต้องเขียนคำสั่ง SQL ด้วยตนเอง

ว่างเปล่า SQL Fiddle หน้าต่างพร้อมสำหรับโครงสร้างข้อมูลและการสืบค้น

ขั้นตอน 1) ป้อนรหัสนี้ในช่องด้านซ้าย

CREATE TABLE `users` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `email` VARCHAR(45) NULL,
  `password` VARCHAR(45) NULL,
  PRIMARY KEY (`id`));
  
  
insert into users (email,password) values ('m@m.com',md5('abc'));

ขั้นตอน 2) คลิก สร้างสคีมา (Build Schema)

ขั้นตอน 3) ป้อนรหัสนี้ในช่องด้านขวา

select * from users;

ขั้นตอน 4) คลิก "เรียกใช้ SQL" คุณจะเห็นผลลัพธ์ดังต่อไปนี้

SQL Fiddle ผลลัพธ์ที่แสดงบันทึกผู้ใช้รายเดียวที่ส่งคืน

สมมติว่าผู้ใช้ป้อน admin@admin.sys และรหัสผ่านเป็น 1234 คำสั่งที่ดำเนินการกับฐานข้อมูลจะเป็นดังนี้:

SELECT * FROM users WHERE email = 'admin@admin.sys' AND password = md5('1234');

โค้ดข้างต้นสามารถถูกโจมตีได้โดยการคอมเมนต์ส่วนของรหัสผ่านออก และเพิ่มเงื่อนไขที่จะเป็นจริงเสมอเข้าไป สมมติว่าผู้โจมตีป้อนข้อมูลต่อไปนี้ในช่องที่อยู่อีเมล

xxx@xxx.xxx' OR 1 = 1 LIMIT 1 -- ' ]

xxx สำหรับรหัสผ่าน

คำสั่งไดนามิกที่สร้างขึ้นจะเป็นดังนี้

SELECT * FROM users WHERE email = 'xxx@xxx.xxx' OR 1 = 1 LIMIT 1 -- ' ] AND password = md5('1234');

ที่นี่

  • xxx@xxx.xxx ปิดท้ายด้วยเครื่องหมายอัญประกาศเดี่ยวซึ่งทำให้ข้อความสมบูรณ์
  • OR 1 = 1 LIMIT 1 คือเงื่อนไขที่จะเป็นจริงเสมอ และจำกัดผลลัพธ์ที่ส่งคืนให้เหลือเพียงระเบียนเดียวเท่านั้น
  • — ' AND … เป็นความคิดเห็น SQL ที่จะกำจัดส่วนของรหัสผ่าน

คัดลอกคำสั่ง SQL ด้านบนแล้ววางลงในช่อง SQL Fiddle เรียกใช้คำสั่ง SQL ในช่องข้อความตามที่แสดงด้านล่าง

SQL Fiddle ส่งคืนค่าบันทึกหลังจากเงื่อนไขที่ฉีดเข้าไปทำงานเสร็จสิ้น

กิจกรรมการแฮ็ก: SQL Inject เว็บแอปพลิเคชัน

เรามีเว็บแอปพลิเคชั่นง่ายๆที่ http://www.techpanda.org/ โค้ดนี้มีความเสี่ยงต่อการโจมตีแบบ SQL Injection ใช้เพื่อเป็นตัวอย่างเท่านั้น โค้ดแบบฟอร์ม HTML ด้านบนนำมาจากหน้าล็อกอิน แอปพลิเคชันมีระบบรักษาความปลอดภัยขั้นพื้นฐาน เช่น การตรวจสอบความถูกต้องของช่องอีเมล ซึ่งหมายความว่าโค้ดข้างต้นของเราไม่สามารถนำไปใช้เพื่อหลีกเลี่ยงการล็อกอินได้

เพื่อหลีกเลี่ยงปัญหานั้น เราจึงใช้วิธีเจาะช่องรหัสผ่านแทน แผนภาพด้านล่างแสดงขั้นตอนที่ต้องปฏิบัติตาม

แผนภาพแสดงขั้นตอนการแทรกข้อมูลในช่องรหัสผ่านของแบบฟอร์มล็อกอิน

สมมติว่าผู้โจมตีป้อนข้อมูลดังต่อไปนี้

  • ขั้นตอนที่ 1: ป้อน xxx@xxx.xxx เป็นที่อยู่อีเมล
  • ขั้นตอนที่ 2: ป้อน xxx') หรือ 1 = 1 — ]

แบบฟอร์มล็อกอินพร้อมสตริงที่ใช้ในการแทรกโค้ดที่ป้อนในช่องรหัสผ่าน

  • คลิกที่ปุ่มส่ง
  • คุณจะถูกนำไปยังหน้าแดชบอร์ด

คำสั่ง SQL ที่สร้างขึ้นจะมีลักษณะดังต่อไปนี้

SELECT * FROM users WHERE email = 'xxx@xxx.xxx' AND password = md5('xxx') OR 1 = 1 -- ]');

แผนภาพด้านล่างแสดงให้เห็นถึงวิธีการสร้างข้อความดังกล่าว

อธิบายขั้นตอนการสร้างคำสั่ง SQL ที่ถูกแทรกเข้าไป

ที่นี่

  • ข้อความดังกล่าวตั้งสมมติฐานอย่างชาญฉลาดว่ามีการใช้การเข้ารหัส MD5
  • เติมเครื่องหมายอัญประกาศเดี่ยวและวงเล็บปิดให้สมบูรณ์
  • เพิ่มเงื่อนไขให้กับข้อความซึ่งจะเป็นจริงเสมอ

โดยทั่วไป การโจมตีที่ประสบความสำเร็จจะใช้เทคนิคหลายอย่างร่วมกัน ดังที่แสดงไว้ข้างต้น

ประเภทการโจมตีแบบฉีด SQL อื่นๆ

การโจมตีแบบ SQL Injection สามารถสร้างความเสียหายได้มากกว่าแค่การหลีกเลี่ยงอัลกอริทึมการล็อกอิน การโจมตีบางประเภทได้แก่:

  • กำลังลบข้อมูล
  • กำลังอัปเดตข้อมูล
  • การแทรกข้อมูล
  • การดำเนินการคำสั่งบนเซิร์ฟเวอร์ที่สามารถดาวน์โหลดและติดตั้งโปรแกรมที่เป็นอันตราย เช่น โทรจัน
  • การส่งออกข้อมูลที่มีค่าเช่นรายละเอียดบัตรเครดิต อีเมล และรหัสผ่านไปยังเซิร์ฟเวอร์ระยะไกลของผู้โจมตี
  • การรับรายละเอียดการเข้าสู่ระบบของผู้ใช้ เป็นต้น
  • การฉีด SQL ตามคุกกี้
  • การฉีด SQL ตามข้อผิดพลาด
  • การฉีด SQL แบบตาบอด

รายการข้างต้นไม่ใช่รายการที่ครบถ้วนสมบูรณ์ แต่เป็นเพียงตัวอย่างให้เห็นว่าการโจมตีแบบ SQL Injection สามารถทำอะไรได้บ้าง

เครื่องมืออัตโนมัติสำหรับการฉีด SQL

ในตัวอย่างข้างต้น เราใช้เทคนิคการโจมตีด้วยตนเองโดยอาศัยความรู้ด้าน SQL ที่เรามีมากมาย อย่างไรก็ตาม มีเครื่องมืออัตโนมัติที่สามารถช่วยให้คุณทำการโจมตีได้อย่างมีประสิทธิภาพมากขึ้นและใช้เวลาน้อยลง เครื่องมือเหล่านั้นได้แก่:

วิธีป้องกันการโจมตีแบบ SQL Injection

องค์กรสามารถใช้หลักการต่อไปนี้เพื่อป้องกันตัวเองจากการโจมตี SQL Injection

  • ไม่ควรเชื่อถือข้อมูลที่ผู้ใช้ป้อนเข้ามา – ต้องทำการตรวจสอบและกรองข้อมูลก่อนนำไปใช้ในคำสั่ง SQL แบบไดนามิกเสมอ
  • ขั้นตอนการจัดเก็บ – สิ่งเหล่านี้สามารถห่อหุ้มคำสั่ง SQL และถือว่าข้อมูลนำเข้าทั้งหมดเป็นพารามิเตอร์ได้
  • งบที่เตรียมไว้ – คำสั่งเตรียมการ (prepared statements) ทำงานโดยการสร้างคำสั่ง SQL ก่อน จากนั้นจึงนำข้อมูลที่ผู้ใช้ส่งเข้ามาทั้งหมดมาใช้เป็นพารามิเตอร์ ซึ่งไม่มีผลต่อไวยากรณ์ของคำสั่ง SQL
  • นิพจน์ปกติ – สามารถใช้สิ่งเหล่านี้ในการตรวจจับโค้ดที่อาจเป็นอันตรายและลบออกก่อนที่จะดำเนินการคำสั่ง SQL
  • สิทธิ์การเข้าถึงของผู้ใช้ในการเชื่อมต่อฐานข้อมูล – ควรให้สิทธิ์การเข้าถึงเฉพาะที่จำเป็นแก่บัญชีที่ใช้เพื่อ เชื่อมต่อกับฐานข้อมูล- ซึ่งสามารถช่วยลดสิ่งที่คำสั่ง SQL สามารถดำเนินการบนเซิร์ฟเวอร์ได้
  • ข้อความแสดงข้อผิดพลาด – ข้อความเหล่านี้ไม่ควรเปิดเผยข้อมูลที่ละเอียดอ่อนหรือตำแหน่งที่เกิดข้อผิดพลาดอย่างแน่ชัด สามารถใช้ข้อความแสดงข้อผิดพลาดแบบกำหนดเองง่ายๆ เช่น “ขออภัย ขณะนี้เรากำลังประสบปัญหาทางเทคนิค เราได้ติดต่อทีมงานด้านเทคนิคแล้ว โปรดลองอีกครั้งในภายหลัง” แทนการแสดงคำสั่ง SQL ที่ทำให้เกิดข้อผิดพลาดได้

กิจกรรมการแฮ็ก: ใช้ Havij สำหรับ SQL Injection

ในสถานการณ์จำลองนี้ เราใช้โปรแกรม Havij Advanced SQL Injection เพื่อสแกนเว็บไซต์หาช่องโหว่

หมายเหตุ: Havij เป็นอาคารเก่าที่ไม่ได้มีการบำรุงรักษา Windows เครื่องมือ SQLMap ที่กล่าวถึงข้างต้น เป็นมาตรฐานโอเพนซอร์สในปัจจุบัน

หมายเหตุ: โปรแกรมป้องกันไวรัสของคุณอาจตรวจพบไฟล์นี้เนื่องจากลักษณะของไฟล์ คุณควรเพิ่มไฟล์นี้ลงในรายการยกเว้นหรือหยุดการทำงานชั่วคราว โปรแกรมป้องกันไวรัส.

ภาพด้านล่างแสดงหน้าต่างหลักของ Havij

หน้าต่างหลักของเครื่องมือ Havij สำหรับการโจมตีแบบ SQL injection

เครื่องมือข้างต้นสามารถใช้ประเมินความเสี่ยงด้านความปลอดภัยของเว็บไซต์หรือแอปพลิเคชันได้

คำถามที่พบบ่อย

ต้องได้รับอนุญาตเป็นลายลักษณ์อักษรจากเจ้าของเว็บไซต์ก่อน การทดสอบแอปพลิเคชันที่คุณไม่ได้เป็นเจ้าของนั้นผิดกฎหมาย เช่น กฎหมายว่าด้วยการฉ้อโกงและการใช้คอมพิวเตอร์ในทางที่ผิดของสหรัฐอเมริกา ขอบเขตของโครงการล่ารางวัลสำหรับการค้นหาช่องโหว่ (Bug-bounty scopes) จะกำหนดสิ่งที่ได้รับอนุญาต

ใช่แล้ว ใน OWASP Top 10:2025 การโจมตีแบบ Injection อยู่ในอันดับที่ A05 และการทดสอบยังคงพบช่องโหว่ Injection ในเกือบทุกแอปพลิเคชัน ด้วยจำนวน CVE การโจมตีแบบ SQL Injection ใหม่ๆ นับพันรายการต่อปี การโจมตีแบบ Injection จึงยังคงเป็นความเสี่ยงสำคัญบนเว็บอยู่

MD5 เป็นฟังก์ชันแฮชที่รวดเร็ว ไม่ใช่การเข้ารหัส และผู้โจมตีสามารถถอดรหัสได้อย่างรวดเร็วด้วยตารางเรนโบว์และ GPU ควรใช้อัลกอริทึมที่ช้ากว่าและมีการเพิ่มเกลือ (salted algorithm) เช่น bcrypt หรือ Argon2 สำหรับรหัสผ่านแทน

ฐานข้อมูลใดๆ ที่ถูกสืบค้นผ่าน SQL ที่สร้างขึ้นแบบไดนามิก — MySQL, PostgreSQL, Microsoft SQL Server, Oracleและ SQLiteข้อบกพร่องไม่ได้อยู่ที่กลไกของฐานข้อมูล แต่อยู่ที่วิธีการที่แอปพลิเคชันนำข้อมูลที่ผู้ใช้ป้อนเข้ามาไปรวมเข้ากับคำสั่งค้นหา

ไฟร์วอลล์และเครื่องสแกนที่ขับเคลื่อนด้วย AI เรียนรู้รูปแบบการรับส่งข้อมูลปกติ จากนั้นจะตรวจจับข้อมูลที่ผิดปกติ เช่น เงื่อนไขหรือความคิดเห็นที่ถูกแทรกเข้ามาแบบเรียลไทม์ โมเดลการเรียนรู้ของเครื่องสามารถตรวจจับข้อมูลที่ถูกปกปิดซึ่งลายเซ็นแบบตายตัวตรวจไม่พบ

ผู้ช่วย AI เช่น นักบิน GitHub สามารถแนะนำการสืบค้นแบบพารามิเตอร์และการตรวจสอบความถูกต้องของข้อมูลนำเข้าได้ แต่ก็ยังสร้างรูปแบบที่ไม่ปลอดภัยซ้ำอีกด้วย ควรพิจารณาข้อเสนอแนะแต่ละข้อเป็นร่าง และตรวจสอบความถูกต้องด้วยเครื่องมือตรวจสอบความปลอดภัยก่อน

การโจมตีแบบ SQL injection มุ่งเป้าไปที่ฐานข้อมูลโดยการแทรกคำสั่ง SQL เข้าไปในคำสั่งค้นหาฝั่งเซิร์ฟเวอร์ ส่วนการโจมตีแบบ Cross-site scripting มุ่งเป้าไปที่ผู้ใช้รายอื่นโดยการแทรกสคริปต์ที่ทำงานในเบราว์เซอร์ของพวกเขา การโจมตีแบบ SQL injection ทำให้ข้อมูลรั่วไหล ส่วนการโจมตีแบบ Cross-site scripting ขโมยเซสชันของผู้ใช้

ORM (object-relational mapper) สร้างคำสั่ง SQL จากอ็อบเจ็กต์โค้ดโดยใช้การกำหนดพารามิเตอร์เป็นค่าเริ่มต้น ซึ่งช่วยป้องกันการโจมตีแบบ SQL injection ได้เป็นส่วนใหญ่ อย่างไรก็ตาม มันก็ไม่ได้ป้องกันได้ 100% คำสั่ง SQL ดิบและเมธอดที่ไม่ปลอดภัยยังคงทำให้เกิดช่องโหว่ ดังนั้นการตรวจสอบความถูกต้องจึงยังคงมีความสำคัญ

สรุปโพสต์นี้ด้วย: