Контакты

Для связи с нами можно использовать:
irc://irc.chatnet.ru:#gfs
icq://546460
email://cobalt[@]gfs-team.ru

Все материалы предоставлены только с ознакомительной целью
ГлавнаяСтатьиВирусологияИстория о том, как я тестовое задание касперского проходил
© jsm 05.01.2015

[ Предыстория ]

Вечером я как обычно просматривал почту, интересного было мало, пока я не увидел заголовок, который гласил "тестовое задание от лаборатории  касперского", в нем говорилось что для того что бы мне попасть к ним на собеседование мне нужно выполнить тестовое задание на реверс, а именно взломать crackme который они мне прислали и объяснить как я нашел ключ и почему он именно такой. подумав, ну а что можно и поломать раз времени много свободного, по имени архива я понял что приложение 64-битное, по этому только IDA-pro мне в помощь.

[ Осмотр ]

Думать особо в начале не стоило, так как посмотрев какие API вызываются в приложении, стало очевидно откуда мне начинать поиски, но не все так просто как в обычных crackme, веселье только начиналось.

[ Взлом ]

В начале исследования программы я установил точку останова "breakpoint" на вызов GetDlgItemTextA так как функция GetDlgItemText извлекает текст из указанного элемента, будь то заголовок приложения или элемент для ввода текста.

.text:0000000140001153                 call    cs:GetDlgItemTextA
.text:0000000140001159                 lea     rcx, [rsp+78h+String]
.text:000000014000115E                 mov     edx, eax

Следующий вызов, это вызов функции проверки пароля, почему я так решил? ответ ниже ну или если посмотреть в графическом отображении кода в IDA pro (клавиша проблем), там все и так становится понятным, для того кто хотя бы два или три раза крошил приложения.

.text:0000000140001160                 call    sub_140001000

После входа в функцию проверки пароля "нажатие F7 в IDA pro",первая стадия проверки если ключ равен длине 19, положить в r8 первые 10 символов.

.text:0000000140001000 sub     rsp, 18h
.text:0000000140001004 cmp     edx, 13h
.text:0000000140001007 mov     r8, rcx
.text:000000014000100A jz      short loc_140001013
Если длина не 19 символов то выходим и говорим об ошибке:
.text:000000014000100C loc_14000100C:                          ; CODE XREF: sub_140001000+23 j
.text:000000014000100C xor     eax, eax
.text:000000014000100E add     rsp, 18h
.text:0000000140001012 retn

В следующем блоке кода происходит проверка на символ - в ключе

.text:0000000140001020 loc_140001020:                          ; CODE XREF: sub_140001000+2F j
.text:0000000140001020 cmp     byte ptr [rax], 2Dh
.text:0000000140001023 jnz     short loc_14000100C
.text:0000000140001025 add     ecx, 1
.text:0000000140001028 add     rax, 5
.text:000000014000102C cmp     ecx, 3
.text:000000014000102F jb      short loc_140001020

Участок кода проверят что каждый 5 символ должен быть символом "-" hex(2Dh) если это не так то прыжок .text:0000000140001023 jnz short loc_14000100C отправит нас на выход и далее ошибка о неправильном вводе пароля.

.text:0000000140001053 loc_140001053:                          ; CODE XREF: sub_140001000+6C j
.text:0000000140001053 movsx   eax, byte ptr [r9+rcx]
.text:0000000140001058 add     eax, -30h
.text:000000014000105B cmp     eax, 9
.text:000000014000105E ja      loc_1400010FD
.text:0000000140001064 add     rcx, 1
.text:0000000140001068 cmp     rcx, 4
.text:000000014000106C jl      short loc_140001053

Данный участок кода провер€ет каждые 4 символа ключа должны быть числами с 0 - 9, в противном случае прыжок .text:000000014000105E ja loc_1400010FD отправит нас на выход из проверки, а далее ошибка о неправильном вводе пароля.

Следующий участок кода считывает значения каждого ряда значений ключа начиная с предпоследнего в eax, последнего в ecx ряда чисел, далее добавляется в r11d значение 1 и в регистр ecx добавляется значение eax, суммирует их.

