суббота, 26 декабря 2015 г.

Изучение Base64

Сегодня я решил написать о том, как выглядит алгоритм base64 в исполняемом файле.
Для этого я взял две реализации, мою собственную (немного корявую), и взятую из интернета.
Собственно логика этого алгоритма предельно проста: исходная строка разбивается на символы, затем они переводятся в двоичный вид, склеиваются в одну последовательность, затем берется грубо говоря по 6 бит и сравнивается с таблицей base64, в которой каждой такой последовательности соответствует символ из ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/.

Данный пост отражает только мысли автора.

четверг, 24 декабря 2015 г.

Разбор MaxXor's KeygenMe V6

Ссылка на оригинал http://www.crackmes.de/users/maxxor/keygenme_v6/

Итак, первым делом проверим файл на упакованность через DIE. Нам показывает что он не упакован, и что написан на С/С++.
Далее загружаем файл в IDA и что же мы там видим. А видим мы там много "лишнего" кода, который определяет и создает формы приложения. Тем не менее, после непродолжительных поисков мы находим функцию, в которой создается форма с текстом "Thank you for registering!".

После вдумчивого анализа графа в IDA вот к чему я пришел:
есть имя и оно должно быть числовое;
есть пароль и он должен быть 20 символов, при этом присутствует символ тире ('-');

Также есть цикл проверки, в котором есть две ветви:

Подумав на ассемблерным кодом, я пришел к выводу, что сначала проверяется чтобы имя было из четырех цифр.
Затем на основе имени заполняется некоторый массив по формуле:
      Bufname[j] = name * (name / (8 * j + 16)); j<4;
Потом идет основной цикл, цель которого расчитать индекс для взятия символа и массива хеша:
      SecHash = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

Вот этот цикл:
for ( k = 0; k < 20; ++k )
      {
        if ( !k || (signed int)k % 5 )    //проверяется остаток от деления на 5    
        {
          if ( (signed int)k % 2 )        //проверяется остаток от деления на 2    
          {
            a = (signed int)k / 4 + 1;    //ветвь первая
            if ( a > 3 )
              a -= 4;
            b = 2 * (Bufname[a] % (signed int)(k + 1));
            if ( (signed int)b <= 9 )
              b += 3;
            if ( (signed int)b >= 36 )
              b -= 10;
            if ( (b & 0x80000000) != 0 || (signed int)b > 35 )    //проверка на выход за пределы SecHash
              b = k + 7;
            OutPass += SecHash[b];
          }
          else
          {
            c = (signed int)k / 4 + 1;      //ветвь вторая
            if ( c > 3 )
              c -= 4;
            d = 2 * (Bufname[c] % (signed int)(k + 1));
            if ( (signed int)d <= 9 )
              d += 4;
            if ( (signed int)d >= 36 )
              d -= 10;
            if ( (d & 0x80000000) != 0 || (signed int)d > 35 )
              d = k + 7;
            OutPass += SecHash[d];
          }
        }
        else
        {
          OutPass += '-';
        }
      }

По сути алгоритм не так уж и сложен. Вот собственно и все что я хотел рассказать.

вторник, 22 декабря 2015 г.

Разбор CrackMe by Fereter #1

Данный разбор представлен исключительно в ознакомительных целях!

Собственно полностью логику данного кракми я до конца не понял, но поставленную его автором задачу выполнил:) А задача стояла такая:
------------------------------------
An easy crackme for Windows. It implements a simple protection against debugging and against binary patching.
The goal of this exercise is to patch this executable file in order to any password was accepted.
------------------------------------
Для решения этой задачи я использовал:
   OllyDbg 2.0 в качестве отладчика.
   HxD в качестве хекс-редактора.
   IDA pro в качестве статического анализатора.

Загрузив файл в IDA я увидел что выполнение программы начинается с:
--------------------------------------------------------------------------
.code:00403070                 push    10480000h       ; dwStyle
.code:00403075                 push    offset Caption  ; "CrackMe by Fereter"
.code:0040307A                 push    offset ClassName ; "GetNumberClass"
.code:0040307F                 push    0               ; dwExStyle
.code:00403081                 call    ds:CreateWindowExA
.code:00403087                 test    eax, eax
.code:00403089                 jz      short loc_4030CA
.code:0040308B
.code:0040308B loc_40308B:                             ; CODE XREF: start+B8 j
.code:0040308B                                         ; DATA XREF: start+94 o
.code:0040308B                 push    0               ; wMsgFilterMax
.code:0040308D                 push    0               ; wMsgFilterMin
.code:0040308F                 push    0               ; hWnd
.code:00403091                 push    offset Msg      ; lpMsg
.code:00403096                 call    ds:GetMessageA
.code:0040309C                 mov     ebx, eax
.code:0040309E                 call    ds:IsDebuggerPresent
.code:004030A4                 add     eax, offset loc_40308B
.code:004030A9                 cmp     ebx, 1
.code:004030AC                 jb      short loc_4030DB
.code:004030AE                 jz      short loc_4030B2
.code:004030B0                 jmp     eax
--------------------------------------------------------------------------
А вот немного причесанный вид основной процедуры:

Теперь видно что если мы сразу откроем этот кракми в Olly то придется либо пользоваться плагинами для обхода антиотладки, либо вручную менять значения регистров при выполнении. Я ленивый, поэтому я просто запустил файл отдельно, и приаттачился к нему.


Собственно все что нам надо узнать в данном случае, так это где проверяется пароль на правильность. Здесь проверок две:
сначала по адресу 00403225h, затем 0040328Dh. Так вот, так как обычно патчингу подвергаются команды типа jmp, я подумал что на их целостность и проверяется этот кракми. Поэтому я решил изменить предшествующие команды
cmp EAX, ECX на cmp EAX, EAX, тем более что в обоих случаях они одинаковые.
Для этого я открыл кракми в хекс-редакторе и через поиск заменил байты 39C8 на 39C0. Если дизассемблировать эти опкоды, то получатся нужные нам инструкции. 
Ну собственно вот и все:) Хочу сказать, что я очень долго тупил над тем, как же все таки реализована защита от патчинга, но так ничего и не понял. Так что буду рад если мне кто-нибудь поможет))