Легальный взлом как разминка для ума

    IT-шники часто придумывают себе упражнения для ума, пытливый ум постоянно требует разминки. Хочу рассказать об одном из самых жестких и спорных способах – взлом специально защищенных программ-головоломок (Часто их называют crackme).

    Одно из мест, где такие головоломки собраны — crackmes.de.

    Здесь находятся много интересных программ, на которых можно испробовать свои силы по взлому. Никакого криминала – программы специально написаны для этой цели (так называемые crackme и reverseme);

    Часто любят говорить «Все защиты можно взломать». Поковыряв некоторые из crackme вы возможно измените своё мнение.


    Итак приступим:


    Общая схема работы многих crackme — а давайте какую-то процеду в коде зашифруем, и «верный-неверный пароль» — в зависимости от сделанного хеша из расшифрованных этим паролем данных?

    Или как вариент — заюзаем SEH (Structured Exception Handling – механизм обработки аппаратных и программных исключений), в который положим месседжбокс о плохом пароле, перед этим передав управление на наш «расшифрованный» код, при этом если пароль – правильный, то в расшифрованном коде будут «верные» опкоды команд, а если нет, то процессор сгенерит исключение о неверном опкоде и «кошерно» задействует SEH, в котором у нас стоит уведомление об ошибке. Надо сказать, что в общем этот вариант не «святой» поскольку после расшифровки возможны и «полувалидные» опкоды- к примеру jmp-команда за пределами этой нашей процедуры.

    Но на первых порах и этого достаточно.

    Итак берём крекми отсюда: crackmes.de/users/sharpe/unlockme_crackme_8_by_sharpe/download или отсюда:
    crackmes.de/users/sharpe/unlockme_crackme_7_by_sharpe/download (седьмой, кстати, не взломан пока) и загружаем в дебаггер- я использовал олю (OllyDBG)- програмка – очень маленькая- сегмент кода всего 0х2В6=694 байта, очень легко найти часть кода отвечающего за чтение пароля:

    0040107F  |. 3D F3030000    CMP EAX,3F3
    00401084  |. 75 4E          JNZ SHORT 004010D4                       
    00401086  |. 6A 21          PUSH 21                                 	 ; /Count = 21 (33.)
    00401088  |. 68 88314000    PUSH 403188                            	 ; |Buffer = eight.00403188
    0040108D  |. 68 F1030000    PUSH 3F1                                	 ; |ControlID = 3F1 (1009.)
    00401092  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]   ; |hWnd
    00401095  |. E8 04020000    CALL 0040129E                           ; \GetDlgItemTextA
    0040109A  |. 83F8 07        CMP EAX,7		здесь сравниваем длину пароля
    0040109D  |. 76 1F          JBE SHORT 004010BE                       переход на смерть
    0040109F  |. 83F8 20        CMP EAX,20		здесь тоже сравниваем длину пародя
    004010A2  |. 73 1A          JNB SHORT 004010BE                       
    004010A4  |. E8 D9000000    CALL 00401182                            преобразователь пароля
    004010A9  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                
    004010AC  |. E8 FD000000    CALL 004011AE                            расшифровщтк кода
    004010B1  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                
    004010B4  |. E8 61010000    CALL 0040121A                            не интересно
    004010B9  |. E9 85000000    JMP 00401143                             ;  eight.00401143
    004010BE  |> 6A 30          PUSH 30                                  а здесь прыгать не надо)))
    004010C0  |. 68 34314000    PUSH 403134                              ; |Title = "-=[ Unlock Code Error"
    004010C5  |. 68 4A314000    PUSH 40314A                              ; |Text = "The entered Unlock Code is invalid.
    004010CA  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                ; |hOwner
    004010CD  |. E8 D8010000    CALL 004012AA                            ; \MessageBoxA
    004010D2  |. EB 6F          JMP SHORT 00401143                       ;  eight.00401143


    Итак, на основании этого видим что длина пароля долна быть в диапазоне 8-32 знака, и если это так то прыгаем в функцию преобразования изначального пароля:

    00401182  /$ 57             PUSH EDI
    00401183  |. 33FF           XOR EDI,EDI
    00401185  |. BE 88314000    MOV ESI,403188                           ;  здесь в регистр пишем указатель на пароль 
    0040118A  |. B9 20000000    MOV ECX,20
    0040118F  |. C705 A8314000 >MOV DWORD PTR DS:[4031A8],0 ;здесь мы запишем преобразован «хеш»
    00401199  |> AC             /LODS BYTE PTR DS:[ESI]
    0040119A  |. 85C0           |TEST EAX,EAX
    0040119C  |. 74 08          |JE SHORT 004011A6                       ;  eight.004011A6
    0040119E  |. 8BC8           |MOV ECX,EAX	;здесь  мы сохраним «хеш» с пароля
    004011A0  |. 03F8           |ADD EDI,EAX	;процедура преобразования пароля
    004011A2  |. D3C7           |ROL EDI,CL		; процедура преобразования пароля
    004011A4  |.^EB F3          \JMP SHORT 00401199                      ;  eight.00401199
    004011A6  |> 893D A8314000  MOV DWORD PTR DS:[4031A8],EDI; сохраняем и выходим 
    004011AC  |. 5F             POP EDI
    004011AD  \. C3             RETN


    А вот здесь живет расшифровщик кода:

    004011AE  /$ 55             PUSH EBP
    004011AF  |. 8BEC           MOV EBP,ESP
    004011B1  |. 83EC 04        SUB ESP,4
    004011B4  |. 68 88314000    PUSH 403188                              ; здесь вновь проверяем длину пароля 
    004011B9  |. E8 C2000000    CALL 00401280                            ; но это – не обязательно
    004011BE  |. 8945 FC        MOV DWORD PTR SS:[EBP-4],EAX
    004011C1  |. 837D FC 01     CMP DWORD PTR SS:[EBP-4],1
    004011C5  |. 77 16          JA SHORT 004011DD                        ;  eight.004011DD
    004011C7  |. 6A 30          PUSH 30                                  
    004011C9  |. 68 34314000    PUSH 403134                              ; |Title = "-=[ Unlock Code Error"
    004011CE  |. 68 4A314000    PUSH 40314A                              ; |Text = "The entered Unlock Code is invalid.
    004011D3  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                ; |hOwner
    004011D6  |. E8 CF000000    CALL 004012AA                            ; \MessageBoxA
    004011DB  |. EB 1E          JMP SHORT 004011FB                       ;  eight.004011FB
    004011DD  |> B8 49114000    MOV EAX,401149                ;  А вот здесь начинается расшифровка пароля
    004011E2  |. B9 7F114000    MOV ECX,40117F
    004011E7  |. 2BC8           SUB ECX,EAX				
    004011E9  |. 33DB           XOR EBX,EBX
    004011EB  |> 8B1418         /MOV EDX,DWORD PTR DS:[EAX+EBX]
    004011EE  |. 3315 A8314000  |XOR EDX,DWORD PTR DS:[4031A8]; как видем простая ксор-функция
    004011F4  |. 891418         |MOV DWORD PTR DS:[EAX+EBX],EDX
    004011F7  |. 43             |INC EBX
    004011F8  |. 49             |DEC ECX
    004011F9  |.^75 F0          \JNZ SHORT 004011EB                      ;  и выходим
    004011FB  |> C9             LEAVE
    004011FC  \. C2 0400        RETN 4


    Итак, теперь понятно: но как найти правильный хеш-код?
    Перебором?

    Это очень долго: надо сначала расшифровать, потом посчитать «энтропию» полученного кода и возможно код с минимумом «энтропии»- рабочий, но для этого надо писать или использовать уже написанные дизассемблерные движки;
    а можно использовать SEH, в теле которого прописать код брумфорсера, но тогда даже одна «ложно-правильная» инструкция может полностю изменить верный ход исполнения программы.
    Но я заметил, что хоть программа написана на чистом ассемблере, но автор всё-же много использовал в своём коде «открытие» стека, поэтому давайте думать, что первые правильные 4 байта в нашем «зашифрованном» коде:

    PUSH EBP
    MOV EBP,ESP
    

    Значение: 0х55, 0х8В, 0хЕС

    А сейчас(до прохождения процедуры шифрования) значения: 0x66, 0x71, 0x77, но мы же помним (можем посмотреть) свойства «ксор» функции и увидеть что тогда конечный хеш станет извесным:
    Не забываем о «little-endian» соглашении:

    77 71 66 ^
    АА ВВ СС ^
    ВВ СС    ^
    СС
    **********
    ЕС   8В   55


    Итак, посчитав это дело в «Калькуляторе» мы видем, что СС=0х33; ВВ=0хС9; АА=0х61,
    Полученная последовательность: ХХ61C93.

    Последний байт, к сожалению, пришлось искать перебором с использованием «self-keygening»a (патчинга бинарника), и в конце получаем: E961C933.

    А расшифрованная процедура в действительности содержит много мусора(«обфускация»)
    Но «открытие стека» нас спасло, и расшифрованая процедура (в теле):
    00401149   $ 55             PUSH EBP
    0040114A   . 8BEC           MOV EBP,ESP
    0040114C   . D3C8           ROR EAX,CL
    0040114E   . 58             POP EAX
    0040114F   . EB 04          JMP SHORT 00401155                       ;  eight.00401155
    00401151     D6             DB D6
    00401152     FE             DB FE
    00401153   . 32C9           XOR CL,CL
    00401155   > BE 9C314000    MOV ESI,40319C                           ;  ASCII "Secret: Marius!"
    0040115A   . C706 53656372  MOV DWORD PTR DS:[ESI],72636553
    00401160   . C746 04 65743A>MOV DWORD PTR DS:[ESI+4],203A7465
    00401167   . C746 08 4D6172>MOV DWORD PTR DS:[ESI+8],6972614D
    0040116E   . C746 0C 757321>MOV DWORD PTR DS:[ESI+C],217375
    00401175   . EB 00          JMP SHORT 00401177                       ;  eight.00401177
    00401177   > 58             POP EAX
    00401178   . FFE0           JMP EAX
    0040117A     F7             DB F7
    0040117B     ED             DB ED
    0040117C     12             DB 12
    0040117D     DA             DB DA
    0040117E     3F             DB 3F                                    ;  CHAR '?'
    0040117F     4E             DB 4E                                    ;  CHAR 'N'
    00401180     40             DB 40                                    ;  CHAR '@'
    00401181     C4             DB C4


    Всё что делает ета процедура-записывает слово: Secret: Marius! по соответственому указателю.
    Далее осталось узнать исходный пароль – Ну, тут – брутфорс вам в помощь))))

    Процедуру преобразования можна «ripp»ать у нашей програмы и оформить это дело как ассемблерную вставку.

    	mov  dword ptr [znach], 0	
    	xor  edi, edi
    	mov  esi, [str1]
        m:
    	lodsb
    	test al, al
    	jz   m1
    	mov  ecx, eax
    	add  edi, eax
    	rol  edi, cl
    	jmp  m


    Да, исходный пароль-005sj[Vg

    Только, если брутфорс будете писать под какую-то экзотику типа cuda или под шейдеры- помните там нет инструкции циклического сдвига- rol eax, 5 и ёё надо заменить на два простых сдвига (один влево и один вправо) и потом «or» над полученным; реализация в виде: #define ROT (n, m) (((n)<<(m))|((n)>>(32-(m))))
    В следующих постах вы узнаете о других интересных способах взлома неломаемых защит.

    PS. Автор статьи (ash — его пока нет на хабре) попросил меня опубликовать эту статью.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 42

      +1
      Помню как баловался подобным после того как прошёл курс ASMа в ТУСУРе. Очень нравилось! Всем советую попробовать себя в ASMе, это очень занимательно :)
        0
        поддержываю,
        головоломки на асемблере отлично развивают мышление =)
        0
        Да, помню еще писал на ассемблере резидентную игралку в тетрис, встроенный в Dos Navigator (смотрит на экран, ищет падающие фигурки, жмет на кнопки) — успевало играть до 8-й скорости :-)
          +4
          Предвижу вопрос — почему не на максимальной, 9-й? :-)
          Программа анализировала экран по стандартному прерыванию, которое идет каждые 55мс (18.2 раз в секунду).
          На 9-й скорости смотреть на экран и жать на кнопки 18 раз в секунду — недостаточно для победы :-)

          Хотел бы я посмотреть на человека, который может выдержать такой темп :-D
            +11
              +1
              я в шоке!!!
                +4
                Сколько же надо было провести времени тренируясь?
                Интересно, он кроме того, что играть в тетрись, хоть что-нибудь ещё в жизни умеет?
                  0
                  Добывать огонь трением )
                  +2
                  ну в этом варианте игры видно аж целых три последующих фигуры.
                  так что по большому счёту там только ловкость рук.
                  но тем не менее да, круто.
                    0
                    а как он собирал, когда не видно было фигурок?

                    зы. аааад
                0
                Я, наверное, штук 100 крякмисов с crackmes.de прорешал, потом надоело. Перешел на win7 и ollyadvanced не работает. Кто-нибудь правил?
                +4
                Мммм… Знакомый прогер в олимпиадной задаче писал перевод системного таймера на 1 секунду назад, чтобы прога соответствовала олимпиадному ограничению по времени выполнения.
                  0
                  И как, зачли? :)
                    0
                    Ага. Даже место призовое дали.
                      +3
                      Я делал круче ) Искал по всем дискам файлы с содержимым таким же, какое подсовывают на входе, угадывал расширение файла с правильным ответом, и выводил его. Максимальный балл, раскрылось через несколько лет :-)
                        +1
                        Раскрылось потому что мигала лампочка CDROM-а при тестировании :-D
                          +1
                          Грамотная проверялка заданий должна запускать проги как минимум в jail имхо
                            +1
                            А по времени успевали сделать поиск? (:
                          0
                          Помню, когда я был маленький, нам на кружке программирования рассказали такую историю.

                          Один из преподавателей (давали предмет нам студенты/старшеклассники) пришел на олимпиаду по программированию. Посмотрел на задания и поинтересовался: «на каком языке сдавать?»

                          «На каком хотите», — на свою беду ответили в комиссии.

                          Парень написал программу на ассемблере, сходил в соседнюю аудиторию, набрал, сделал комок, распечатал его на матричном принтере и сдал.
                          +2
                          wasm.ru
                          Введение в крэкинг с нуля, используя OllyDbg — Глава 1-46(Рикардо Нарваха)
                            0
                            Приёмы социальной инженерии применять можно? :)
                              +1
                              можно. только некуда.
                                0
                                В этом и заключается подзадачка, которая тоже решается.
                                  0
                                  тут цели не те. как вы социальной инженерией кейген напишете? или nag screen вырежете?
                                    0
                                    Делегировать задачу фрилансеру, да так, чтобы бесплатно :)
                              +2
                              в конце школы увлекался этим… даже свой крякми написал простенький =)
                              crackmes.de/users/stigger/stigger/
                                +1
                                Реверс — это, можно сказать, идеальное хобби.
                                Всегда есть к чему стремиться, всегда есть что-то новое и всегда есть направление, в котором можно совершенствоваться.
                                Очень затягивает :)
                                  +1
                                  Нада будет перед сном, вместо книжки почитать.
                                    +1
                                    нда помню как сам просидывал ночами на нашем cracklab.ru там тоже выкладывали неломаемые крякмисы и кучу полезных статей:) а потом как то прошло увлечение.
                                      0
                                      Насчет перевода системного времени на секунду назад — это классная идея :)
                                        0
                                        прикольно, жалко на асм мозгов не хватает(
                                          0
                                          Эх, asm уже не торт (то есть, увы, уже абсолютно не греет).

                                          Вот в начале 90-х масм, тасм, резиденты, взлом эротических игрушек, чтобы посмотреть все картинки, было время.

                                          Вот если бы за решение каждой задачи давали, например, килобакс.
                                            –1
                                            Надают больше.
                                            100К за реверс вас устраивает?
                                            Тогда вперёд: Opera/FireFox/IE7/IE8 итд… находите дырку — 100K ваши (виртуальные, конечно, т.к. вряд ли вы быстро найдёте кому продать 0day exploit)
                                              –1
                                              Забыла, можно и по честному.
                                              К примеру в MSFT есть целое подразделение которое занимается фазингом (вообщем ломает сообственные продукты).
                                              Там з.п. хорошая, может подавать резюме, кстати MSFT HRы кажется должны быть уже в MSK
                                                0
                                                класная работа ломать проги за деньги… создателей этих прог)))
                                                сам занимался этим.
                                                а вы как с ассемблером?
                                                0
                                                Из вашего поста не понятно, даюи или не дают?

                                                100К хорошая сумма, можно и вписаться в тему.
                                              +1
                                              Жаль, не раскрыта тема «self-keygening».
                                                0
                                                Раскрываю)))

                                                сначала патчим екзешник в дебагере- в СЕХ пошем код брутфорсера: он расшифров. наш блок и передаёт управление на него, если правильный пароль то «возбуждения» СЕХа не происходит; но не забывайте что в коде бруофорсера сначала надо зашифровать начальным паролем а потом пробовать расшифровать «новым» паролем.
                                                0
                                                Сайт crackmes.de инфицирован
                                                  0
                                                  static analysis AV product must die!

                                                  а что вы хотели многие прийоми используются в вирусах
                                                  0
                                                  Да это клёвая тема. Жду продолжения, может вернуться в это хобби… :)

                                                  Only users with full accounts can post comments. Log in, please.