.text:000000014000106E movsx   eax, byte ptr [r9+2]
.text:0000000140001073 movsx   ecx, byte ptr [r9+3]
.text:0000000140001078 add     r11d, 1
.text:000000014000107C add     ecx, eax

Дальше происходит считывание в eax второго значения ключа, далее это значение суммируется с остальными в регистре ecx.

.text:000000014000107E movsx   eax, byte ptr [r9+1]
.text:0000000140001083 add     rbx, 4
.text:0000000140001087 add     ecx, eax

Считываем первое значение в eax ключа и суммируется с остальными в ecx, после добавляется к ecx значение r11d очень важный момент, но о нем ниже.

.text:0000000140001089 movsx   eax, byte ptr [r9]
.text:000000014000108D add     r9, 5
.text:0000000140001091 add     ecx, eax
.text:0000000140001093 add     ecx, r11d
.text:0000000140001096 nop
.text:0000000140001097 nop

Записываем сумму чисел ключа по адресу [rbx-4], добавляем в r10d значение ecx, проверяем r11d равен ли 4, если не то возвращаемся в начало данного блока кода и повторяем операцию со следующим рядом чисел.

.text:0000000140001098 mov     [rbx-4], ecx
.text:000000014000109B add     r10d, ecx
.text:000000014000109E cmp     r11d, 4
.text:00000001400010A2 jb      short loc_140001050

Данный участок кода будет, суммировать значения всех значений каждого ряда и сохранит все в r10d далее происходит деление значение в r10d на 4

.text:00000001400010A4 shr     r10d, 2

Получить в rax смещение где находятся результаты сложения значений каждого ряда ключа

.text:00000001400010AA lea     rax, [rsp+18h+var_18]

Тут идет сравнение полученных значений rax, если они не равны значению полученному делением на 4 r10d, прыжок отправит нас на выход из проверки и далее сообщение о не правильном ключе.

.text:00000001400010B0 loc_1400010B0:                          ; CODE XREF: sub_140001000+BF j
.text:00000001400010B0 cmp     [rax], r10d
.text:00000001400010B3 jnz     short loc_1400010FD
.text:00000001400010B5 add     ecx, 1

Переходим к следующему значению:

.text:00000001400010B8 add     rax, 4

Если не проверены все четыре значение продолжает проверят пока ecx не будет равен 4

.text:00000001400010BC cmp     ecx, 4
.text:00000001400010BF jb      short loc_1400010B0

Выше я писал про важный момент с r11d, значение которого увеличивается на 1 после каждого прохода, исходя из этого и дальнейшей проверки полученных значений я понял что каждый ряд ключа, при его сложении должен быть равен одному значению, к примеру ключ 1111-1111-1111-1111 значение каждого ряда должны быть равны одному в данном случае 5 так как при первом проходе к этому значению 4 добавляется значение r11d которое равно 1, но надо учитывать что с новым проходом r11d увеличивается на 1, то есть следующий ряд уже не будет равен 5, так как r11d будет равно 2, таким образом известно что всего проходов 4 и последнее значение r11d будет 4, нужно составить ключ таким образом что при сложение каждого ряда чисел мы получали значение 5, 1111-1110-1100-1000. Но не все так просто :) и про это скажет на следующий участок кода:

.text:00000001400010C4 loc_1400010C4:                          ; CODE XREF: sub_140001000+EC j
.text:00000001400010C4 movzx   ecx, byte ptr [r8+rax+0Fh]
.text:00000001400010CA cmp     [r8+rax], cl
.text:00000001400010CE jz      short loc_1400010FD
.text:00000001400010D0 movzx   r9d, byte ptr [rax+r8+5]
.text:00000001400010D6 cmp     cl, r9b
.text:00000001400010D9 jz      short loc_1400010FD
.text:00000001400010DB cmp     r9b, [rax+r8+0Ah]
.text:00000001400010E0 jz      short loc_1400010FD
.text:00000001400010E2 add     edx, 1
.text:00000001400010E5 add     rax, 1
.text:00000001400010E9 cmp     edx, 4
.text:00000001400010EC jb      short loc_1400010C4
.text:00000001400010EE mov     eax, 1
.text:00000001400010F3 mov     rbx, [rsp+18h+var_8]
.text:00000001400010F8 add     rsp, 18h
.text:00000001400010FC retn

