การโจมตีระบบผู้ใช้งาน หรือการแฮ็คผู้ใช้งานอย่างหนึ่งที่นิยมใช้กันมาก ก็คือการสุ่มโจมตีชื่อผู้ใช้และรหัสผ่าน หรือ brute-force attack. วิธีที่ผู้โจมตีใช้งานหลักๆโดยทั่วไปก็คือ ถ้าไม่รู้ชื่อผู้ใช้เลยก็เขียนโปรแกรมเดาสุ่มชื่อผ้ใช้และรหัสผ่าน, ถ้ารู้ชื่อผู้ใช้แล้วก็เขียนโปรแกรมเดาสุ่มรหัสผ่าน. การเดาสุ่มก็ใช้วิธีเดียวกับการสุ่มสร้างอักขระ (random string) โดยอาจเน้นรหัสผ่านที่เดาง่ายและนิยมใช้กันมาก เช่น 12345678, password เป็นต้น.
สำหรับวิธีป้องกันก็ทำได้หลายวิธี เช่น
- การใช้ Captcha ให้กรอกอักษรที่ปรากฏบนภาพ แต่ข้อเสียก็คือสร้างความยุ่งยากให้ผู้ใช้ตัวจริง ยิ่งถ้าตัวอักษรอ่านยากเกินไปก็เดากันไม่ค่อยจะถูก.
- การใช้ป้องกันการสุ่มโจมตีด้วย IP address แต่ข้อเสียก็คือถ้าเครื่องผู้ใช้นั้นกลายเป็นเครื่องซอมบี้ หรือเครื่องอื่นๆในเครือข่ายเดียวกัน เช่นผู้ใช้ 2 คนในร้านเน็ตคาเฟ่ คนหนึ่งกำลังเข้าสู่ระบบอย่างถูกต้อง เป็นผู้ใช้ตัวจริง อีกคนเป็นผู้โจมตีที่กำลังพยายามสุ่มโจมตี การแบนทั้ง IP อาจทำให้ผู้ใช้ตัวจริงในเครือข่ายนั้นใช้งานไม่ได้เลย กลายเป็น DoS attack ไป.
- การใช้ป้องกันการสุ่มโจมตีด้วย Device cookies. วิธีนี้เป็นแนวความคิดที่ดีมาก ไม่ต้องอ่านตัวอักษรที่อ่านยากๆ, ไม่กระทบผู้ใช้ในระดับ IP หรือทั้งเครือข่าย, และไม่รบกวนผู้ใช้ตัวจริงอีกด้วย.
ขั้นตอนการทำงาน
สำหรับขั้นตอนการทำงาน ขออ้างอิงจากในเว็บไซต์ของ OWASP โดยตรง ซึ่งจะพยายามแปลเป็นไทยให้เข้าใจได้มากที่สุด แต่หากอ่านภาษาอังกฤษได้ แนะนำให้เปิดทางต้นฉบับดูจะดีที่สุด.
- T - time period (ระยะเวลา)
- N - max number of authentication attempts allowed during T (จำนวนที่พยายามเข้าสู่ระบบได้มากครั้งที่สุดภายในระยะเวลา T)
- สัญญลักษณ์ ∎ คือสิ้นสุดขั้นตอน.
Entry point for authentication request (จุดเริ่มต้นของการร้องขอตรวจสอบ หรือ login)
- if the incoming request contains a device cookie (ถ้าเครื่องผู้เรียกมี device cookie อยู่แล้ว):
- validate device cookie (ตรวจสอบ device cookie)
- if device cookie is not valid then proceed to step 2. (ถ้า device cookie ไม่ถูกต้องให้ไปขั้นตอน 2.)
- if the device cookie is in the lockout list (ถ้า device cookie อยู่ในรายการติดล็อค)
- reject authentication attempt (ปฏิเสธการตรวจสอบผู้ใช้ หรือ login)∎
- else (ถ้าอื่นๆ)
- authenticate user (ตรวจสอบผู้ใช้ หรือ login)∎
- if authentication from untrusted clients is locked out for the specific user (ถ้าการตรวจสอบจากเครื่องผู้ใช้ที่ไม่น่าเชื่อถือซึ่งถูกล็อคจากผู้ใช้ที่กำหนด)
- reject authentication attempt (ปฏิเสธการตรวจสอบผู้ใช้ หรือ login)∎
- else (ถ้าอื่นๆ)
- authenticate user (ตรวจสอบผู้ใช้ หรือ login)∎
Authenticate user (ตรวจสอบผู้ใช้ หรือ login)
- check user credentials (ตรวจสอบชื่อผู้ใช้และรหัสผ่าน)
- if credentials are valid (ถ้าชื่อผู้ใช้และรหัสผ่านถูกต้อง)
- issue new device cookie to user’s client (เขียน device cookie ให้ผู้ใช้นั้น)
- proceed with authenticated user (ส่งต่อไปยังหน้าเข้าสู่ระบบเรียบร้อยแล้ว)
- else (ถ้าอื่นๆ)
- register failed authentication attempt (ลงทะเบียนว่าล้มเหลวในการเข้าสู่ระบบ)
- finish with failed user’s authentication (เสร็จการเข้าสู่ระบบแบบล้มเหลว)
Register failed authentication attempt (ลงทะเบียนว่าล้มเหลวในการเข้าสู่ระบบ)
- register a failed authentication attempt with following information: { user, time, device cookie (if present) }. (ลงทะเบียนว่าล้มเหลวในการเข้าสู่ระบบ ด้วยข้อมูลเหล่านี้: {ชื่อผู้ใช้, เวลา, device cookie (ถ้ามี)}.)
- depending on whether a valid device cookie is present in the request, count the number of failed authentication attempts within period T either for (ขึ้นอยู่กับ device cookie ที่ถูกต้องมีอยู่หรือไม่, นับจำนวนครั้งที่เข้าสู่ระบบล้มเหลวภายในเวลา T สำหรับ
- all untrusted clients (เครื่องผู้ใช้ที่ไม่น่าเชื่อถือทั้งหมด)
or (หรือ) - a specific device cookie (device cookie ที่กำหนดมาให้)
- all untrusted clients (เครื่องผู้ใช้ที่ไม่น่าเชื่อถือทั้งหมด)
- if number of failed attempts within period T > N (ถ้าจำนวนล้มเหลวภายในเวลา T > N)
- if a valid device cookie is presented (ถ้า device cookie ที่ถูกต้องมีอยู่)
- put the device cookie into the lockout list for device cookies until now+T (เอา device cookie นั้นไปอยู่ในรายการที่ถูกล็อค จนกระทั่งเวลาปัจจุบัน + T)
- else (ถ้าอื่นๆ)
- lockout all authentication attempts for a specific user from all untrusted clients until now+T (ล็อคการเข้าสู่ระบบทั้งหมดสำหรับผู้ใช้ที่กำหนดจากเครื่องผู้ใช้ที่ไม่น่าเชื่อถือทั้งหมด จนกระทั่งเวลาปัจจุบัน + T)
- if a valid device cookie is presented (ถ้า device cookie ที่ถูกต้องมีอยู่)
Issue new device cookie to user’s client (เขียน device cookie ให้ผู้ใช้นั้น)
เขียน device cookie ให้ผู้ใช้นั้นโดยมีรายละเอียดอย่างเช่น LOGIN, NONCE, SIGNATURE รายละเอียดดังนี้
- LOGIN อาจเป็นข้อมูลชื่อผู้ใช้หรือเลขไอดีของผู้ใช้
- NONCE คือตัวเลขหรืออักขระสุ่ม
- SIGNATURE คือลายเซ็นที่เข้ารหัสประกอบด้วย LOGIN, NONCE และ secret key โดยอาจใช้
hash_hmac
- secret key คือกุญแจลับที่ใช้ในการเข้ารหัสและถอดรหัส
validate device cookie (ตรวจสอบ device cookie)
- ตรวจสอบว่ามีรูปแบบถูกต้องตามการเขียนที่อธิบายไว้ด้านบน
- ตรวจสอบ SIGNATURE เท่ากับการเข้ารหัสของ LOGIN, NONCE
- ตรวจสอบว่า LOGIN นั้นมีตัวตนจริงในฐานข้อมูล
Download
ดาวน์โหลดจากโค้ดตัวอย่างที่จะดาวน์โหลด จะมีไฟล์ .sql ซึ่งจะสร้างตารางผู้ใช้ตัวอย่าง และตารางอื่นๆที่จำเป็นรวมทั้งหมด 3 ตาราง.
การติดตั้ง
- แตกไฟล์ทั้งหมดลงใน folder ที่เรียกผ่าน HTTP ได้ เช่น http://localhost.localhost/device-cookies-example
- สร้างฐานข้อมูลเปล่าๆขึ้นมา 1 ฐาน
- import .sql ที่ดาวน์โหลดไป
- แก้ไขข้อมูลฐานข้อมูลต่างๆในไฟล์ config.php ให้ถูกต้อง
การทดสอบ
- เปิดเว็บไปยังหน้าที่ติดตั้งตัวอย่าง โดยเรียกไปยังหน้า form.php
- เปิดเครื่องมือบนเว็บเบราเซอร์เพื่อแสดงคุกกี้ที่จะได้รับ
- กรอกอีเมล admin@localhost และรหัสผ่าน pass โดยให้ทดลองกรอกที่ผิดและถูกเพื่อดูว่าได้ device cookie มาอย่างไรเมื่อผิดและถูก. สามารถลบคุกกี้, ล้างค่าในฐานข้อมูล และทดลองได้เรื่อยๆ โดยอาจทดลองเป็นผู้โจมตีเพื่อดูว่าระบบป้องกันได้อย่างไร
- เรียกใช้หน้า cron.php เพื่อล้างค่าต่างๆเมื่อมันหมดอายุแล้ว
กระบวนการทำงานในการตรวจชื่อผู้ใช้และรหัสผ่านจะอยู่ในไฟล์ login.php และการทำงานของ device cookie ส่วนหนึ่งก็ถูกประยุกต์ใช้ร่วมกันในนั้น.
Source code ชุดนี้ทำแจกฟรีภายใต้การอนุญาตแบบ MIT ซึ่งให้อิสระในการนำไปแก้ไข ดัดแปลง หรือใช้งานได้ทุกจุดประสงค์.