diff --git a/1/he/6.html b/1/he/6.html new file mode 100644 index 0000000..b016a7e --- /dev/null +++ b/1/he/6.html @@ -0,0 +1,263 @@ + +
++ ┐───────────────────────┌ + │ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ + │ █ █ █ █ █ █ │ + │ ▀▀▀▀█ █ █ █ █ │ + │ ▄ █ █ █ █ │ + │ ▄▄▄▄▄ │ + │ █ █ │ + │ █ █ │ + │ █▄▄▄█ │ + │ ▄ ▄ │ + │ █ █ │ + │ █ █ │ + │ █▄▄▄█ │ + │ ▄▄▄▄▄ │ + │ █ │ +דיסאסמבלי-שגוי פולימורפית │ █ │ +~ S01den ┘───█───────────────────└ + +נכתב באהבה ע"י S01den, מהצוות של tmp.out ! +mail: S01den@protonmail.com + +[ תורגם ע"י Lit3r4lly ] + +--- הקדמה --- + +כשכתבתי את [0]Lin32.Bakunin, תהיתי לעצמי איך לעשות את זה יותר מעניין +מסתם וירוס שכתוב ב-MIPS ומדפיס קצת שטויות. אני פשוט רציתי לעצבן רברסרים. +ואז נזכרתי בטכניקת ה-False-Disassembly שמימשתי בחלק מה-crackme's שלי. + +בגלל שפולימורפיזם זה מגניב, רציתי להבין אם זה אפשרי ליצור משהו מעניין בעזרת ערבוב של זה יחד עם +טכניקת ה-False-Disassembly. + +התשובה היא כן, וקראתי לשיטה הזו (אני לא יודע אם זו טכניקה מקורית שלי או לא), שיטת +ה-"דיסאסמבלי-שגוי פולימורפית" או בפשטות "פולימורפיזם מזוייף". + +--- איך False-Disassembly עובד? --- + +הטכניקה הזו היא די פשוטה להבנה ולמימוש, ואני גיליתי עליה במסמך המפורסם של [1]Silvio Cesare על +טכניקות anti-debugging ורברסינג בלינוקס. +פשוט צריך לשים כמה בייטים רנדומליים שבד"כ מייצגים התחלה של הוראה מסויימת (Opcode) לפני קטע הקוד, +כמו בדוגמה הבאה: + ++-------------------- נחתך-כאן -------------------- +hey: hey: + xor %rbx, %rbx .ascii "\x48\x31" + jmp yo ====> xor %rbx, %rbx + jmp yo +---------------------------------------------------++עכשיו, אם נסתכל על שני קטעי הקוד שעברו disassemble, אנחנו נקבל משהו כזה (radare2 מה לעזעזאל?):++-------------------- נחתך-כאן -------------------- +;-- hey: +0x00401002 4831db xor rbx, rbx +0x00401005 eb02 jmp 0x401009 + + || + \/ +;-- hey: +0x00401002 48314831 xor qword [rax + 0x31], rcx +0x00401006 dbeb fucomi st(3) +0x00401008 026631 add ah, byte [rsi + 0x31] + +---------------------------------------------------++מדוע הדיסאסמבלר מתנהג בצורה הזו? + +ובכן, \x48\x31 הם בד"כ ייצוג של ההתחלה של הוראת [2]xor, והבייטים שבאים לאחר מכן מייצגים לרוב את +האוגרים שאיתם האופרציה עובדת. + +אז למעשה הבייטים ה"מאתחלים" הללו שהוספנו נדבקים לבייטים העוקבים, שהם למעשה בעצמם בייטים "מאתחלים", וכך +הדיסאסמבלר מפרש את אותם בייטים מאתחלים באמת, כבייטים המייצגים את הרגיסטרים ובגלל זה מופיע לנו זבל במקום ההוראות הרצויות. + +לכן, כדי שנוכל להריץ קוד שבנוי בצורה שכזו, אנחנו חייבים לקפוץ מעל הבייטים שהוספנו. +זה אמור להיות משהו כזה: +++-------------------- נחתך-כאן -------------------- +_start: +jmp hey+2 + +hey: + .ascii "\x48\x31" + xor %rbx, %rbx + jmp yo +--------------------------------------------------- +++--- הקוד המלא --- + +עכשיו, דמיינו שאתם יכולים רנדומלית לשנות את כל הבייטים הללו שמייצרים את ה-false-disassembly בכל +אופרציה, וכך גם הקוד שעבר disassembly ישתנה גם ולכן הרברסר +שיחקור את הקוד, יחשוב שהוא פולימורפי בזמן שרק מספר בייטים בודדים שונו. + +וכעת, ללא דיחוי נוסף, הקוד המלא. +++----------- נחתך כאן ----------- +# build cmd: as Linux.FakePolymorphism.asm -o fakePoly.o ; ld fakePoly.o -o fakePoly + +# this code is a fake polymorphic example, feel free to try/use/whatever it! +# It grabs itself its code, modify the fake-disassembly bytes and put the result +# on the stack. + +.text + .global _start + +_start: +jmp true_start+2 # jump over the fake-disassembly bytes + +true_start: +.ascii "\x48\x31" # fake-disassembly bytes +xor %rbx, %rbx +jmp get_code+2 # jump over the fake-disassembly bytes + +get_code: + .ascii "\x66\x31" # fake-disassembly bytes + call get_rip + sub $0x10 ,%rax # 0x10 is the number of bytes between _start abd this instruction + movb (%rax,%rbx), %al + movb %al, (%rsp,%rbx) + inc %rbx + cmp $0x54, %rbx # 0x54 is the total size of this code + jne get_code+2 + + # Pseudo RNG thanks to the time stamp counter + rdtsc + xor $0xdead, %rax + mov %ax, 2(%rsp) + xor $0xbeef, %rdx + mov %ax, 9(%rsp) + + mov $60, %rax + mov $0, %rdi + syscall # sys_exit + +get_rip: + mov (%rsp), %rax + ret +----------------------------++--- סיכום --- + +אני מקווה שנהנתם מהמאמר הזה ושתנסו לממש את הטכניקה הזו בוירוסים והcrackme's שלכם! + +ביחד עם sblip, כתבנו וירוס פולימורפי (Lin64.Eng3ls, תעיפו מבט על המאמר והקוד !) שמשתמש בטכניקה +הזו בשביל לערפל את הקוד של המפענח של עצמו. + +הקוד של המפענח: +++------- נחתך-כאן ------- + pop rcx + jmp jmp_over+2 + jmp_over: + db `\x48\x31` ; false disassembly + mov al,0x00 + xor rdx, rdx + + decoder: + jmp jmp_over2+2 + + jmp_over2: + db `\xb8\xd9` ; false disassembly + mov dl, byte [r12+rdi] + cmp rdi, STUB_SIZE-1 + jna no_decrypt + + jmp jmp_over3+2 + jmp_over3: + db `\x48\x81` ; false disassembly + xor dl, al + + no_decrypt: + mov byte [rbx+rdi], dl + inc rdi + loop decoder +-------------------------++והנה מספר מפענחים שהבאתי מבינארים זדוניים שונים שעברו [3]disassemble, בוא נראה את הטריק בפעולה:++1. + 0x0c003f46 59 pop rcx + 0x0c003f47 eb02 jmp 0xc003f4b + 0x0c003f49 00d6 add dh, dl + 0x0c003f4b b06d mov al, 0x6d + 0x0c003f4d 4831d2 xor rdx, rdx + 0x0c003f50 eb02 jmp 0xc003f54 + 0x0c003f52 1aca sbb cl, dl + 0x0c003f54 418a143c mov dl, byte [r12 + rdi] + 0x0c003f58 4881ff870000. cmp rdi, 0x87 + 0x0c003f5f 7606 jbe 0xc003f67 + 0x0c003f61 eb02 jmp 0xc003f65 + 0x0c003f63 c0d630 rcl dh, 0x30 + 0x0c003f66 c28814 ret 0x1488 + 0x0c003f69 3b48ff cmp ecx, dword [rax - 1] + 0x0c003f6c c7 invalid + 0x0c003f6d e2e1 loop 0xc003f50 + +2. + 0x0c003fe6 59 pop rcx + 0x0c003fe7 eb02 jmp 0xc003feb + 0x0c003fe9 ce invalid + 0x0c003fea 0ab0a34831d2 or dh, byte [rax - 0x2dceb75d] + 0x0c003ff0 eb02 jmp 0xc003ff4 + 0x0c003ff2 39cb cmp ebx, ecx + 0x0c003ff4 418a143c mov dl, byte [r12 + rdi] + 0x0c003ff8 4881ff870000. cmp rdi, 0x87 + 0x0c003fff 7606 jbe 0xc004007 + 0x0c004003 0e invalid + 0x0c004004 0a30 or dh, byte [rax] + 0x0c004006 c28814 ret 0x1488 + 0x0c004009 3b48ff cmp ecx, dword [rax - 1] + 0x0c00400c c7 invalid + 0x0c00400d e2e1 loop 0xc003ff0++התוצאות שונות מאוד מהקוד המקורי. + +--- הערות ורפרנסים ---++[0] https://vx-underground.org/papers/VXUG + /Exclusive/Bakounin/Writing_virus_in_MIPS_assembly_for_fun.txt +[1] http://www.ouah.org/linux-anti-debugging.txt // Silvio המסמך של +[2] https://www.felixcloutier.com/x86/xor +[3] radare2 עם ++