|
Постоянный
Регистрация: 20.08.2006
Сообщений: 327
С нами:
10381346
Репутация:
1077
|
|
CrackMe #3 by anorganix
CrackMe: CrackMe #3 by anorganix
Цель: найти верный пароль
Сложность: средне
link: http://arteam.accessroot.com/releases/ (Crackmes 1 To 8 By Anorganix)
Решение:
Грузим прогу в Olly!
Код:
100A45BC > 9C PUSHFD
100A45BD 60 PUSHAD
100A45BE E8 00000000 CALL CrackMe3.100A45C3
100A45C3 5D POP EBP
Это даёт нам понять, что прога чем то запакованна. F8 и ставим бряк на esp (в command bar ввести hr esp). F9 и брякаемся тут:
Код:
100A482D 9D POPFD
100A482E -E9 15F3FAFF JMP CrackMe3.10053B48
Удаляем бряк (в command bar ввести hd esp-4). F8 и мы на oep! Мдя o e p....
Код:
10053B48 55 DB 55 ; CHAR 'U'
10053B49 8B DB 8B
10053B4A EC DB EC
10053B4B 83 DB 83
10053B4C C4 DB C4
10053B4D F0 DB F0
10053B4E B8 DB B8
10053B4F 60390510 DD CrackMe3.10053960
10053B53 E8 DB E8
10053B54 6C DB 6C ; CHAR 'l'
10053B55 22 DB 22 ; CHAR '"'
10053B56 FB DB FB
10053B57 FF DB FF
10053B58 E8 DB E8
Меня утешило то, что я знал: 55h - "push ebp", 8BECh - "mov ebp,esp" и тп. А следовательно можно попытаться объяснить это Olly, разуж Ctrl-A не всилах нам помочь.
F10 > Analysis > During next analysis ... > command. После третьей команды я опять попробовал нажать Ctrl-A и, о чудо, Olly всё проанализировала как надо!!
Код:
10053B48 . 55 PUSH EBP
10053B49 . 8BEC MOV EBP,ESP
10053B4B . 83C4 F0 ADD ESP,-10
10053B4E . B8 60390510 MOV EAX,CrackMe3.10053960
10053B53 . E8 6C22FBFF CALL CrackMe3.10005DC4
10053B58 . E8 73FDFFFF CALL CrackMe3.100538D0
10053B5D . 84C0 TEST AL,AL
10053B5F . 75 09 JNZ SHORT CrackMe3.10053B6A
10053B61 . E8 8EFDFFFF CALL CrackMe3.100538F4
10053B66 . 84C0 TEST AL,AL
10053B68 . 74 05 JE SHORT CrackMe3.10053B6F
10053B6A > E8 3903FBFF CALL CrackMe3.10003EA8
10053B6F > A1 3C500510 MOV EAX,DWORD PTR DS:[1005503C]
10053B74 . 8B00 MOV EAX,DWORD PTR DS:[EAX]
10053B76 . E8 D5D9FFFF CALL CrackMe3.10051550
10053B7B . A1 3C500510 MOV EAX,DWORD PTR DS:[1005503C]
10053B80 . 8B00 MOV EAX,DWORD PTR DS:[EAX]
10053B82 . BA C03B0510 MOV EDX,CrackMe3.10053BC0 ; ASCII "CrackMe #3"
10053B87 . E8 D4D5FFFF CALL CrackMe3.10051160
10053B8C . 8B0D 684F0510 MOV ECX,DWORD PTR DS:[10054F68] ; CrackMe3.10056C00
10053B92 . A1 3C500510 MOV EAX,DWORD PTR DS:[1005503C]
10053B97 . 8B00 MOV EAX,DWORD PTR DS:[EAX]
10053B99 . 8B15 C4320510 MOV EDX,DWORD PTR DS:[100532C4] ; CrackMe3.10053310
10053B9F . E8 C4D9FFFF CALL CrackMe3.10051568
10053BA4 . A1 3C500510 MOV EAX,DWORD PTR DS:[1005503C]
Я начал трейсить!! И после
Код:
10053B6A > E8 3903FBFF CALL CrackMe3.10003EA8
Прога вылетела! Пришлось проходить всё заново! Беглый анализ функции дал понять, что она проверяла под отладчиком мы или нет! Не долго думая, я решил обойти злощастную функцию! Дойдя до неё, я поменял eip (с помощью New origin here). F9 и прога запустилась и вылетела. Что удивило вылетела в отладчике и норамльно функционировала со мной! Единственное что пришло в голову, так это - пред тем как прога убивает себя она создаёт новый процесс! А с помощь чего можно создать процес? Правильно CreateProcessA! Поищем эту апи. И вот код:
Код:
10053657 |. 6A 04 PUSH 4
10053659 |. 6A 00 PUSH 0
1005365B |. 6A 00 PUSH 0
1005365D |. 6A 00 PUSH 0
1005365F |. 8D95 C0FEFFFF LEA EDX,DWORD PTR SS:[EBP-140]
10053665 |. 33C0 XOR EAX,EAX
10053667 |. E8 78F3FAFF CALL crackme3.100029E4
1005366C |. 8B85 C0FEFFFF MOV EAX,DWORD PTR SS:[EBP-140]
10053672 |. E8 E10DFBFF CALL crackme3.10004458
10053677 |. 50 PUSH EAX ; |CommandLine
10053678 |. 6A 00 PUSH 0 ; |ModuleFileName = NULL
1005367A |. E8 3D29FBFF CALL <JMP.&kernel32.CreateProcessA> ; \CreateProcessA
1005367F |. C785 18FFFFFF >MOV DWORD PTR SS:[EBP-E8],10007
10053689 |. 8D85 18FFFFFF LEA EAX,DWORD PTR SS:[EBP-E8]
1005368F |. 50 PUSH EAX ; /pContext
10053690 |. 8B85 0CFFFFFF MOV EAX,DWORD PTR SS:[EBP-F4] ; |
10053696 |. 50 PUSH EAX ; |hThread
10053697 |. E8 F029FBFF CALL <JMP.&kernel32.GetThreadContext> ; \GetThreadContext
1005369C |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
1005369F |. 50 PUSH EAX ; /pBytesRead
100536A0 |. 6A 04 PUSH 4 ; |BytesToRead = 4
100536A2 |. 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8] ; |
100536A5 |. 50 PUSH EAX ; |Buffer
100536A6 |. 8B45 BC MOV EAX,DWORD PTR SS:[EBP-44] ; |
100536A9 |. 83C0 08 ADD EAX,8 ; |
100536AC |. 50 PUSH EAX ; |pBaseAddress
100536AD |. 8B85 08FFFFFF MOV EAX,DWORD PTR SS:[EBP-F8] ; |
100536B3 |. 50 PUSH EAX ; |hProcess
100536B4 |. E8 7B2AFBFF CALL <JMP.&kernel32.ReadProcessMemory> ; \ReadProcessMemory
100536B9 |. 6A 40 PUSH 40
100536BB |. 68 00300000 PUSH 3000
100536C0 |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
100536C3 |. 50 PUSH EAX
100536C4 |. 8B45 E4 MOV EAX,DWORD PTR SS:[EBP-1C]
100536C7 |. 8B40 34 MOV EAX,DWORD PTR DS:[EAX+34]
100536CA |. 50 PUSH EAX
100536CB |. 8B85 08FFFFFF MOV EAX,DWORD PTR SS:[EBP-F8]
100536D1 |. 50 PUSH EAX
100536D2 |. E8 BD2AFBFF CALL <JMP.&kernel32.VirtualAllocEx>
100536D7 |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
100536DA |. 50 PUSH EAX ; /pBytesWritten
100536DB |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10] ; |
100536DE |. 50 PUSH EAX ; |BytesToWrite
100536DF |. 8B45 E8 MOV EAX,DWORD PTR SS:[EBP-18] ; |
100536E2 |. 50 PUSH EAX ; |Buffer
100536E3 |. 8B45 E4 MOV EAX,DWORD PTR SS:[EBP-1C] ; |
100536E6 |. 8B40 34 MOV EAX,DWORD PTR DS:[EAX+34] ; |
100536E9 |. 50 PUSH EAX ; |Address
100536EA |. 8B85 08FFFFFF MOV EAX,DWORD PTR SS:[EBP-F8] ; |
100536F0 |. 50 PUSH EAX ; |hProcess
100536F1 |. E8 BE2AFBFF CALL <JMP.&kernel32.WriteProcessMemory> ; \WriteProcessMemory
100536F6 |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
100536F9 |. 50 PUSH EAX ; /pBytesWritten
100536FA |. 6A 04 PUSH 4 ; |BytesToWrite = 4
100536FC |. 8B45 E4 MOV EAX,DWORD PTR SS:[EBP-1C] ; |
100536FF |. 83C0 34 ADD EAX,34 ; |
10053702 |. 50 PUSH EAX ; |Buffer
10053703 |. 8B45 BC MOV EAX,DWORD PTR SS:[EBP-44] ; |
10053706 |. 83C0 08 ADD EAX,8 ; |
10053709 |. 50 PUSH EAX ; |Address
1005370A |. 8B85 08FFFFFF MOV EAX,DWORD PTR SS:[EBP-F8] ; |
10053710 |. 50 PUSH EAX ; |hProcess
10053711 |. E8 9E2AFBFF CALL <JMP.&kernel32.WriteProcessMemory> ; \WriteProcessMemory
10053716 |. 8B45 E4 MOV EAX,DWORD PTR SS:[EBP-1C]
10053719 |. 8B40 34 MOV EAX,DWORD PTR DS:[EAX+34]
1005371C |. 8B55 E4 MOV EDX,DWORD PTR SS:[EBP-1C]
1005371F |. 0342 28 ADD EAX,DWORD PTR DS:[EDX+28]
10053722 |. 8945 C8 MOV DWORD PTR SS:[EBP-38],EAX
10053725 |. 8D85 18FFFFFF LEA EAX,DWORD PTR SS:[EBP-E8]
1005372B |. 50 PUSH EAX ; /pContext
1005372C |. 8B85 0CFFFFFF MOV EAX,DWORD PTR SS:[EBP-F4] ; |
10053732 |. 50 PUSH EAX ; |hThread
10053733 |. E8 342AFBFF CALL <JMP.&kernel32.SetThreadContext> ; \SetThreadContext
10053738 |. 8B85 0CFFFFFF MOV EAX,DWORD PTR SS:[EBP-F4]
1005373E |. 50 PUSH EAX ; /hThread
1005373F |. E8 002AFBFF CALL <JMP.&kernel32.ResumeThread> ; \ResumeThread
10053744 |. 33C0 XOR EAX,EAX
10053746 |. 5A POP EDX
Поставив бряк на CreateProcessA, я нажал F9 (не забывайте обходить ту вредную функцию). Брякаемся и вот параметры функции:
Код:
0012FC6C 1005367F /CALL to CreateProcessA from crackme3.1005367A
0012FC70 00000000 |ModuleFileName = NULL
0012FC74 00DB3A30 |CommandLine = "C:\crackme3u.exe"
0012FC78 00000000 |pProcessSecurity = NULL
0012FC7C 00000000 |pThreadSecurity = NULL
0012FC80 00000000 |InheritHandles = FALSE
0012FC84 00000004 |CreationFlags = CREATE_SUSPENDED
0012FC88 00000000 |pEnvironment = NULL
0012FC8C 00000000 |CurrentDir = NULL
0012FC90 0012FCC0 |pStartupInfo = 0012FCC0
0012FC94 0012FD04 \pProcessInfo = 0012FD04
Действительно создаёт новый процес и тормозит его! А как же нам попасть туда? Аттачится конечно! Но вот беда, Olly видит процес только после выполнения
Код:
1005373F |. E8 002AFBFF CALL <JMP.&kernel32.ResumeThread> ; \ResumeThread
А после выполнения этой функции программу на ep нам не застать! Лан жмём F9 в Olly прога вылетает, новый процесс остаётся! Открываем ещё раз Olly (ну чтоб было два процесса)! Аттачимся!
Открываем карту памяти и вот что замечаем:
Код:
Memory map, item 15
Address=00400000
Size=000A0000 (655360.)
Owner=CrackMe3 00400000 (itself)
Section=
Contains=PE header
Type=Priv 00021040
Access=RWE
Initial access=RWE
Новый image base => новый ep, код которого записывается старым процесом. Посмотрим новый EP!
Код:
00400068 BC950700 DD 000795BC ; AddressOfEntryPoint = 795BC
Ладно всё что нужно мы узнали закрываем окно! Перезапускаем прогу и опять проходим до CreateProcessA. Идём до WriteProcessMemory. И пока не выполняем её! Вот параметры этой функции:
Код:
0012FC80 100536F6 /CALL to WriteProcessMemory from crackme3.100536F1
0012FC84 000000A8 |hProcess = 000000A8 (window)
0012FC88 00400000 |Address = 400000
0012FC8C 00D13A24 |Buffer = 00D13A24
0012FC90 000A0000 |BytesToWrite = A0000 (655360.)
0012FC94 0012FDF0 \pBytesWritten = 0012FDF0
Отправляемся по адресу, с которого ведётся запись в новый процесс! 00D13A24 - это image base в новом процессе, а значит по 00D13A24+795BC будет код ep. Отправляемся по 00D8CFE0. Этот код вызвал у меня истерический смех:
Код:
$+795BC > 9C PUSHFD
$+795BD > 60 PUSHAD
$+795BE > E8 00000000 CALL 00D8CFE7
$+795C3 > 5D POP EBP
$+795C4 > 83ED 07 SUB EBP,7
Судя по всему процесс будет ещё распаковываться =)) Спросите зачем я вас сюда завёл! Смотрите, если в каком-нибудь процессе возникнет исключение, то мы можем поймать его Olly, правильно сконфигурировав её. Итак перебиваем pushfd на int3. Именно int3; не int 3; разница в целый байт! Нам нужен int3 = 0CCh. Теперь конфигурируем Olly. В Options > Just-in-time debugging > Make OllyDbg just-in-time debugger. Теперь когда процесс вызовит исключение, а он вызовит первой же коммандой =), Olly среагирует на это и мы окажемся но ep!
F9 и открывается новый процесс Olly! Ура мы на EP! Возвращаем на место pushf и обходим пакер, благо использовался старый!
Мдя.. На первый взгляд ничего не изменилось...
Код:
00454DFC 55 PUSH EBP
00454DFD 8BEC MOV EBP,ESP
00454DFF 83C4 F0 ADD ESP,-10
00454E02 B8 1C4C4500 MOV EAX,CrackMe3.00454C1C
00454E07 E8 540EFBFF CALL CrackMe3.00405C60
00454E0C E8 7BFDFFFF CALL CrackMe3.00454B8C
00454E11 84C0 TEST AL,AL
00454E13 75 09 JNZ SHORT CrackMe3.00454E1E
00454E15 E8 96FDFFFF CALL CrackMe3.00454BB0
00454E1A 84C0 TEST AL,AL
00454E1C 74 05 JE SHORT CrackMe3.00454E23
00454E1E E8 39EFFAFF CALL CrackMe3.00403D5C
00454E23 A1 98604500 MOV EAX,DWORD PTR DS:[456098]
00454E28 8B00 MOV EAX,DWORD PTR DS:[EAX]
00454E2A E8 71DFFFFF CALL CrackMe3.00452DA0
00454E2F A1 98604500 MOV EAX,DWORD PTR DS:[456098]
И та функця проверки осталась. На этот раз мы в неё зайдём, только через enter. И поставим бряк на первый байт! Теперь если туда попадёт управление мы будем об этом знать! "-" и обходим с помощью New origin here! F9.
Попадание на ep нам практически ничего не дало! Пытал прогу и на String reference и бряки на апи ставил, естественно на последние байты, но это ничего не дало. ппц! Но у меня в запасе был ещё один приём. Я ввёл dimok и вылетело сообщение о неправильности пароля. В ArtMoney нашёл адреса, в которых лежит это слово. Поставил на них бряки и ещё раз нажал ввод!
Бряк сработал мгновенно я оказался внутри какойто функции!
Посомотрим на стек, там несколько раз встречается слово dimok. Но мы ищем первый адрес вазврата в секцию кода и находим
Код:
0012F45C |00437B10 RETURN to CrackMe3.00437B10 from CrackMe3.00406278
Идём по адресу!
Код:
00437B03 50 PUSH EAX
00437B04 8B86 74010000 MOV EAX,DWORD PTR DS:[ESI+174]
00437B0A 50 PUSH EAX
00437B0B E8 68E7FCFF CALL CrackMe3.00406278 ; JMP to USER32.CallWindowProcA
00437B10 8943 0C MOV DWORD PTR DS:[EBX+C],EAX
00437B13 8B03 MOV EAX,DWORD PTR DS:[EBX]
00437B15 83F8 0C CMP EAX,0C
00437B18 75 1B JNZ SHORT CrackMe3.00437B35
00437B1A 8B53 08 MOV EDX,DWORD PTR DS:[EBX+8]
00437B1D 52 PUSH EDX
Снимаем старые бряки и поставим новый на 437b1a. Нажмём на кнопочку, и бряк срабатывает!
Код:
00437B1A 8B53 08 MOV EDX,DWORD PTR DS:[EBX+8]
00437B1D 52 PUSH EDX
00437B1E 8B4B 04 MOV ECX,DWORD PTR DS:[EBX+4]
00437B21 8BD0 MOV EDX,EAX
00437B23 8BC6 MOV EAX,ESI
00437B25 E8 56B7FFFF CALL CrackMe3.00433280
Один из параметров этой функции адрес Warning. Следовательно функция проверки гдето выше, а то куда мы попали это функции отрисовки MessageBoxA. Начинаем трассировать. В стеке должны храниться адреса строк о неправильности. Мыже находимся в вызываемой функции отрисовки. Короче жмём F8 пока в стеке нам не встретятся строчки о неправильности! Дальше нам встретится
Код:
0012F93C 00DB2448 ASCII "dimok"
0012F940 00DB3B90 ASCII "351239814584495632156"
0012F944 00DB23F8 ASCII "651236594485418932153-XNA"
0012F948 00DB2420 ASCII "ANX-351239814584495632156"
а после этого следует адрес возврата
Код:
0012F950 |00434C7A RETURN to CrackMe3.00434C7A
идём по нему и мы окажемся в этой функции, если подняться выше.
Код:
004549BC 55 PUSH EBP
004549BD 68 CC4A4500 PUSH CrackMe3.00454ACC
004549C2 64:FF30 PUSH DWORD PTR FS:[EAX]
004549C5 64:8920 MOV DWORD PTR FS:[EAX],ESP
004549C8 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
Кароче, если вы её проанализируете, то поймёте, что пароль ANX-351239814584495632156.
|