ตัวอย่างการโจมตี
จากนี้ไปจะแสดงให้ดูว่าแฮ็กเกอร์สามารถหารหัสผ่านจากระบบที่เก็บรหัสผ่านในแบบ plaintext ได้ง่ายขนาดไหน อย่างที่บอกไว้ตั้งแต่แรกว่าการเก็บรหัสผ่านในแบบ plaintext ไม่ว่าจะเก็บไว้ที่ไหนก็ไม่ปลอดภัยทั้งนั้น แม้รหัสผ่านจะถูกเขียนฝังไว้ในตัวโปรแกรมก็ตาม แฮ็กเกอร์ก็สามารถหาวิธีเข้าไปดูได้อยู่ดี จากนี้ไปจะแสดงวิธีการงัดแงะข้อมูลในรูป plaintext ที่ฝังอยู่ในโปรแกรมที่เขียนด้วยเทคโนโลยี .NET ออกมาแต่ก่อนจะไปดูวิธีการโจมตี ขอให้ท่านผู้อ่านทำความเข้าในเกี่ยวกับ CLR’s Execution Model ก่อน
โปรแกรมที่เขียนด้วยเทคโนโลยี .NET ไม่ว่าจะใช้ภาษา C++, C# หรือ VB.NET สิ่งที่ได้หลังจากการคอมไพล์เบื้องต้นจะอยู่ในรูปของ Microsoft Intermediate Language (MSIL) ซึ่ง MSIL นี้ยังไม่สามารถทำงานได้ แต่เมื่อเรียกโปรแกรมเหล่านี้ขึ้นมาทำงาน MSIL จะถูกคอมไพล์อีกครั้งขณะทำงาน (หรือที่เรียกว่า Just-in-time Compilation) ให้กลายเป็นภาษาเครื่องที่สามารถทำงานได้จริงๆ โดยสิ่งที่ทำหน้าที่ในการแปล MSIL ให้เป็นภาษาเครื่องคือ Common Language Runtime (CLR) ซึ่งเป็นส่วนประกอบหนึ่งใน Microsoft’s .NET framework
ในขั้นตอนการคอมไพล์ภาษาระดับสูง คอมไพเลอร์จะรวม metadata เข้ากับ MSIL ให้กลายเป็น Portable Executable file (PE file) ซึ่ง metadata นี้จะรวมข้อมูลต่างๆ เช่นโครงสร้างข้อมูล คลาส ฟิลด์ เป็นต้น และ MSIL ยังมีรายละเอียดเกี่ยวกับขั้นตอนการทำงานของโปรแกรม ดังนั้นแฮ็กเกอร์จึงมักใช้ PE file เป็นแหล่งสำหรับหาข้อมูลเบื้องต้นของเป้าหมายเสมอ
เพื่อแสดงให้ดูว่าการเก็บรหัสผ่านในรูปของ plaintext เสี่ยงต่อการถูกขโมยข้อมูลอย่างไร ขอให้ลองพิจารณาจากตัวอย่างต่อไปนี้ สมมติว่าเราเขียนโปรแกรมสำหรับตรวจสอบการเข้าสู่ระบบด้วยภาษา C# โดยใช้ Windows Form ลักษณะดังรูป
ในโปรแกรมจะมีคลาส ConstantString เพื่อใช้ในการเก็บรหัสผ่านเข้าสู่ระบบเอาไว้ดังตัวอย่างโค้ดต่อไปนี้
Username และ Password ที่ถูกกรอกจากหน้าจอเข้าสู่ระบบจะถูกตรวจสอบเมื่อกดปุ่ม Submit ถ้าข้อมูลที่กรอกเข้ามาตรงกับที่ประกาศไว้ในคลาส ConstantString จะแสดงข้อความว่า Login Successful แต่ถ้ากรอกข้อมูลผิดจะขึ้นข้อความว่า Login Fail โค้ดสำหรับตรวจสอบ Username และ Password มีดังต่อไปนี้
หลังจากเราคอมไพล์โปรแกรมแล้วจะได้เป็นไฟล์ .exe เพื่อเอาไปทำงาน จากนี้เราจะงัดแงะเอา Username และ Password ที่อยู่ในไฟล์ .exe ออกมา เครื่องมือที่จะใช้เพื่อการนี้คือ Intermediate Language Disassembler (ILDASM)
ILDASM จะถูกติดตั้งพร้อมกับ Visual Studio สามารถทำงานผ่านหน้าจอ GUI หรือ ทำงานผ่านหน้าจอคอนโซลก็ได้ ในกรณีนี้เราจะทำงานโดยผ่านหน้าจอคอนโซล วิธีเรียก ILDASM ขึ้นมาทำงานมีขั้นตอนคือ คลิกปุ่ม Start -> All Programs -> Visual Studio -> Visual Studio Tools -> Visual Studio Command Prompt
คำสั่งสำหรับใช้งาน ILDASM จะมีลักษณะดังนี้
ildasm [options] [PEfilename] [options] |
รายละเอียดของคำสั่งสำหรับใช้งานโป รแกรม ILDASM สามารถหาอ่านได้จากเว็บ https://msdn.microsoft.com/en-us/library/f7dy01k1.aspx ในการโจมตีโปรแกรมเป้าหมายของเรา จะใช้คำสั่งดังต่อไปนี้
ildasm /text LoginForm.exe | findstr ldstr |
ตัวเลือก /text คือการสั่งให้แสดงผลการทำงานในหน้าจอคอนโซล และจากนั้นให้ส่งผลลัพธ์ไปยังคำสั่ง findstr เพื่อให้หาสายอักขระ ldstr โดย ldstr คือคำสั่งใน MSIL ใช้ในการโหลดสายอักขระเข้าสู่หน่วยความจำสแต็ก หลังจาก ildasm ทำงานจะได้ผลลัพธ์ดังรูปต่อไปนี้
จะเห็นว่าคำสั่ง ldstr ทั้งหมดจะถูกแสดงออกมา รวมทั้ง Username และ Password (ในบรรทัด IL_0000 และ IL_000a) ที่เก็บไว้ในคลาส ConstantString ด้วย
ผู้พัฒนาโปรแกรมอาจป้องกันโปรแกรมของตัวเองด้วยการใช้ Obfuscation tool เครื่องมือดังกล่าวจะเข้ารหัสข้อมูลสายอักขระ รวมถึงเปลี่ยนโค้ดให้ไม่สามารถอ่านได้ แต่วิธีนี้ก็ไม่สามารถป้องกันช่องโหว่ได้ทั้งหมด
โดยสรุป การเก็บรหัสผ่านของผู้ใช้ให้ปลอดภัยมีหลักดังนี้
- เมื่อระบบต้องการให้มีการกู้รหัสเมื่อผู้ใช้ลืมรหัส → ใช้วิธีเข้ารหัสก่อนเก็บลงฐานข้อมูล
- เมื่อต้องการความปลอดภัยมากๆ และระบบไม่ต้องการให้กู้รหัส → ใช้วิธีเก็บค่าแฮชของรหัสผ่าน
- ทั้งการเข้ารหัสและการเก็บค่าแฮชให้ใช้ควบคู่กับ SALT
เป็นอย่างไรบ้างครับ หวังว่าบทความนี้คงช่วยให้ท่านผู้อ่านได้รู้พื้นฐานของการรักษาข้อมูลส่วนตัวของผู้ใช้งานระบบได้ไม่มากก็น้อย สวัสดีครับ