Ключ 1111-1110-1100-1000 обречен на провал потому что он не удовлетворяет требованием проверки, а суть этого кода такой:

Первый проход:

1 символ 4 ряда не должен быть равен 1 символу 1 ряда
1 символ 2 ряда не должен быть равен 0
1 символ 3 ряда не должен быть равен 2

Второй проход:

2 символ 4 ряда не должен быть равен 2 символу 1 ряда
2 символ 2 ряда не должен быть равен 1
2 символ 3 ряда не должен быть равен 2

Третий проход:

3 символ 4 ряда не должен быть равен 3 символу 1 ряда
3 символ 2 ряда не должен быть равен 2
3 символ 3 ряда не должен быть равен 0

Четвертый проход:

4 символ 4 ряда не должен быть равен 4 символу 1 ряда
4 символ 2 ряда не должен быть равен 0
4 символ 3 ряда не должен быть равен 1

Основываясь на анализе и ряде проверок я составил ключ который удовлетворяет все критерии проверок 1032-2201-1120-0120, ключ равен длине 19 символов, каждый 5-й символ ключа "-", одинаковые значения при сложении каждого ряда чисел и так же удовлетворяет правило ключа которое описано выше.

[ Завершение ]

Ты сам можешь покопать данное приложение и протестировать все сам :), crackme к статье прилагается. после недолго ожидание меня пригласили пообщаться с ребятами из касперского, скажу сразу в начале мне понравилось все открыто и приятно на вид, но когда меня начали расспрашивать о том и о сем, я подумал нет, спасибо, лучше им будет без меня и технично слился, и продолжил работу системного администратора в своей конторе :). В любом случае что бы не говорили, кроши приложение, поднимай скил, как показывает практика это приносит свои плоды. Все пока с вами был jsm.




© jsm 05.01.2015

e-Commerce Partners Network
Мороженщик написал:

Просто и понятно написано, спасибо.

Сколько вам времени понадобилось на решение этого задания и на какую позицию в компании вам предлагали пройти это тестовое задание?

jsm написал:

Сколько вам времени понадобилось на решение этого задания

Время затраченное на решение 5-10 минут.
какую позицию в компании вам предлагали пройти это тестовое задание

на вирусного аналитика.

Руссинович написал:

1 символ 2 ряда не должен быть равен 0

Чёйто? Там всегда первые символы сравниваются.
.text:00000001400010C4 movzx   ecx, byte ptr [r8+rax+0Fh]

.text:00000001400010CA cmp [r8+rax], cl; 1 символ 1 четвёрки с 1 символом 4 четворки
.text:00000001400010CE jz short loc_1400010FD
.text:00000001400010D0 movzx r9d, byte ptr [rax+r8+5]
.text:00000001400010D6 cmp cl, r9b ; 1 символ 4 четвёрки с 1 символом 2 четверки
.text:00000001400010D9 jz short loc_1400010FD

jsm написал:

1 символ 2 ряда не должен быть равен 0


1032-0212-1120-0120

Подходит по всем критериям кроме выше описанного, 1 символ 2 ряда равен нулю. результат: неправильный ключ.

pabloz написал:

Дайте пароль к архиву! :)

jsm написал:

Пароль от архива: crackme

Ник:

Текст:
P Br B I Qute



Код: обновить
Последние комментарии
26.06.2017 07:33:17 DeweyAloma написал:
If you have a desire to learn how to earn from...
XSS Часть II
26.06.2017 07:09:03 DeweyAloma написал:
If you have a desire to learn how to earn from...
Взлом приложений WEB 2.0 из Firefox
26.06.2017 04:42:47 DeweyAloma написал:
If you have a desire to learn how to earn from...
HTTP. Описание протокола
Реклама

Тут должна была быть ваша реклама, но мы потеряли глиняную табличку с ее текстом. SapeId: 665044

Rambler's Top100