Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Авторские статьи (https://forum.antichat.xyz/forumdisplay.php?f=31)
-   -   Брут (https://forum.antichat.xyz/showthread.php?t=34206)

taha 26.02.2007 12:39

Брут
 
Брут паролей

Сегодня я поведаю о том, как узнать пароль, не зная алгоритма генерации, вобщем о бруте. Скажу сразу, дело это долгое и весьма рисковое. Помните один из главных принципов - чем меньше изменений мы вносим в логику программы, тем лучше. Вдеь мы будем менять логику программы, внедрять свой код.

[iNtr0]

Перебор паролей происходит по средствам внедрения генератора и определения нескольких состояний полученной системы - правильный пароль, неправильный. Определяем куда поподает управление при правильном пароле и при неправильном. Если пароль правильный, то тормозимся и вызываем отладчик, а если нет, меняем (генерируем новый) и проверяем его и тд., получается, маленький такой, конечный автомат.

[scripts]

Эта часть статьи написана по принципу 'зацените изврат'. Брут через скрипты для Olly не самое быстрое занятие, но если вам так же как и мне нравится смотреть на бегущие буквы, то это для Вас. Долгое потому, что код сначала интерпритируется плагом OllyScript затем в игру вступает сама Olly и только потом прога. Так что мы успеваем и буквы увидеть.

Начнём пожалуй. Сперва мне понадобилась программа с простейшим способом проверки. И я написал эти скромные строки.

Код:

        invoke func_prov,offset str_pass,offset brutpass
        test eax,eax
        je @F
        invoke MessageBox,0,0,0,0
@@:
        push 0
        call ExitProcess

Где func_prov - функция, осуществлющая проверку, тупо, через cmp reg1,reg2. Она возвращает 0 если пароль неправильный, и 1 если правилный. Если мы выполняем перебор через скрипт, то внедрять в программу ничего не нужно, просто поставим бряки... Как бы это сказать?! Ну вот из чего состоит простейший автомат?... Сначала идёт проверка состояния, потом передача управления на нужный код (переход). Проверка состояния (switch в switch-технологии, извините за тавтологию =)) происходит с помощью

Код:

        invoke func_prov,offset str_pass,offset brutpass
        test eax,eax
        je @F

У нас два состояния 0 и 1. Если 0, то управление передаётся на

Код:

        push 0
        call ExitProcess

если 1, то на

Код:

        invoke MessageBox,0,0,0,0
Откроем прорамму в Olly.

Код:

00401000  PUSH prog.00403006
00401005  PUSH prog.00403000                      ;  ASCII "ACBCA"
0040100A  CALL <prog.func_prov>
0040100F  TEST EAX,EAX
00401011  JE SHORT prog.00401021
00401013  PUSH 0                                  ; /Style = MB_OK|MB_APPLMODAL
00401015  PUSH 0                                  ; |Title = NULL
00401017  PUSH 0                                  ; |Text = NULL
00401019  PUSH 0                                  ; |hOwner = NULL
0040101B  CALL <JMP.&user32.MessageBoxA>          ; \MessageBoxA
00401020  PUSH 0                                  ; /ExitCode = 0
00401022  CALL <JMP.&kernel32.ExitProcess>        ; \ExitProcess

Мы поставим бряки на 00401020 и 00401013. Если сработает бряк по адресу 00401020, то сгенерированный пароль не подходит, если по адресу 00401013, то всё круто можно выходить (из скрипта).

Мной был написан следующий скрипт (не буду вдаваться в особенности генерации и несовершенности OllyScript, имхо не для этого он был написан).

Код:

//  Name:        Bruter 0.1
// Author:        taha
//  Date:        18/02/07

//-- .data ---------------------------------

        var ot
        mov ot,41
        var do
        mov do,43

//_ address ___________________
        var start_addr
        mov start_addr,00401000
        var bad_addr
        mov bad_addr,00401020
        var good_addr
        mov good_addr,00401013

//__ string _________________
        var str_addr
        mov str_addr,00403006

        var y
        var count

//__ backUp _____
        var b_eax
        var b_ebx
        var b_ecx
        var b_edx
        var b_esi
        var b_edi
        var b_esp
        var b_ebp

//-- .code ---------------------------------

        bphws bad_addr,"x"
        bphws good_addr,"x"

        mov b_eax,eax
        mov b_ebx,ebx
        mov b_edx,edx
        mov b_ecx,ecx
        mov b_edi,edi
        mov b_esi,esi
        mov b_esp,esp
        mov b_ebp,ebp

        mov count,str_addr
        mov y,str_addr
        mov [str_addr],41

genstr:
        cmp [y],do
        je gen_ra
        inc [y]
        jmp gen_ex
 gen_ra:
        fill y,1,ot
        cmp y,str_addr
        je add_s
        mov eax,y
        dec eax
        mov ecx,[eax]
        and ecx,FF
        cmp ecx,do
        je y_dec
        inc [eax]
        jmp gen_ex
 y_dec:
        dec y
        jmp gen_ra
 add_s:
        fill count,1,ot
        inc count
        fill count,1,ot
 gen_ex:
        mov y,count

        run
        cmp good_addr,eip
        je good

        mov eax,b_eax
        mov ebx,b_ebx
        mov ecx,b_ecx
        mov edx,b_edx
        mov edi,b_edi
        mov esi,b_esi
        mov esp,b_esp
        mov ebp,b_ebp

        mov eip,start_addr
        jmp genstr

good:
        BPHWC good_addr
        BPHWC bad_addr
        msg "Всё гуд"
        ret

Просто указываете адреса куда нужно попасть, а куда нет, адрес начала проверки и адрес буффера. Изначально строка, буффер, должна состоять из одного символа "A". Да, и не забудте указать с какого по какой символ.

Код:

        var ot
        mov ot,41
        var do
        mov do,43

Запускаем скрипт и...

Код:

00403000  41 43 42 43 41 00 41 43 42 43 41 00 00 00 00 00  ACBCA.ACBCA.....
Heppy end!

[aSm]

Тут всё сложнее, здесь нужно изменять не только логику, но и код. Однако смысл тот же. Я не стал ничего никуда внедрять, а сразу написал программу как будто внедрение было.

Код:

start:
        invoke func_prov,offset str_pass,offset brutpass
        test eax,eax
        je @F
        invoke MessageBox,0,0,0,0
        int 3
@@:
        jmp Brute
        push 0
        call ExitProcess

Как видите, если пароль неверный, то происходит переход на наш код генерации, оттуда опять на start, а если верный то тормозится по int 3 и мы читаем пасс =)). Внедрять куда-либо мне было лень.

[полиморфы]

Я о простейших видах полиморфизма. Просто расшифровка какой-либо функции. Здесь тоже всё просто, но есть одна маленькая неприятность. Я пробовал брутить крямис ProTeuS'a. И прога упала при ключе 0BBh (187). Стек был забит всякой гадостью. Попробовал проанализировать код на котором она упала. Это был просто push [...]. Значит при предыдущих ключах вся область стека забилась мусором. Для того чтобы понять о чём я собствено сейчас пишу попробуйте испольнить следующие строки

Код:

xor eax,eax
dec eax
mov esp,eax

А теперь попробуйте чтонить пропушить. Тото)). Большая неприятность. НО можно прогу перезапустить и начать брут с следующего ключа. Склоко раз предётся перезапускаться неизвестно...

[ps]
Врядли вам это пригодится. ИМХО брутить алго, смыс которого в расхоривании имени, нерационально. А если прога для собственного пользования, то проще перебить переход.


Время: 12:17