Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Статья с хэллоуина
Салом КулХацкер! Ну что настало время хэллоуина. Мне хочется рассказать тебе про алгоритм решения одного лёгкого crackme и поделиться кодом генератора. Это был один из первых crackme, который я решил.
На просторах сети найден был наш подопотный. Это сrackme . Естественно, что необходимо изучить его. Для вскрытия нам понадобиться:
Сей crackme не очень сложный. Рассмотрим алгоритм генерации ключа на правильном ключе 8365-5794-2566-0817. В IDA Pro я добавил комментарии по поводу кода.
Осмотр пациента
Поведение на первый взгляд обычное. Расширение .exe. Не упаковано. Запустим.
Что это? Требует ключ. Нужно лечить
Вскрытие больного
При ошибке была надпись «Fail, Serial is invalid!». Надём место, где она используется в программе.
Видим 1 функцию key_check_func перед условным переходом. Осмотрим её.
Интересное древо получается.
Ставим точку останова и начинаем отладку.
Необходимо, чтобы ключ был длиной 19 символов.
Затем программа проверяет присутствие знака тире в ключе через каждые 5 символов, входя в цикл 3 раза.
После проверки на наличие тире, программ изучает состоит ли блок ключа (1/4 ключа) из цифр. Есть предположение, чтобы понять, какая цифра была передана компилятор исполняет команду add eax, 0FFFFFFD0h
Например, сложим 8 (38h) c данным числом. Получившиеся число чрезмерно большое (10000008h) и на конце располагается 8, следовательно, обрезается. Остаётся 8. Это переданная нами цифра. Так происходит 4 раза в цикле.
Что теперь? Нынче начинается сложение кодов каждой цифры проверяемого блока друг с другом, однако последняя 4 цифра складывается 3 раза подряд. Получившуюся сумму опять складывают. Код последней цифры блока + получившиеся сумма — 150h. Результат добавляется в r10d. Весь этот цикл повторяется 4 раза для каждого блока ключа.
В нашем случае рассмотрим на примере первого блока ключа 8365: 38h (8) + 33h (3) + 36h (6) + 35h (5) + 35h (5) + 35h (5) = 140h + 35h — 150h = 25h. 25 прибавляется в r10d и записывается в память. Пометим сие место, как A. Сумма прочих блоков ключа также равна 25h. Значит, умножаем 25h * 4 = 94.
Далее происходит побитовый сдвиг в право на 2 байта. Это место для себя пометим, как B.
У нас есть значение обозначенное, как A (25h) и B (25h). Впоследствии произойдёт сравнение данных чисел. Они должны быть одинаковые. Эта операция происходит для каждого блока ключа.
Последняя, что осуществляет программа — это проверяет схожи ли цифры в блоках. Поначалу сравниваются цифры 1 блока с цифрами 2 блока. Потом проверка 2 блока с 3 блоком. Заключительная проверка 3 блока с 4 блоком. Вся это проверка происходит не сразу, а постепенно в цикле.
Анализ закончен. Больной изучен.
Время для лекарства
Для генерации ключа используем нечто необычное. Python + Библиотеку random. Сам код находится ниже. Комментарии в коде:
import random
def gen_key_part():
# Генерация цифр
num1 = str(random.randint(0, 9))
num2 = str(random.randint(0, 9))
num3 = str(random.randint(0, 9))
num4 = str(random.randint(0, 9))
# Генерация части ключа (1 блок)
final = num1 + num2 + num3 + num4
return final
def sum_ord(key_part):
# Раскладываем переданную часть ключа на цифры
num1 = key_part[0]
num2 = key_part[1]
num3 = key_part[2]
num4 = key_part[3]
# Алгорит сложения в crackme
sum = ord(num1) + ord(num2) + ord(num3) + ord(num4) + ord(num4) + ord(num4)
sum_final = ord(num4) + sum - 336
return sum_final
def shr(key):
# Разбиваем ключ на блоки
a = key[0:4]
b = key[5:9]
c = key[10:14]
d = key[15:19]
# Алгоритм сдвига по битам в crackme
x = sum_ord(a) + sum_ord(b) + sum_ord(c) + sum_ord(d)
x = x >> 2
return x
def check_key(key):
i = 0 # Счётчик
while i != 4:
# Переменная i будет увеличиваться на 1 до 4. Это будет указатель на проверяемый символ
first = 0 + i
second = 5 + i
third = 10 + i
four = 15 + i
# Проверка ключа на соответсвие сдвига по битам и суммы чисел ( Обозначали, как A и B)
if sum_ord(key[0:4]) != shr(key) or sum_ord(key[5:9]) != shr(key) or sum_ord(key[10:14]) != shr(key) or sum_ord(key[15:19]) != shr(key):
return False
# Проверка ключа на совпадающие цифры
if int(key[first]) == int(key[second]):
return False
if int(key[second]) == int(key[third]):
return False
if int(key[third]) == int(key[four]):
return False
i += 1 # # Счётчик увеличиваем
def generate_key():
# Генерация ключа
key = gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part()
# Проверяем ключ и печатаем true или false
while True: #
if check_key(key) == False:
# Генерация ключа если не верно
key = gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part()
print('Checking this key -> ' + key)
else:
# Ключ правильный
print('This is the correct key -> ' + key)
break
# Генерируем ключ, вызывая функцию
if __name__ == "__main__":
generate_key()
Запускаем
Вводим ключ и видим.
Пациент излечен.
Салом КулХацкер! Ну что настало время хэллоуина. Мне хочется рассказать тебе про алгоритм решения одного лёгкого crackme и поделиться кодом генератора. Это был один из первых crackme, который я решил.
На просторах сети найден был наш подопотный. Это сrackme . Естественно, что необходимо изучить его. Для вскрытия нам понадобиться:
- Немного языка Assembler
- Логика вместе с отладчиком (IDA PRO)
Сей crackme не очень сложный. Рассмотрим алгоритм генерации ключа на правильном ключе 8365-5794-2566-0817. В IDA Pro я добавил комментарии по поводу кода.
Осмотр пациента
Поведение на первый взгляд обычное. Расширение .exe. Не упаковано. Запустим.
Что это? Требует ключ. Нужно лечить
Вскрытие больного
При ошибке была надпись «Fail, Serial is invalid!». Надём место, где она используется в программе.
Видим 1 функцию key_check_func перед условным переходом. Осмотрим её.
Интересное древо получается.
Ставим точку останова и начинаем отладку.
Необходимо, чтобы ключ был длиной 19 символов.
Затем программа проверяет присутствие знака тире в ключе через каждые 5 символов, входя в цикл 3 раза.
После проверки на наличие тире, программ изучает состоит ли блок ключа (1/4 ключа) из цифр. Есть предположение, чтобы понять, какая цифра была передана компилятор исполняет команду add eax, 0FFFFFFD0h
Например, сложим 8 (38h) c данным числом. Получившиеся число чрезмерно большое (10000008h) и на конце располагается 8, следовательно, обрезается. Остаётся 8. Это переданная нами цифра. Так происходит 4 раза в цикле.
Что теперь? Нынче начинается сложение кодов каждой цифры проверяемого блока друг с другом, однако последняя 4 цифра складывается 3 раза подряд. Получившуюся сумму опять складывают. Код последней цифры блока + получившиеся сумма — 150h. Результат добавляется в r10d. Весь этот цикл повторяется 4 раза для каждого блока ключа.
В нашем случае рассмотрим на примере первого блока ключа 8365: 38h (8) + 33h (3) + 36h (6) + 35h (5) + 35h (5) + 35h (5) = 140h + 35h — 150h = 25h. 25 прибавляется в r10d и записывается в память. Пометим сие место, как A. Сумма прочих блоков ключа также равна 25h. Значит, умножаем 25h * 4 = 94.
Далее происходит побитовый сдвиг в право на 2 байта. Это место для себя пометим, как B.
У нас есть значение обозначенное, как A (25h) и B (25h). Впоследствии произойдёт сравнение данных чисел. Они должны быть одинаковые. Эта операция происходит для каждого блока ключа.
Последняя, что осуществляет программа — это проверяет схожи ли цифры в блоках. Поначалу сравниваются цифры 1 блока с цифрами 2 блока. Потом проверка 2 блока с 3 блоком. Заключительная проверка 3 блока с 4 блоком. Вся это проверка происходит не сразу, а постепенно в цикле.
Анализ закончен. Больной изучен.
Время для лекарства
Для генерации ключа используем нечто необычное. Python + Библиотеку random. Сам код находится ниже. Комментарии в коде:
import random
def gen_key_part():
# Генерация цифр
num1 = str(random.randint(0, 9))
num2 = str(random.randint(0, 9))
num3 = str(random.randint(0, 9))
num4 = str(random.randint(0, 9))
# Генерация части ключа (1 блок)
final = num1 + num2 + num3 + num4
return final
def sum_ord(key_part):
# Раскладываем переданную часть ключа на цифры
num1 = key_part[0]
num2 = key_part[1]
num3 = key_part[2]
num4 = key_part[3]
# Алгорит сложения в crackme
sum = ord(num1) + ord(num2) + ord(num3) + ord(num4) + ord(num4) + ord(num4)
sum_final = ord(num4) + sum - 336
return sum_final
def shr(key):
# Разбиваем ключ на блоки
a = key[0:4]
b = key[5:9]
c = key[10:14]
d = key[15:19]
# Алгоритм сдвига по битам в crackme
x = sum_ord(a) + sum_ord(b) + sum_ord(c) + sum_ord(d)
x = x >> 2
return x
def check_key(key):
i = 0 # Счётчик
while i != 4:
# Переменная i будет увеличиваться на 1 до 4. Это будет указатель на проверяемый символ
first = 0 + i
second = 5 + i
third = 10 + i
four = 15 + i
# Проверка ключа на соответсвие сдвига по битам и суммы чисел ( Обозначали, как A и B)
if sum_ord(key[0:4]) != shr(key) or sum_ord(key[5:9]) != shr(key) or sum_ord(key[10:14]) != shr(key) or sum_ord(key[15:19]) != shr(key):
return False
# Проверка ключа на совпадающие цифры
if int(key[first]) == int(key[second]):
return False
if int(key[second]) == int(key[third]):
return False
if int(key[third]) == int(key[four]):
return False
i += 1 # # Счётчик увеличиваем
def generate_key():
# Генерация ключа
key = gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part()
# Проверяем ключ и печатаем true или false
while True: #
if check_key(key) == False:
# Генерация ключа если не верно
key = gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part()
print('Checking this key -> ' + key)
else:
# Ключ правильный
print('This is the correct key -> ' + key)
break
# Генерируем ключ, вызывая функцию
if __name__ == "__main__":
generate_key()
Запускаем
Вводим ключ и видим.
Пациент излечен.
Последнее редактирование модератором: