สืบเนื่องจาก น้องเปลี่ยน password MSN messenger แล้วดันลืม password แต่ยังโชคดีที่ ตั้ง Messenger ให้ save password เอาไว้ (โชคไม่ดีมากกว่า ถ้าไม่ตั้งให้ remember password มันก็คงไม่ลืมหรอก) ก็เลยเดือดร้อน ต้องไปหาวิธีดู password
เข้าไป search ใน google ก็เจอเลย http://www.msn-password-recovery.com/ พอ download มาลงก็พบว่าจะต้องจ่ายตังถึงจะใช้งานได้ ก็พยายามหา crack ก็เจอเฉพาะ version เก่าๆ ซึ่งมันจะ support MSN version 7.5 แต่ MSN ที่ใช้อยู่มันเป็น version 8 อ่ะดิ ซึ่งวิธีที่มันเก็บ password ดันไม่เหมือน version 7 ซะอีก
ลองหาอยู่นาน ก็คาดว่ามีแต่ไอ้โปรแกรมนี้นี่แหละที่จะดู password ได้ ตอนแรกลองไปแกะ code ตรงส่วนลงทะเบียน ปรากฎว่าซับซ้อนเกินไป ไม่ไหว สุดท้ายก็มาเจอจุดที่ง่ายจนได้ ซึ่งก็คือส่วนที่มันแสดงผลนั่นเอง
ใน version ที่ยังไม่ได้ลงทะเบียน เมื่อเรากดปุ่ม recovery password มันจะรายงานว่า account ของเรา มีอะไรบ้าง แต่ละอันมี password ยาวเท่าไหร่ (แต่มันจะไม่แสดง password ให้ดูแค่นับจำนวนอักษรใน password)
ขอยกส่วนสำคัญขึ้นมาเลยละกัน ในส่วนนี้จะเป็นการแสดง account ของ MSN version 8 (เอา code มาจาก IDA Pro)
00401C01 push offset aPasswordContai ; "Password contains " 00401C06 mov ecx, ebx 00401C08 call sub_40BCAC ; เรียก sub สำหรับแสดงตัวหนังสือ 00401C0D lea eax, [esp+280h+String] 00401C11 push 0Ah ; int 00401C13 push eax ; char * 00401C14 lea edi, [esp+288h+String1] ; Password นอนรออยู่ในนี้แล้ว 00401C1B or ecx, 0FFFFFFFFh 00401C1E xor eax, eax 00401C20 repne scasb ; เอามานับว่ายาวเท่าไหร่ 00401C22 not ecx 00401C24 dec ecx 00401C25 push ecx ; int 00401C26 call __itoa ; นับเสร็จก็แปลงเป็น string ซะ 00401C2B add esp, 0Ch 00401C2E lea ecx, [esp+280h+String] 00401C32 push ecx ; lpString 00401C33 mov ecx, ebx 00401C35 call sub_40BCAC ; เรียก sub สำหรับแสดงตัวหนังสือ ซึ่งเป็นจำนวนตัวอักษรที่ได้จาก itoa
ทีนี้มาดูว่าจะทำอะไรได้บ้าง สิ่งแรกที่คิดได้คือ ควรเอา password มาแสดงผลแทนที่จะเอา จำนวนอักษรมาแสดงผล ซึ่ง ก็คือคำสั่ง
lea ecx, [esp+280h+String]
ซึ่งกินพื้นที่ 4 byte แต่คำสั่งสำหรับ load address นั้นต้องการพื้นที่มากกว่า 4 byte (เพราะ offset ของ memory ที่เก็บค่า password ตอนนี้มันอยู่ห่างจาก esp เหลือเกิน)
ย้อนกลับไปดู code อีกที เรารู้ว่า password ถูก load เข้า edi เพื่อที่จะนับความยาว ดังนั้นเราน่าจะใช้ประโยชน์จาก edi ได้ และความยาว string ที่นับได้จะเก็บอยู่ใน ecx เราจึงเขียน code ใหม่ได้เป็น
sub edi, ecx lea ecx, dword ptr [edi]
ซึ่งเมื่อเอาไปแปลงเป็น asm จะได้ความยาว 4 byte พอดีเลย แต่พอเอาไปลอง ปรากฏว่า หลังจากที่เรียกคำสั่ง itoa มันดันทำให้ค่า edi เปลี่ยนซะนี่ เราก็เปลี่ยนคำสั่ง call __itoa ให้เป็น nop ซะ พอเอาไปลองอีกทีก็พบว่า password มาไม่ครบเนื่องจาก ecx ถูกลดค่าลงไป 1 ตอนนับเสร็จ (เพราะเวลานับจะรวม null terminate string ไปด้วย) เราก็เปลี่ยนคำสั่ง dec ecx ให้เป็น nop สุดท้ายจะได้เป็น
00401C01 push offset aPasswordContai ; "Password contains " 00401C06 mov ecx, ebx 00401C08 call sub_40BCAC 00401C0D lea eax, [esp+280h+var_244] 00401C11 push 0Ah 00401C13 push eax 00401C14 lea edi, [esp+288h+String1] 00401C1B or ecx, 0FFFFFFFFh 00401C1E xor eax, eax 00401C20 repne scasb 00401C22 not ecx 00401C24 nop ; ไม่ต้องลดค่า ecx 00401C25 push ecx 00401C26 nop ; ไม่ต้องเรียก itoa 00401C27 nop 00401C28 nop 00401C29 nop 00401C2A nop 00401C2B add esp, 0Ch 00401C2E sub edi, ecx ; คำนวณหาตำแหน่ง password 00401C30 lea ecx, [edi] ; load address ที่เก็บ password ไปแทน 00401C32 push ecx ; lpString 00401C33 mov ecx, ebx 00401C35 call sub_40BCAC
เทียบ code เมื่อเอามาแปลงเป็นฐาน 16 (เริ่มจาก offset ที่ 1C20h)
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F Before 00001C20 F2 AE F7 D1 49 51 E8 00 90 00 00 83 C4 0C 8D 4C 00001C30 24 3C 51 8B CB E8 72 A0 00 00 68 B0 B1 41 00 8B ----------------------------------------------------------- After 00001C20 F2 AE F7 D1 90 51 90 90 90 90 90 83 C4 0C 2B F9 00001C30 8D 0F 51 8B CB E8 72 A0 00 00 68 B0 B1 41 00 8B
Download โปรแกรม
MSN Password Recovery 1.01.09.06 ต้นฉบับ
MSN Password Recovery 1.01.09.06 crack แล้ว
Link ที่น่าสนใจ
Enumerating Windows credentials with CredEnumerate function (Windows XP/2003 Only)
MSN Messenger Password Decrypter for Windows XP and 2003