ה Crackme הראשון שלי

17/01/2019

לקראת קורס פיתוח מאובטח שאני מעביר בשבוע הבא כתבתי Crackme פשוט כדי לתת לאנשים תחושה של עבודה עם ה Debugger. קראקמיס, לאלה מכם שלא מכירים, אלה תוכניות שאנשים היו מפרסמים פעם כדי שתפרצו אותן, בדרך כלל באמצעות שימוש ב Disassembler או Debugger. את הקראקמי קיבלת בתור קובץ הפעלה ללא הקוד ובגדול מה שהתוכניות האלה עשו זה לבקש סיסמא ואם הסיסמא שהכנסתם מתאימה לתנאי התוכנית תקבלו על המסך הודעת ניצחון.

המטרה שלכם היתה לזהות את הלוגיקה של התוכנית רק מצפיה בקוד ה Assembly שלה וכך לדעת איזה סיסמא להכניס. בחלק מהמקומות גם היה מותר לשנות את ה Executable עצמו כדי לקבל את הודעת ההדפסה המתאימה. ככל שהשלבים מתקדמים הלוגיקה היתה מסתבכת והיה יותר קשה להוציא את ה Assembly Code מהתוכנית עצמה בגלל כל מיני מנגנוני הגנה שהיו שותלים שם.

מאחר ויש עוד כמה ימים עד הקורס חשבתי לשתף את התרגיל גם כאן ולתת לכם לשבור את הראש. כמו תמיד בפוסטים מהסוג הזה מוזמנים בחום לספר בתגובות - מה התוכנית עושה? איזה ערך יגרום לה להדפיס את הודעת ההצלחה? ואיך אפשר לשנות את קובץ ה Executable כדי שהתוכנית תמיד תדפיס את הודעת ההצלחה.

קוד ה Assembly של התוכנית:

a.out[0x100000ed0] <+0>:   pushq  %rbp
a.out[0x100000ed1] <+1>:   movq   %rsp, %rbp
a.out[0x100000ed4] <+4>:   subq   $0x30, %rsp
a.out[0x100000ed8] <+8>:   leaq   0xad(%rip), %rax          ; "What's the password?\n"
a.out[0x100000edf] <+15>:  movl   $0x0, -0x4(%rbp)
a.out[0x100000ee6] <+22>:  movl   %edi, -0x8(%rbp)
a.out[0x100000ee9] <+25>:  movq   %rsi, -0x10(%rbp)
a.out[0x100000eed] <+29>:  movl   $0x0, -0x14(%rbp)
a.out[0x100000ef4] <+36>:  movq   %rax, %rdi
a.out[0x100000ef7] <+39>:  movb   $0x0, %al
a.out[0x100000ef9] <+41>:  callq  0x100000f5c               ; symbol stub for: printf
a.out[0x100000efe] <+46>:  leaq   0x9d(%rip), %rdi          ; "%d"
a.out[0x100000f05] <+53>:  leaq   -0x14(%rbp), %rsi
a.out[0x100000f09] <+57>:  movl   %eax, -0x1c(%rbp)
a.out[0x100000f0c] <+60>:  movb   $0x0, %al
a.out[0x100000f0e] <+62>:  callq  0x100000f62               ; symbol stub for: scanf
a.out[0x100000f13] <+67>:  movl   %eax, -0x18(%rbp)
a.out[0x100000f16] <+70>:  cmpl   $0x1, -0x18(%rbp)
a.out[0x100000f1a] <+74>:  jne    0x100000f52               ; <+130>
a.out[0x100000f20] <+80>:  movl   $0x7, %eax
a.out[0x100000f25] <+85>:  movl   -0x14(%rbp), %ecx
a.out[0x100000f28] <+88>:  movl   %eax, -0x20(%rbp)
a.out[0x100000f2b] <+91>:  movl   %ecx, %eax
a.out[0x100000f2d] <+93>:  cltd   
a.out[0x100000f2e] <+94>:  movl   -0x20(%rbp), %ecx
a.out[0x100000f31] <+97>:  idivl  %ecx
a.out[0x100000f33] <+99>:  cmpl   $0x0, %edx
a.out[0x100000f36] <+102>: jne    0x100000f4d               ; <+125>
a.out[0x100000f3c] <+108>: leaq   0x62(%rip), %rdi          ; "Correct!\n"
a.out[0x100000f43] <+115>: movb   $0x0, %al
a.out[0x100000f45] <+117>: callq  0x100000f5c               ; symbol stub for: printf
a.out[0x100000f4a] <+122>: movl   %eax, -0x24(%rbp)
a.out[0x100000f4d] <+125>: jmp    0x100000f52               ; <+130>
a.out[0x100000f52] <+130>: movl   -0x4(%rbp), %eax
a.out[0x100000f55] <+133>: addq   $0x30, %rsp
a.out[0x100000f59] <+137>: popq   %rbp
a.out[0x100000f5a] <+138>: retq   

וקובץ ה Executable בגירסת מק זמין להורדה מכאן: https://www.tocode.co.il/system/ex1

וכמובן אם בא לכם לשחק עם קראקמיס יותר מקצועיים יש אוסף נחמד בקישור כאן: https://crackmes.one/lasts